Nasal for C++ programmers: Difference between revisions

Jump to navigation Jump to search
m
Line 104: Line 104:
Nasal itself has a standard library of general purpose functions, in addition it supports dozens of FG-specific extension functions to do various FG-related things, for example to interact with other subsystems (e.g. AI traffic, weather, FDM, GUI etc). In other words, while you'll find lots of standard library functions, there are many FG/simulation-specific functions available in FlightGear/Nasal.
Nasal itself has a standard library of general purpose functions, in addition it supports dozens of FG-specific extension functions to do various FG-related things, for example to interact with other subsystems (e.g. AI traffic, weather, FDM, GUI etc). In other words, while you'll find lots of standard library functions, there are many FG/simulation-specific functions available in FlightGear/Nasal.


An increasing number of subsystems in FlightGear no longer have direct scripting bindings via extension functions, but instead work by replicating their APIs on top of the property tree - so that these systems can be mostly controlled just by setting/getting properties - the autopilot system, AI Traffic and the canvas are some more recent examples of this. To add new bindings to Nasal, the cppbind framework in Nasal should be used (the Canvas system and NasalPositioned being the implementation reference here for the time being).
An increasing number of subsystems in FlightGear no longer have direct scripting bindings via extension functions, but instead work by replicating their APIs on top of the property tree - so that these systems can be mostly controlled just by setting/getting properties - the autopilot system, AI Traffic and the canvas are some more recent examples of this. Unlike conventional subsystems, C++ code or Nasal code, such systems can easily be controlled via the property tree - so that you can even control these systems via [[Telnet usage|Telnet]].
To add new bindings to Nasal, the cppbind framework in SimGear/Nasal should be used (the Canvas system and NasalPositioned being the implementation reference here for the time being).


One of the oldest mechanism to run custom code are so called "fgcommands", which is just a fancy word for "FlightGear commands" that work purely via the property tree - i.e. they accept parameters solely as properties, and they may also only return values via the property tree. So these know nothing about Nasal or Nasal's data structures - which makes them pretty flexible and powerful, because they can also be used in non-scripting contexts, such as in XML files/bindings - from Nasal space, these can still be easily invoked via the fgcommand() API.  
One of the oldest mechanism to run custom code are so called "fgcommands", which is just a fancy word for "FlightGear commands" that work purely via the property tree - i.e. they accept parameters solely as properties, and they may also only return values via the property tree. So these know nothing about Nasal or Nasal's data structures - which makes them pretty simple and still flexible, because they can also be used in non-scripting contexts, such as in XML files/bindings - from Nasal space, these can still be easily invoked via a dedicated fgcommand() API.  


Also, there are extension functions available which allow callbacks to be registered in the form of property listeners (which get invoked whenever a property is updated/written to) or via timers (that may expire and trigger a callback that gets called after expiration).  
Also, there are extension functions available which allow callbacks to be registered in the form of property listeners (which get invoked whenever a property is updated/written to) or via timers (that may expire and trigger a callback that gets called after expiration). So you can basically make up your own control property '''/sim/foo/control-bar''' and register a listener callback that gets invoked whenever the property is updated (via cockpit hot spots, the GUI, autopilot, C++ code other Nasal code).


You will typically want to use listeners to get notifications whenever a certain property changes - a good example is a cockpit button or a GUI control that's updated. Timers are usually used to regularly run a piece of code, i.e. to do some form of background processing - stuff that doesn't need to be running all the same, but that needs to be run at regular intervals. Often times, callbacks invoked via timers will typically set up a new timer at the end of the routine, so that they basically invoke themselves. A more recent (and more sophisticated) option is the new "maketimer()" API.
You will typically want to use listeners to get notifications whenever a certain property changes - a good example is a cockpit button or a GUI control that's updated.  
 
Timers are usually used to regularly run a piece of code, i.e. to do some form of background processing - stuff that doesn't need to be running all the same, but that needs to be run at regular intervals (such as 1hz, 5hz, 10hz). Often times, callbacks invoked via timers will typically set up a new timer at the end of the routine, so that they basically invoke themselves. A more recent (and more sophisticated) option is the new "maketimer()" API.


Finally, there's a plethora of FlightGear-specific modules in $FG_ROOT/Nasal that greatly simplify coding stuff from scratch.  
Finally, there's a plethora of FlightGear-specific modules in $FG_ROOT/Nasal that greatly simplify coding stuff from scratch.  

Navigation menu