2,733
edits
m (Copyediting) |
Red Leader (talk | contribs) (Re-link lots of things) |
||
Line 1: | Line 1: | ||
{{ | {{Nasal Internals}} | ||
This article is dedicated to describing how to write custom C/C++ extension functions in order to extend the [[Nasal]] scripting interpreter in FlightGear, for example in order to expose new or existing FlightGear APIs to the Nasal scripting engine, so that Nasal scripts can access additional FlightGear internals. | This article is dedicated to describing how to write custom C/C++ extension functions in order to ''extend the [[Nasal]] scripting interpreter'' in FlightGear, for example in order to expose new or existing FlightGear APIs to the Nasal scripting engine, so that Nasal scripts can access additional FlightGear internals. | ||
<!-- Some interesting ideas for extending Nasal this way have been collected at [[Proposals:Nasal related]]. Article was deleted 1 July 2014. /Johan G, 12 December 2014 --> | <!-- Some interesting ideas for extending Nasal this way have been collected at [[Proposals:Nasal related]]. Article was deleted 1 July 2014. /Johan G, 12 December 2014 --> | ||
== Status (cppbind) == | == Status (cppbind) == | ||
As of 03/2013, this article should be considered depreciated, we have [[Nasal/CppBind | As of 03/2013, this article should be considered depreciated, we have [[Nasal/CppBind]], a new C++-based API for exposing C/C++ functions/data structures to Nasal and vice versa in {{simgear file|simgear/nasal/cppbind}}. Usually, there should be no need to use the bare Nasal APIs anymore for exposing functions/data to Nasal or Nasal-space types to C++, except for people working on the '''cppbind''' framework itself. | ||
The cppbind framework is much more generic and high level than the bare APIs documented here, it includes unit testing support and makes use of modern C++ features like templates and STL support, including SimGear specific types like SGPath/SGGeod etc, its overhead is fairly small (not just performance, but also LoC to create new bindings). | The cppbind framework is much more generic and high level than the bare APIs documented here, it includes unit testing support and makes use of modern C++ features like templates and STL support, including SimGear specific types like SGPath/SGGeod etc, its overhead is fairly small (not just performance, but also LoC to create new bindings). | ||
Line 36: | Line 36: | ||
If you have any Nasal specific questions, you will want to check out the [[Nasal FAQ]], feel free to ask new questions or help answer and refine existing ones. | If you have any Nasal specific questions, you will want to check out the [[Nasal FAQ]], feel free to ask new questions or help answer and refine existing ones. | ||
All Nasal related articles can be found in | All Nasal related articles can be found in [[:Category:Nasal]]. | ||
{{Note|FlightGear's version of the Nasal interpreter is maintained in the | {{Note|FlightGear's version of the Nasal interpreter is maintained in the SimGear git repository, inside the {{simgear file|simgear/nasal}} folder, the most important header file detailing the internal Nasal API is [http://api-docs.freeflightsim.org/simgear/nasal_8h.html nasal.h], you will want to check this out for the latest changes and information.}} | ||
You will probably also want to check out the {{ | You will probably also want to check out the {{simgear file|simgear/nasal}} folder for specific examples on using the various Nasal APIs that are not yet covered here completely. | ||
{{caution|As of 05/2009, this article is work in progress, and ''none'' of the examples have so far been tested/compiled. | {{caution|As of 05/2009, this article is work in progress, and ''none'' of the examples have so far been tested/compiled. | ||
Line 48: | Line 48: | ||
== Intro == | == Intro == | ||
In FlightGear, the simplest way to add new extension functions is to look at the existing functions | In FlightGear, the simplest way to add new extension functions is to look at the existing functions at {{flightgear file|src/Scripting/NasalSys.cxx|l=747}}. | ||
There is a static table of function pointers (named funcs[]) referencing extension functions, along with their corresponding names in Nasal: {{ | There is a static table of function pointers (named funcs[]) referencing extension functions, along with their corresponding names in Nasal: {{flightgear file|src/Scripting/NasalSys.cxx|l=482}}. | ||
The following is a copy of the extension function list, taken in 12/2014: | The following is a copy of the extension function list, taken in 12/2014: | ||
Line 83: | Line 83: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
(Note, as of 06/2012, some of these functions have meanwhile been moved to a different file and are initialized there: NasalPositioned.cxx) | (Note, as of 06/2012, some of these functions have meanwhile been moved to a different file and are initialized there: {{flightgear file|src/Scripting/NasalPositioned.cxx|t=NasalPositioned.cxx}}) | ||
So, the basic format is "name" (string), function_pointer - whereas "name" refers to the internal name used by Nasal and its scripts, and "function_pointer" has to use the right function signature and is a pointer to the implementation of the Nasal function in C/C++ code space: | So, the basic format is "name" (string), function_pointer - whereas "name" refers to the internal name used by Nasal and its scripts, and "function_pointer" has to use the right function signature and is a pointer to the implementation of the Nasal function in C/C++ code space: | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
// The function signature for an extension function: | |||
typedef naRef (*naCFunction)(naContext ctx, naRef me, int argc, naRef* args); | |||
</syntaxhighlight> | </syntaxhighlight> | ||
You will need to add your new extension function to this list of static functions, preferably following the existing naming convention (i.e. "f_" prefix). | You will need to add your new extension function to this list of static functions, preferably following the existing naming convention (i.e. "f_" prefix). | ||
If your extension functions are likely to be fairly low level, and will thus be provided with a more abstract wrapper in Nasal space, these functions should use a prepended undercore ("_"), such as the _fgcommand, _setlistener, _cmdarg and _interpolate functions. | If your extension functions are likely to be fairly low level, and will thus be provided with a more abstract wrapper in Nasal space, these functions should use a prepended undercore ("_"), such as the {{func link|_fgcommand}}, {{func link|_setlistener}}, {{func link|_cmdarg}} and {{func link|_interpolate}} functions. | ||
== Extension function signature == | == Extension function signature == | ||
These extension functions look like: | These extension functions look like: | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static naRef f_your_function(naContext c, naRef me, int argc, naRef* args) | |||
{ | |||
// ... | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 111: | Line 109: | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
static naRef f_cool (naContext c, naRef me, int argc, naRef* args) | |||
{ | |||
SG_LOG(SG_GENERAL, SG_ALERT, "Nasal:cool() got executed!"); | |||
return naNil(); | |||
} | |||
</syntaxhighlight> | </syntaxhighlight> | ||
Line 177: | Line 175: | ||
The "me" reference is set if the function was called as a method call on an object (e.g. object.your_function() instead of just your_function(), in which case "me" would be set to the object (Nasal hash)). | The "me" reference is set if the function was called as a method call on an object (e.g. object.your_function() instead of just your_function(), in which case "me" would be set to the object (Nasal hash)). | ||
The naRef objects can be manipulated using the functions in [http:// | The naRef objects can be manipulated using the functions in [http://api-docs.freeflightsim.org/simgear/nasal_8h.html nasal.h]. | ||
For the latest copy of the file, see | For the latest copy of the file, see {{simgear file|simgear/nasal/nasal.h}} | ||
Basically, you can check the type of the reference with the following naIs*() functions: | Basically, you can check the type of the reference with the following naIs*() functions: | ||
Line 320: | Line 318: | ||
== Wrapping C++ classes as Nasal objects with cppbind == | == Wrapping C++ classes as Nasal objects with cppbind == | ||
Please see: {{ | Please see: {{simgear file|simgear/nasal/cppbind}} | ||
<!-- | <!-- | ||
'''To be written by Hooray & Zakalawe''' | '''To be written by Hooray & Zakalawe''' | ||
For the time being, it's a good idea to take a look at the FGPositioned wrappers for the navdb to see how this is done in Nasal, see | For the time being, it's a good idea to take a look at the FGPositioned wrappers for the navdb to see how this is done in Nasal, see {{flightgear file|src/Scripting/NasalPositioned.cxx}}. | ||
Also, the implementation of the SGPropertyNode bindings in | Also, the implementation of the SGPropertyNode bindings in {{flightgear file|src/Scripting/nasal-props.cxx}} contains additional examples. | ||
--> | --> | ||
== Passing pointers to Nasal scripts == | == Passing pointers to Nasal scripts == |