Recommended Project Policies
This article may require cleanup to meet the quality standards of the wiki. Please improve this article if you can. |
This page is meant to summarize project policies related to contributing to FlightGear, these don't necessarily have to be "officially" agreed upon, but only need to be backed up by former contributions or simply "make sense", so that they may be considered "established procedures". Hopefully, this page will eventually enable future contributors to more easily provide contributions in acceptable shape and form.
Please feel free to add non-controversial items to this page, if you feel that there's need to discuss anything in particular, please use the page's talk page.
Base Package
General
texture compression
SGI textures (*.rgb) shall be "aggressively" (as GIMP calls it) compressed, unless this makes a file actually bigger.
language
File names, comments, function names etc. shall be in English, so that they can be understood by the biggest possible audience and are truly "open". This also applies to all commentary provided in any FlightGear related files.
configuration files
If possible, all new configuration files should be stored in XML format - preferably, in a format that can be easily processed using the property tree API (propertylist based).
File naming
FlightGear being a multi-platform project, needs to cater for those platforms that do not differentiate between upper/lower case strings, thus it is important to name files accordingly [1].
"userarchive" attribute
Aircraft XML or Nasal files must not set the "userarchive" flag on properties. This is reserved for usage by the FlightGear system. Aircraft save their data to the ~/.fgfs/aircraft-data/<aircraft-name>.xml file. This can be done by using the Nasal command aircraft.data.add(<list-of-properties>), or by listing the properties under /sim/aircraft-data/path[n]. (Rationale: avoid conflicts and side effects for other aircraft, keep the data cleanly separated, don't fill up autosave.xml with temporary properties, where they have to be removed manually)
"type" attribute
Preferably, PropertyList-files should make use of the type attribute to specify node types.
Node Naming Conventions
Whenever possible, node names should be as self-explanatory as possible - node names may be separated using "-" or "_", however the former notation is used far more commonly so far and can be considered standard. Also, nodes should preferably indicate their unit/type info using a corresponding suffix, as well: i.e. "rate-hz", "heading-deg","airspeed-kts","altitude-ft","sink-rate-fps", including this sort of info makes nodes far more intuitive.
Standard Suffices currently include (incomplete right now):
- kt (knots)
- hz (hertz)
- fpm (feet per minute)
- fps (frames per second)
- fps (feet per second)
- deg (degrees)
- rad (radians)
- ft (feet)
- degc (degrees celsius)
- degf (degrees fahrenheit)
Node Descriptions & Comments
When making up new custom XML nodes or file formats, please consider providing sufficient commentary for each node, this can also be achieved by providing an optional "description" attribute for each node. The latter approach also has the advantage, that this information would also be accessible within FlightGear, so that it may be used at runtime to directly show tooltip-like descriptions for each node, i.e. within the property browser.
Aircraft
Global Settings
Aircraft shall not modify global settings other than those that are directly related to the aircraft simulation. It's the user who decides whether s/he wants the menu bar or dynamic view on or off. It's not the aircraft developer. Please see this discussion for a detailed explanation.
Generic Files
Aircraft directories shall not contain copies of generic files. Generic files are exactly there to be *shared*, they aren't merely a copy source. If a generic file doesn't suit your needs and you want to enhance it, then consider first if this change is generally useful and should therefor be done to the generic version, so that other aircraft profit from it as well.
Views
Aircraft use <view> numbers 100..199, while numbers 0..99 are reserved for the system. (Rationale: avoid conflicts after adding new system views, allow to save aircraft views to the aircraft data file)
Bindings
Aircraft may not change joystick bindings. Keyboard bindings shall be avoided if the same effect can be achieved by redefining a controls wrapper (see $FG_ROOT/Nasal/controls.nas). Panel bindings shall use controls wrappers where possible.
Modeling
Things to watch out for
- high resolution textures
- textures containing alpha
- textures themselves
- unwant polygons casting shadows
Scenery
Coding Conventions
Providing Patches
Please see Howto:Submit patches
C++
Please also see C++ Tips
Basics & Style
- if possible, retain existing file naming conventions (i.e. *.cxx & *.hxx), larger components may use their own conventions, though (i.e. jsbsim, yasim, nasal)
- if possible, follow existing style conventions when naming classes, methods and members - i.e. prepend "_" or "m_" to class-specific fields
- if possible, split components into separate, distinct compilation units, i.e. avoid monolithic, bloated files
- if possible, make use of existing infrastructure code
- if possible, prefer using the SG_LOG macro instead of printf/cout statements for debugging purposes
- if possible, try to avoid pulling in complete namespaces to avoid unnecessarily bloated namespaces and possible symbol collisions/conflicts
- if you do pull in a complete namespace, do so in the smallest possible scope (i.e. in a function block rather than globally), this helps avoid namespace pollution
Coding
- <iostream> sucks in expensive initialization of the standard streams and isn't appropriate in a header file. Use <istream> and <ostream> instead.
- using declarations should never appear at global scope in a header file; source files get to decide what they want to use in their namespace.
- if possible, favor use of smart pointers (SGSharedPtr<T>) over using raw pointers: whenever you allocate memory using new, this should be directly assigned to a smart pointer
- OpenGL/OSG code should make use of osg::ref_ptr
- properties from the property tree are owned by the property tree, thus never explicitly delete pointers obtained this way
- if possible, use the RAII idiom to handle initialization and cleanup of resources
- Parameter passing
- if possible, favor passing parameters by reference rather than by value
- if possible, favor passing by reference rather than by pointer
- if possible, make parameter constness explicit by using the 'const' specifier
- initialize unused pointers to NULL
- if possible, avoid memory allocation within the main loop: use pre-allocated memory instead, consider the possible benefits of using memory pools ('placement new')
- if possible, initialize objects and pointers directly to avoid unnecessary calls, i.e. using:
SGPropertyNode* m(fgGetNode("/sim/foo")); //instead of: SGPropertyNode* m; m=fgGetNode("/sim/foo");
Conceiving new data file formats
- when introducing new data files and possibly even completely new file formats, please do consider the possible merits of settling for an XML/PropertyList-based file format: the majority of files in FlightGear are by design intended to be easily editable, plaintext file formats such as XML, or more specifically the XML-based PropertyList format, ensure that most FlightGear components and related tools can easily work with such files, in fact by "marshalling" your data file formats into the XML/PropertyList syntax, you can easily leverage most of the existing (tested and robust!) file handling related infrastructure/API code and can thus concentrate on the task at hand, rather than first having to write a data file parser from scratch, possibly even introducing new additional dependencies.
Modifying existing files
- existing files should be modified following existing style
- major additions and changes should be shortly documented at the top of the file detailing: date, last changes, authors
- significant modifications might best be kept separate, so that putting such code into new files might be a better option
Adding new files
- make sure to properly separate declarations from implementations
- new source files should contain information detailing: purpose/description of file, authors, data & license header (GPL)
- new files should be properly added to the files belonging to the existing build system (mainly autotools based currently)
- ensure that source files don't end up being unnecessarily bloated, often several distinct compilations units may be more intuitive and also faster to re/build
Integrating new code
- new subsystems that need to be run within the FlightGear main loop should derive from SGSubsystem and implements its interface
- for code that doesn't necessarily have to run within the main loop or code that is computationally intense, you might want to consider factoring out certain components to be run in a separate worker thread instead of possibly blocking the main loop, this can be accomplished in a multi-platform fashion by deriving new classes from SGThread and implementing its interface, in particular the run() method. Note however, that FlightGear is generally not (yet) threadsafe, thus you cannot directly use most of the SimGear/FlightGear API (i.e. property tree) from threads without taking special care to handle threading issues.
- threaded code shall be wrapped within "#ifdef ENABLE_THREADS", so that its compilation can be easily enabled/disabled during source code configuration
Subsystems
- distinct components shall be put into distinct subsystem modules
- all subsystems shall fully implement the SGSubsystem interface
- all subsystems shall be suspendable and resumable
- subsystems should never consume CPU cycles if they are not needed/activated
- consider the possible benefits of using opaque/pImpl pointers to avoid unnecessary recompilations of unchanged files
- make local, file-specific functions static (or use an anonymous/unnamed namespace) to help unclutter the linking process
Property Tree Usage
SGPropertyNode
- pre-allocate pointers or references to frequently accessed properties, rather than using the fgSet*/fgGet* utility helpers repeatedly (to avoid possibly expensive and unnecessary hash table lookups within the main loop) (i.e. in class ctors or via the "static" storage specifier in functions/methods).
Using tied properties
OpenGL
- Never make use of raw OpenGL calls
in places where using raw calls may possibly conflict/interfere, or unnecessarily complicate integration, with other FlightGear components,as this would add unwanted implications with future improvements of FlightGear's visual capabilities (affecting multi-monitor setups for example) [2] (For proper approaches, see: [3] [4] [5])
Nasal
TODO: we need a Nasal "Style Guide", for recommended guidelines, please see [6]
- make use of the 'var' keyword (as documented on the Nasal page) [7]
Community Collaboration
CVS related restructuring efforts shall be coordinated with fellow developers and contributors, in particular with component owners/maintainers, to ensure that all relevant people are informed about such plans and to avoid breakage that may be caused during such efforts [8] [9].
Related Mailing List Discussions
- http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg05224.html
- http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg10936.html
- http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg10932.html
- http://www.mail-archive.com/flightgear-devel@lists.sourceforge.net/msg13462.html