ned Productions – TnFOX

by . Last updated . This page has been accessed 99,616 times since the 17th June 2003.

TnFOX is a modern, secure, robust, multithreaded, exception aware, internationalisable, portable GUI toolkit library designed for mission-critical work in C++ and Python forked from the FOX library. It replicates the Qt API in many places and has been designed primarily for Tn, the port of Tornado to FOX.

What will it work with?

It runs on Microsoft Windows (2000 and after), Linux, FreeBSD and Apple Mac OS X. It will compile with MSVC7.1 or later, GCC v3.2 or later and Intel's C++ compiler. It is portable to any architecture you like on any of the supported platforms. It will happily run on any endian of machine, using hardware endian conversion during serialisation & deserialisation if available for maximum speed. It automatically detects low memory situations and adjusts the sizes of its internal caches to release memory back to the system and thus runs excellently on low memory systems.

How powerful is it?

TnFOX makes heavy use of C++ compile-time type introspection and metaprogramming to automate much of the drudgery that makes programming boring. Witness the following real world code taken from the automated test manager:

void insert(TnFXSQLDB *db)
		findMyPlatformId(db, true);
	TnFXSQLDBStatementRef st=db->prepare("INSERT INTO 'results'('testname', \
		'started', 'ended', 'platform', 'svnrev', 'returncode', \
		'output') VALUES(:testname, :started, :ended, :platform, :svnrev, :returncode, :output);");
	st->bind(":testname", testname);
	st->bind(":started", started);
	st->bind(":ended", ended);
	st->bind(":platform", myPlatformId);
	st->bind(":svnrev", version.svnrev);
	st->bind(":returncode", returncode);

	// Write the output bz2 compressed to save (lots of) space
	QBuffer buff;
		QBZip2Device bz2(&buff);;
		FXStream s(&bz2);
		s << output;
	st->bind(":output", buff.buffer());

This sets up a SQL statement for inserting a row, binds variables to the SQL parameters (which the compiler deduces how to serialise into a storable format) and executes in as little programmer effort as possible. This code additionally works for any database backend at all. Note also how a Binary Large Object (BLOB) was written via an implicit serialisation via a bzip2 compressor - and best of all, the type of output could be absolutely anything at all and the compiler will deduce what should be done.

In addition to generic coding via metaprogramming, TnFOX has a excellent object abstraction allowing still further generic implementation. Unlike most libraries, every single error is detected1 and reported with additional support for handling nested C++ exception throws and well as C++ rollback transactions which allow interruptions to gracefully unwind partially completed operations. Also unlike almost every other portability library, TnFOX is very secure with industrial strength encryption, entropy generation, access control, optional automatic data shredding and a secure memory allocation pool which can't leak data into the swap file.

If that wasn't enough, TnFOX can transport arbitrary C++ instantiations across a network via its own highly optimised InterProcess Communication (IPC) system which is much faster than CORBA and is directly integrated into C++ - indeed, via this same mechanism can the SQL abstraction serialise & deserialise arbitrary C++ instances in & out of a database (which can also operate across a network over IPC). One can very easily implement encrypted versions of all these by simply placing an encryptor instance (just like a compressor instance) between the transport and the application - indeed one can even encrypt AND compress a transport!

On top of all that, it has an extremely powerful text translation system - far more powerful than GNU gettext(). It will even auto-generate translations via Google Translate for you so your program will operate in any supported language!

TnFOX is, in my admittedly biased opinion, by far the most powerful C++ portability layer in existence anywhere. I certainly personally have seen nothing like it anywhere else.

How fast is it?

It's real fast. It has especially customised support for x86 and x64 processors, making superb use of hardware features not normally used by typical libraries which greatly accelerate performance such as SIMD and parallel processing. It is pervasively multithreaded with hand tuned assembler implementations of light locks. Via metaprogramming, it knows when it can choose faster algorithms when the type allows it (eg; POD classes). Unlike most portability libraries, TnFOX is extensively profiled and optimised for maximum performance, even optionally providing its own super-fast memory allocator.

How big is it?

You can bind as a static library or shared library. You can modularise or have monolithic. You can even compile out large sections to get a lean & mean library including completely removing the GUI code if say you wanted TnFOX as the portability library for a command line app, daemon or system service. For x86, it can be be anywhere between 1Mb and 6Mb depending on compile options.

You will need a fast CPU to compile TnFOX and preferably a quad processor system. The build system will make welcome use of all cores available - on my top-end machine, it still takes seven or eight minutes to compile; on the TiVO box downstairs (a 1Ghz Pentium 3), it's over fifteen minutes. The TnFOX Python bindings need 1.5Gb of RAM to compile and 4Gb is better - thankfully such machines are becoming increasingly commonplace.

What about documentation?

In a nutshell, it's excellent1 with extensive overviews and how-to guides. See for yourself with the online searchable documentation site at either the latest release or SVN head.

[1]: These comments apply to the parts of TnFOX added since the fork from FOX.

Welcome Features & Minimum System Requirements Regression Test Suite Status Support Downloads




Download a self-contained Win32 version of the above program (897Kb)

Contact the webmaster: Niall Douglas @ webmaster2<at symbol> (Last updated: 2003-06-17 00:00:00 +0000 UTC)