Difference between revisions of "Nasal Initialization"

From FlightGear wiki
Jump to: navigation, search
m (Optional load-once modules)
m (Optional load-once modules)
Line 10: Line 10:
 
This allows to use functions from other core files, which have just been defined, e.g. which were not yet available when parsing the file.
 
This allows to use functions from other core files, which have just been defined, e.g. which were not yet available when parsing the file.
  
== Optional load-once modules ==
+
== Optional (load-once) modules ==
 
After the files in the root directory have been processed, the first level of subdirectories is scanned for .nas files.
 
After the files in the root directory have been processed, the first level of subdirectories is scanned for .nas files.
 
Each subdirectory defines a module / namespace which becomes available only after the files in the subdirectory have been completly processed,  
 
Each subdirectory defines a module / namespace which becomes available only after the files in the subdirectory have been completly processed,  
Line 21: Line 21:
  
 
=== Enabling of load-once modules ===
 
=== Enabling of load-once modules ===
Enabling / loading of this modules is done in the C++ code and is a little bit complicated (see FG sources /src/Scripting/NasalSys.cxx).
+
From the user (aircraft developer) point of view, enabling of this modules is done by setting the property {{code|/nasal/<moduleName>/enabled}} to {{code|true}}.
 +
 
 +
If a module is needed by an aircraft, you can just add the following to your aircraft-set.xml file (replace ''module_name'' by the name of the desired module):
 +
<syntaxhighlight lang="xml">
 +
<PropertyList>
 +
    <nasal>
 +
        <module_name>
 +
            <enabled type="bool">true</enabled>
 +
        </module_name>
 +
    <nasal>
 +
</PropertyList>
 +
</syntaxhighlight>
 +
Loading  is done in the C++ code and is a little bit complicated (see FG sources /src/Scripting/NasalSys.cxx).
 
''FGNasalSys::init()'' scans FGDATA/Nasal for subdirectories and calls ''FGNasalSys::addModule()'' for each subdirectory passing its name as module name and a list of all .nas files in it.
 
''FGNasalSys::init()'' scans FGDATA/Nasal for subdirectories and calls ''FGNasalSys::addModule()'' for each subdirectory passing its name as module name and a list of all .nas files in it.
  

Revision as of 18:19, 26 February 2020

some notes on how Nasal files from FGDATA/Nasal appear to be processed when Flightgear is started.

Initialization of Nasal core-/default-modules

When Flightgear starts, it will start the Nasal parser and load Nasal (.nas) files from FGDATA/Nasal.

Core modules

The nasal root folder (FGDATA/Nasal/) is scanned for .nas files and these files are loaded (apparantly in alphabetical order). After all .nas files are loaded /sim/signals/nasal-dir-initialized is set, which triggers listeners in some of the files just loaded. This allows to use functions from other core files, which have just been defined, e.g. which were not yet available when parsing the file.

Optional (load-once) modules

After the files in the root directory have been processed, the first level of subdirectories is scanned for .nas files. Each subdirectory defines a module / namespace which becomes available only after the files in the subdirectory have been completly processed, e.g. a variable foo in module bar becomes available as bar.foo only after parsing of the respective folder.

Note

Sub-sub-directories will not be scanned for .nas files - at least not automatically on FG startup. Of course, files of sub-sub-directories can be included (sooner or later) by the Nasal code that is being processed, so optional code can be loaded on demand.

Enabling of load-once modules

From the user (aircraft developer) point of view, enabling of this modules is done by setting the property /nasal/<moduleName>/enabled to true.

If a module is needed by an aircraft, you can just add the following to your aircraft-set.xml file (replace module_name by the name of the desired module):

<PropertyList>
    <nasal>
        <module_name>
            <enabled type="bool">true</enabled>
        </module_name>
    <nasal>
</PropertyList>

Loading is done in the C++ code and is a little bit complicated (see FG sources /src/Scripting/NasalSys.cxx). FGNasalSys::init() scans FGDATA/Nasal for subdirectories and calls FGNasalSys::addModule() for each subdirectory passing its name as module name and a list of all .nas files in it.

FGNasalSys::addModule() in turn creates property nodes for each file like /nasal/<moduleName>/file[i] = <filename>

Caution  For each subdirectory there SHALL be an entry in FGDATA/defaults.xml defining the default state of the module.
Warning  At the time of writing addModule() creates /nasal/<moduleName>/enabled and sets it to true if it was not defined in defaults.xml. This is about to be corrected.

init() continues, sets the property /sim/signal/nasal-dir-initialized to true which will trigger listeners in some of the previously loaded Nasal files.

Next it calls FGNasalSys::loadPropertyScripts() which checks all the /nasal/<moduleName>/enabled nodes. If true, the files will be loaded by calling FGNasalSys::loadModule() which in turn calls FGNasalSys::createModule().

Otherwise, if enabled is false, a listener is added that will load the module when enabled is set to true.

Note  The module name (which defaults to the name of the subdirectory) is also the name of the Nasal namespace in which functions and variables will be created.

If the namespace already exists, the module will be added to it so you can extend existing modules. But be very careful when overloading existing modules, you can easily break things.

Re-loadable modules

See Modules.nas for re-loadable module support. This type of module can be loaded and unloaded at runtime without exiting or restarting FlightGear.