~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What is it? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STAR is a C++ project cross-platform development framework that is intended to do most of the grunt-work necessary for creating application programs, namely a event-driven methedology. It was originally written under OS-9/68000 (no, that's not a Macintosh thing, see http://www.microware.com/) but most of the real development occurred under Linux. It has been ported to Win32 and should be reasonably easy to extend to other operating systems as well. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Why was it written? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STAR was originally written to be the base layer for a series of continuous- time, multi-player network games being designed and written by myself (Brian White) and some of my friends (Andrew Beere, Behan Webster, Takashi Toyooka, Kevin Rockel, and Todd "Snoopy" Harper). Unfortunately, Verisim, the little company we formed to do the work, went out of business before we were able to actually release one of these gems. (There is a new company called Verisim using the verisim.com domain, but they have nothing to do with us.) STAR was the generic support layer. In fact, there are many modules from that original project still not found in the STAR source code today simply because they could be suffering from a fair degree of bit-rot given that STAR has evolved for use with other projects. These missing modules include, but are not limited to, serial port drivers, parallel port drivers, layered database access, useful Qt objecs, GL object compression and display (with mouse-driver camera control), object-oriented database with data-dictionary support, cross-platform data exchange, and TCL access code generator. It was quite a large project. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tell me about the base. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STAR uses an event-driven object-oriented methodology. You create objects to handle data and then tell them what object/method to call-back when certain things happen. A central customizable event loop deals with checking what system events have occurred and calling the appropriate modules. This works with Unix, with or without X, and also with Win32, though currently only with direct API calls and not using MFC. It has support for multi-threaded applications including locking mechanisims to deal with concurrency issues. In my opinion, you should never, ever, ever use a multi-threaded technique for solving a problem if there is another way! The difficulties it adds are incalcuable and can be extremely difficult to reproduce/diagnose. That said, however, you have no chance of making it work without support at the very base of whatever system you design. autolist -- a global-list handler to allow run-time gathering of information about what components are available. This system allows the program to learn, at start-up, about the resources it has access to so that it is not necessary to recompile base systems every time an external piece of code wants to add something to it. The logging system, for example, uses this to learn what error strings to associate with integer error codes. dataio -- a base input/output system. Different than streams, the DataIo class provides the central I/O management, including call-backs, for STAR. Derived classes allow ordinary unix paths, sockets, programs, pipes, etc. all to be accessed and managed in an identical manner. In additions, there is a type of DataIo class called a "filter" which can wrap another DataIo object (including another filter) for transparent conversion of the data stream. In fact, with only the creation of a few local variables, it is possible to read a file from disk, compress it, encrypt it, uuencoded it, and write it back out to another file with one (1) line of code. Reversing the process means only switching two variables. debug -- support for integrating with local debugger. The code in this module just provides some assistance for setting breakpoints when certain events occur and even dumping core file (without stopping the program) if so desired. errors -- a hierarchy of exceptions that are used for reporting failures. Exceptions are a great feature of C++ to ensure that unexpected results do not go unhandled. The hierachy here makes it easy for a program to trap errors up to a certain severity while letting more serious problems continue up tha call stack. Exceptions also generate log messages. events -- central event management. The events system handles getting events from the operating system and passing them on to the appropriate modules. Both Unix and Win32 are fully supported. logfile -- logging interface. The logging system reports messages, including where in the source code they were generated, for tracking and debugging of problems. It is configurable as to what level of messages actually get stored and can store those messages on any DataIo path. pointer -- smart pointers with reference counting and garbage collection. Dynamically allocated memory is always a difficulty but exceptions make it a real problem. Unless allocated memory is tied to an object with a descructor, any thrown exception will cause a memory leak as the stack is unwound and the pointer is destroyed without its associated memory being deallocated. Smart-pointers take care of all that as well as allowing multiple pointers to the same memory and only deallocated it when the last "reference" is destructed. They are fast, efficient, and offer overloaded operators so they can be used (i.e. "->") just like ordinary pointers with performance penalty (assuming a reasonably smart compiler like gcc). stats -- statistics reporting. Any module can register itself (an autolist) as being able to provide statistics information. It will then be called on a periodic basis to dump those statistics for later analysis and graphing. This doesn't sound much like a "base" service, but since it is called by the event loop and used by smart-pointers, it is included here. threads -- multi-threaded application support. By creating a derived class from "Thread", a new thread of execution is created for your program. That thread can run normally, or can be restarted automatically on a periodic basis. Full support for semaphores is included. timers -- system time information. These functions provide platform-independant access to system timers like a realtime second and microsecond timer, as well as a system independant "timestamp" timer that can be used between machines. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tell me about IO. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The I/O system is all derived from the base DataIo class. Current modules include: fileio -- filesystem access. This provides access to files on disk by their pathnames. socketio -- network socket access. This system provides a high-level view to a socket (really only useful for TCP sockets) so they can be read/written like any other file. Another "Socket" class (as opposed to "SocketIo") is available for lower-level socket access, including improved TCP listeners and UDP connections. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tell me about the utilies. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A great many utility functions, classes, and methods are included. Some are just header files while others have support code. callback -- callback function support. These classes hold function pointers or class/method pointers so they can be called at a later time. charstar -- wrapper for "char*" for STL containers. This class is a simple wrapper around the standard "char*" type that allows them to be used within STL containers and be sorted/accessed by the contents being pointed instead of the value of the pointer. crc -- cyclic redundancy checks. These classes (well, currently only Crc32) provide a simplistic form of data integrity checking. endian -- conversion between big-endian and little-endian architectures. When passing data between machines with different architectures, it is necessary to agree upon how bytes within a larger word will be organized when stored in memory. This module provides functions to do that conversion. hmac -- hashed message authentication codes. This is a wrapper around an authentication method like MD5 to provide increased security of messages. md5 -- message digest #5. This is a standard digest for provide a much more reliable and secure integrity check than a simple CRC. rcfile -- configuration file access. These functions provide parsing and writing of simple key/value configuration files. system -- a collection of system and architecture independant definitions. It is the types defined in here that allow much of the cross-platform compatibility.