- Code: Select all
<!-- register a new element/type with the tutorial engine, purely from XML -->
<register-type>
<name>timer</name>
<require-arg>delay-sec</require-arg>
<require-arg>nasal</require-arg>
<handler>
# this should probably use maketimer() instead
settimer( getMyArg("delay-sec"), compile_call(getMyArg("nasal") ) );
</handler>
</register-type>
To make this work, we only need to process all "register-type" children and register each type as a new element using its name, and mapping the value of the require-arg lookup to a corresponding getMyArg() callback and then compile/bind/call() the resulting callback: http://plausible.org/nasal/lib.html
The same thing could be done for listeners:
- Code: Select all
<!-- register a new element/type with the tutorial engine, purely from XML -->
<register-type>
<name>listener</name>
<require-arg>property</require-arg>
<require-arg>nasal</require-arg>
<handler>
setlistener( getMyArg("property"), compile_call(getMyArg("nasal") ) );
</handler>
</register-type>
This would all be part of the "prologue" of a tutorial, i.e. during initialization - and it would make new "elements" available to the system, without the Nasal code having to be edited.
Once these elements are registered, they can be used elsewhere, e.g. in the form of:
- Code: Select all
<timer>
<name>demo</demo>
<delay-sec>1.5</delay-sec>
<nasal> print("Hello World from an XML-based timer!"); </nasal>
</timer>
<listener>
<name>demo2</demo>
<!-- we could also support multiple properties per nasal block here -->
<property>/autopilot/locks/altitude</property>
<nasal> print("Please dont use the autopilot or route manager!!"); </nasal>
</listener>
As can be seen, just supporting custom handlers to be registered would allow all sorts of interesting extensions, without leaving XML space necessarily, which is good, because it allows us to reuse tutorial building blocks via include/params.
Using the same mechanism, we could easily provide elements for creating AI traffic, but also showing GUI dialogs (NPC interaction or mission briefings) or running fgcommands directly.