13,212
edits
m (+-headings: All headings down one level, level 1 (one equal sign) should not be used in articles. It is used by the wiki software for the article title.) |
|||
Line 1: | Line 1: | ||
= Nasal runtime re-loadable modules = | == Nasal runtime re-loadable modules == | ||
== Introduction and motivation == | === Introduction and motivation === | ||
Nasal (Flightgears integrated scripting language) comes with a limited number of [[Nasal library|core functions]]. | Nasal (Flightgears integrated scripting language) comes with a limited number of [[Nasal library|core functions]]. | ||
The language was [[Howto:Extend Nasal|extended by C++ functions]], as well as libraries written in Nasal (e.g. [[Nasal library/props|props]], [[Nasal library/io|io]], [[Nasal library/math|math]], [[Nasal library/debug|debug]] ...). | The language was [[Howto:Extend Nasal|extended by C++ functions]], as well as libraries written in Nasal (e.g. [[Nasal library/props|props]], [[Nasal library/io|io]], [[Nasal library/math|math]], [[Nasal library/debug|debug]] ...). | ||
Line 9: | Line 9: | ||
For more information on how and when these files are loaded see [[Nasal Initialization]]. | For more information on how and when these files are loaded see [[Nasal Initialization]]. | ||
== Differences between add-ons and modules == | === Differences between add-ons and modules === | ||
While there are many similarities between add-ons and modules, some words on the differences: | While there are many similarities between add-ons and modules, some words on the differences: | ||
Line 18: | Line 18: | ||
Add-ons are selected by the user before launching FlightGear, thus they may or '''may not be available''' at runtime. | Add-ons are selected by the user before launching FlightGear, thus they may or '''may not be available''' at runtime. | ||
= HowTo / Examples = | == HowTo / Examples == | ||
First some examples, the API documentation follows below. | First some examples, the API documentation follows below. | ||
== Nasal modules in an aircraft (e.g. for development) == | === Nasal modules in an aircraft (e.g. for development) === | ||
Nasal code for an aircraft is usually loaded by a XML declaration in the <aircraft>-set.xml file like this: | Nasal code for an aircraft is usually loaded by a XML declaration in the <aircraft>-set.xml file like this: | ||
<syntaxhighlight lang="xml"> | <syntaxhighlight lang="xml"> | ||
Line 82: | Line 82: | ||
|margin=10px |width=50%}} | |margin=10px |width=50%}} | ||
== Nasal frameworks == | === Nasal frameworks === | ||
Another usecase for Modules.nas is frameworks that need reload support. | Another usecase for Modules.nas is frameworks that need reload support. | ||
A framework usually provides more or less generic functionality that has to be adapted (configured) for a specific usecase (e.g. a specific aircraft). | A framework usually provides more or less generic functionality that has to be adapted (configured) for a specific usecase (e.g. a specific aircraft). | ||
Line 98: | Line 98: | ||
A module must contain at least the file '''main.nas''' (default, other filename is possible) and should contain the functions {{code|main()}} and {{code|unload()}}. | A module must contain at least the file '''main.nas''' (default, other filename is possible) and should contain the functions {{code|main()}} and {{code|unload()}}. | ||
=== main() function === | ==== main() function ==== | ||
The main.nas file shall contain a function {{code|main()}} that will be called on load with either the module object as parameter or the parameters passed to the {{code|module.load()}} function. | The main.nas file shall contain a function {{code|main()}} that will be called on load with either the module object as parameter or the parameters passed to the {{code|module.load()}} function. | ||
=== unload() function === | ==== unload() function ==== | ||
If you want the module to be re-/un-loadable, you must make sure to track resources and remove them on onload. | If you want the module to be re-/un-loadable, you must make sure to track resources and remove them on onload. | ||
For this the main.nas shall contain a function {{code|unload()}} that removes any resources which were created by the module. | For this the main.nas shall contain a function {{code|unload()}} that removes any resources which were created by the module. | ||
Line 109: | Line 109: | ||
{{note|Calls to {{code|setlistener()}} and {{code|maketimer()}} are automatically tracked by the Module class for you, timers will be stopped automatically, listeners will be removed automatically on {{code|unload()}}.}} | {{note|Calls to {{code|setlistener()}} and {{code|maketimer()}} are automatically tracked by the Module class for you, timers will be stopped automatically, listeners will be removed automatically on {{code|unload()}}.}} | ||
=== Rules for Module names === | ==== Rules for Module names ==== | ||
# Module names shall contain only letters (a-z, A-Z), numbers (0-9) and underscores ('_'). | # Module names shall contain only letters (a-z, A-Z), numbers (0-9) and underscores ('_'). | ||
# The name must contain at least one letter so it cannot be confused with a number | # The name must contain at least one letter so it cannot be confused with a number | ||
Line 120: | Line 120: | ||
}} | }} | ||
= modules.nas = | == modules.nas == | ||
In ''modules.nas'' the class ''Module'' is defined. | In ''modules.nas'' the class ''Module'' is defined. | ||
A module object holds information about the path and filename of the Nasal script and supports unloading and reloading the code at runtime | A module object holds information about the path and filename of the Nasal script and supports unloading and reloading the code at runtime | ||
Line 130: | Line 130: | ||
}} | }} | ||
== library functions == | === library functions === | ||
=== modules.isAvailable() === | ==== modules.isAvailable() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = modules.isAvailable(module_name); | |syntax = modules.isAvailable(module_name); | ||
Line 143: | Line 143: | ||
}} | }} | ||
=== modules.setDebug() === | ==== modules.setDebug() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = modules.setDebug(module_name, [debug=1]); | |syntax = modules.setDebug(module_name, [debug=1]); | ||
Line 156: | Line 156: | ||
}} | }} | ||
=== modules.load() === | ==== modules.load() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = modules.load(module_name, [namespace_name]); | |syntax = modules.load(module_name, [namespace_name]); | ||
Line 168: | Line 168: | ||
}} | }} | ||
== Methods of class Module == | === Methods of class Module === | ||
=== setFilePath() === | ==== setFilePath() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.setFilePath(path); | |syntax = mymod.setFilePath(path); | ||
Line 177: | Line 177: | ||
}} | }} | ||
=== setMainFile() === | ==== setMainFile() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.setMainFile(filename); | |syntax = mymod.setMainFile(filename); | ||
Line 193: | Line 193: | ||
}} | }} | ||
=== setNamespace() === | ==== setNamespace() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.setNamespace(namespace); | |syntax = mymod.setNamespace(namespace); | ||
Line 201: | Line 201: | ||
}} | }} | ||
=== setDebug() === | ==== setDebug() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.setDebug(debug=1); | |syntax = mymod.setDebug(debug=1); | ||
Line 213: | Line 213: | ||
}} | }} | ||
=== load() === | ==== load() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.load([args]); | |syntax = mymod.load([args]); | ||
Line 221: | Line 221: | ||
}} | }} | ||
=== unload() === | ==== unload() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.unload(); | |syntax = mymod.unload(); | ||
Line 227: | Line 227: | ||
}} | }} | ||
=== reload() === | ==== reload() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.reload(); | |syntax = mymod.reload(); | ||
Line 233: | Line 233: | ||
}} | }} | ||
=== get() === | ==== get() ==== | ||
{{Nasal doc | {{Nasal doc | ||
|syntax = mymod.get(var_name); | |syntax = mymod.get(var_name); | ||
Line 244: | Line 244: | ||
}} | }} | ||
= Property tree interface for modules.nas = | == Property tree interface for modules.nas == | ||
In the property tree there is a subtree /nasal to control modules and get some statistics. | In the property tree there is a subtree /nasal to control modules and get some statistics. | ||
The properties available depend on the type of module ("load-once" or "reloadable", see [[Nasal Initialization]] for more information on the differences). | The properties available depend on the type of module ("load-once" or "reloadable", see [[Nasal Initialization]] for more information on the differences). | ||
== Reloadable modules / frameworks == | === Reloadable modules / frameworks === | ||
Modules handled by modules.nas will have their properties in /nasal/modules/<moduleName> where <moduleName> is given by the developer when calling either | Modules handled by modules.nas will have their properties in /nasal/modules/<moduleName> where <moduleName> is given by the developer when calling either | ||
{{code|Module.new("<moduleName>")}} or {{code|modules.load("<moduleName>")}}. | {{code|Module.new("<moduleName>")}} or {{code|modules.load("<moduleName>")}}. | ||
Line 268: | Line 268: | ||
|} | |} | ||
== Legacy load-once modules == | === Legacy load-once modules === | ||
A legacy load-once module is a direct (1st level) subdirectory of FGDATA/Nasal/ and its corresponding property tree is /nasal/<moduleName>/ where <moduleName> equals the name of the subdirectory. | A legacy load-once module is a direct (1st level) subdirectory of FGDATA/Nasal/ and its corresponding property tree is /nasal/<moduleName>/ where <moduleName> equals the name of the subdirectory. | ||
It is handled by C++ code and must have a corresponding entry in FGDATA/defaults.xml which defines a property "enabled" and optionally a property "module". | It is handled by C++ code and must have a corresponding entry in FGDATA/defaults.xml which defines a property "enabled" and optionally a property "module". | ||
Line 278: | Line 278: | ||
The bool "loaded" property shows the status of the module. | The bool "loaded" property shows the status of the module. | ||
= Existing modules with reload support = | == Existing modules with reload support == | ||
Stable Nasal frameworks which support reloading can be added to ''FGDATA/Nasal/modules/<module_name>''. | Stable Nasal frameworks which support reloading can be added to ''FGDATA/Nasal/modules/<module_name>''. | ||
This allows an aircraft developer to configure the framework for a specific aircraft and make use of the reload magic while developing the configuration. | This allows an aircraft developer to configure the framework for a specific aircraft and make use of the reload magic while developing the configuration. |