The FlightGear source tree is only one level deep, except that all the flight data models are each in their own subdirectory located under the FDM directory. Each directory contains a few header files that expose its object definitions. Other source files refer to the headers directly, without the frustrations of path globbing or multiple include paths for the compiler. The directory names are mostly pretty self-explanatory:
AIModel, Aircraft, Airports, ATC, Autopilot, Cockpit, Controls (in the aircraft cockpit), Environment, FDM (only one constituent is in use), GUI (menus and the like), Include (for compiler configuration), Input (joysticks etc), Instrumentation, Main (initialization and command line parsing), Model (3D aircraft), MultiPlayer, Navaids, Network (data sharing), Objects (dynamically loaded and changing scenery), Replay, Scenery (static), Scripting (remote script control), Server, Sound, Systems and Time (in the simulated world).
FlightGear exposes the internal state of the simulation through the property database, part of the generic simulation infrastructure offered by SimGear. This dynamically maps a name (such as /position/latitude) into an object with getter and setter methods. If the property will be accessed frequently, the pointer to the object can be stored so that the string lookup of the name only occurs one time. The single pointer indirection is still somewhat slower than hard linkage, but enhances the modularity of the code base. For example, the user interface definitions in XML files (panels, instruments, 3D animation, sound, etc) are able to refer to any property offered by any subsystem.
The simulator state is also accessible on the network. Adding the command line option -telnet=5555 allows another computer (such as the instructor console) to interact with the simulator computer using a command such as telnet simulator 5555. This network interface allows any property in the database to be viewed or modified and includes remote enumeration of all the property names. This has been used to implement a complete external operator GUI and for automating FAA certification tests.
Many tasks within the simulator need to only run periodically. These are typically tasks that calculate values that don't change significantly in 1/60th of a second, but instead change noticeably on the order of seconds, minutes, or hours. Running these tasks every iteration would needless degrade performance. Instead, we would like to spread these out over time to minimize the impact they might have on frame rates, and minimize the chance of pauses and hesitations.
We do this using the Event Manager and Scheduler, which consists of two parts. The first part is simply a heap of registered events along with any management information associated with that event. The second part is a run queue. When events are triggered, they are placed in the run queue. The system executes only one pending event per iteration in order to balance the load. The manager also acquires statistics about event execution such as the total time spent running this event, the quickest run, the slowest run, and the total number of times run. We can output the list of events along with these statistics in order to determine if any of them are consuming an excessive amount of time, or if there is any chance that a particular event could run slow enough to be responsible for a perceived hesitation or pause in the flow of the simulation.
FlightGear itself supports threads for parallel execution, which distributes tasks such as scenery management over many iterations, but some of the library dependencies are not themselves thread clean. Thus all accesses to non-thread-clean libraries (such as loading a 3D model) need to be made by a single thread, so that other activities wishing to use the same library must be delayed. These small delays can lead to minor user-visible hesitations.