I've been looking at the implementation of some the checklists involved here, and I think it would be a good idea to localize any custom Nasal blocks, and instead introduce custom fgcommands using the addcommand() API - basically the reason being that there could be an aircraft-specific API using fgcommands for starting engines, instead of having aircraft-specific "Nasal blobs" in each checklist file. A while ago, this was actually discussed on the devel list, too. In other words, an "fgcommand" (implemented in Nasal) would help better isolate checklists from aircraft specifics.
For instance, here's a common snippet of code that could be easily generalized, and provided, as a custom fgcommand:
http://sourceforge.net/p/flightgear/fga ... ngines.xml- Code: Select all
setprop("controls/engines/engine[1]/starter", 1);
var t = maketimer(3.0, func {
setprop("controls/engines/engine[1]/starter", 0);
});
t.singleShot = 1;
t.start()
This is basically boilerplate code that is found in a few other places, with only the "index" being different for each engine obviously.
So I would suggest to establish a best practice and introduce/register a dedicated fgcommand for such generic snippets, and use properties for parameterizing those:
http://wiki.flightgear.org/Nasal_librar ... mand.28.29The other concern here being that we want to fully support reset/re-init and saving/loading flights at some point, as well as switching aircraft sooner or later. So it does make sense to generalize checklists and get rid of any non-generic Nasal snippets, and introduce "fgcommands" as the shim layer in between aircraft specifics and checklists.
A simple function generator could be used for creating the corresponding helper functions automatically:
- Code: Select all
var func = makeEngineStarterCb = func(index) {
return func() {
var node = "controls/engines/engine[" ~ index ~ "]/starter";
setprop(node, 1);
var t = maketimer(3.0, func {
setprop(node, 0);
});
t.singleShot = 1;
t.start()
};
}
which would mean that aircraft specific APIs would live in the aircraft namespace, and would not need to be part of the checklists themselves, i.e. those could simply be referring to an "abstract" fgcommand instead:
- Code: Select all
addcommand("aircraft.startEngine0", makeEngineStarterCb(index:0));
addcommand("aircraft.startEngine1", makeEngineStarterCb(index:1));
Which translates into less work for people wanting to reuse/maintain existing checklists, because aircraft specific code would live in *.nas files, while checklists would primarily contain fgcommands as "pointers" for functionality maintained elsewhere - as can be seen, such a checklist should be pretty straightforward to port to other aircraft, too - even without adding tons of spaghetti code to the checklist.xml files.
Basically, if we want to ensure that checklists become the foundation for enforcing the DRY-principle, we need to ensure that they're mostly aircraft-agnostic and ideally "declarative", i.e. contain as little hard-coded Nasal assumptions as possible, and delegate such stuff to aircraft specific Nasal modules.