Modules.nas: Difference between revisions
(Initial draft) |
m (→Introduction and motivation: + links) |
||
Line 3: | Line 3: | ||
== 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 extended by C++ functions as well as libraries written in Nasal (e.g. props, io, math, debug ...). | The language was [[Howto:Extend Nasal|extended by C++ functions]], as well as libraries written in Nasal (e.g. [[Nasal library/props.nas|props]], [[Nasal library/io|io]], [[Nasal library/math|math]], [[Nasal library/debug|debug]] ...). | ||
The latter are stored in the | |||
The latter are stored in the [[Fgdata]] repository under /Nasal and loaded automatically by FlightGear. | |||
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]]. | ||
To avoid loading files needlessly modules.nas was written to allow | |||
To avoid loading files needlessly modules.nas was written to allow run-time (re-)loadable Nasal modules, that are loaded on demand only. | |||
== modules.nas == | == modules.nas == |
Revision as of 16:14, 13 January 2020
Nasal runtime loadable modules
Introduction and motivation
Nasal (Flightgears integrated scripting language) comes with a limited number of core functions. The language was extended by C++ functions, as well as libraries written in Nasal (e.g. props, io, math, debug ...).
The latter are stored in the Fgdata repository under /Nasal and loaded automatically by FlightGear. For more information on how and when these files are loaded see Nasal Initialization.
To avoid loading files needlessly modules.nas was written to allow run-time (re-)loadable Nasal modules, that are loaded on demand only.
modules.nas
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 (e.g. without restarting Flightgear as a whole) by tracking some critical resources like listeners and timers.
Parts of this functionality where added to the addons manager earlier and have been extracted now to avoid code duplication.
Differences between add-ons and modules
While there are many similarities between add-ons and modules, some words on the differences:
Modules are distributed with Flightgear as part of FGDATA. Add-ons have to be downloaded separatly by a flightgear user from wherever the author of the add-on publishes the add-on.
Modules can be loaded e.g. by an aircraft if the aircraft developer wants to make use of the module. Add-ons are selected by the user before launching Flightgear, thus they may or may not be available at runtime.
Nasal modules
Loadable modules are stored in subdirectories of FGDATA/Nasal/modules/ as these subdirectories will not be loaded automatically by Flightgear on start. However, modules.nas will scan this directory to create a list of available modules (= list of subdirectories). Each module correspondes to one subdirectory and the direcory name is also the module name.
A module must contain at least the file main.nas (default, other filename is possible)
main() function
The main.nas file shall contain a function main that will be called on load with either the module object as parameter or the parameters passed to the module.load() 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. For this the main.nas shall contain a function unload that removes any resources which were created by the module. Exception: setlistener and maketimer are automatically tracked by Module class for you, timers will be stopped automatically, listeners will be removed automatically on unload().
Example: any canvas created by the module should have called its del() method here.
Rules for Module names
- 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 shall not match any existing .nas file or directory in FGDATA/Nasal to avoid namespace clashes
library functions
modules.isAvailable()
modules.isAvailable(module_name);
This function returns true, if there is a module (subdirectory) in FGDATA/Nasal/modules/ with the given name.
- module_name
- The name of the module (=subdirectory in Nasal/modules) to load.
Example
if (modules.isAvailable("foo_bar")) {
modules.load("foo_bar");
}
modules.setDebug()
modules.setDebug(module_name, [debug=1]);
This function enables debugging for a module. It must be called before load()!
- module_name
- The name of the module (=subdirectory in Nasal/modules) to load.
- debug
- Defaults to 1 (true), use 0 to disable debug.
Example
var debug = 1;
modules.setDebug("foo_bar", debug);
modules.load()
modules.load(module_name, [namespace_name]);
This function attempts to load a module from FGDATA/Nasal/modules/
- module_name
- The name of the module (=subdirectory in Nasal/modules) to load.
- namespace_name
- Optional, load module to a different namespace.
Example
modules.load("foo_bar");
Methods of class Module
setFilePath()
mymod.setFilePath(path);
Configure where to look for the main file, e.g. aircraft (sub-)directory.
- path
- File path where the module is stored.
setMainFile()
mymod.setMainFile(filename);
Configure the nasal file to load.
- filename
- File that will be loaded by load().
Example
var my_foo_sys = modules.Module.new("my_aircraft_foo");
my_foo_sys.setDebug(1);
my_foo_sys.setFilePath(getprop("/sim/aircraft-dir")~"/Nasal");
my_foo_sys.setMainFile("foo.nas");
my_foo_sys.load();
setNamespace()
mymod.setNamespace(namespace);
Configure the Nasal namespace to use. Be really carefull when using existing namespaces! unload() or reload() will destroy them!
- namespace
- The Nasal namespace the module code will be loaded into.
load()
mymod.load([args]);
This function attempts to load the module into its namespace.
- optional args
- Arguments are passed to the main() function of the module. If empty, the module object will be passed to main().
unload()
mymod.unload();
This function attempts to remove tracked resources and remove the module by killing its namespace.
reload()
mymod.reload();
Shorthand, calls unload() and load().
get()
mymod.get(var_name);
Returns a variable from modules namespace.
- var_name
- The variable to get.
Example
var foo = modules.load("foo");
var bar = foo.get("bar"); # get variable "bar" defined in FGDATA/Nasal/modules/foo/main.nas (or a file included by this file)
HowTo / Examples
to be written
Existing modules
Module name | Desctiption | time added |
---|---|---|
canvas_efis | framework to manage canvas based EFIS screens | 01/2020 |
canvas_draw | library of drawing functions for canvas | 01/2020 |