- Code: Select all
if (!contains(me, "_LIBRARY_NAS_"))
io.load_nasal(library, me);
Or something like that, will probably need to play with namespaces a bit. That should load the library in the current namespace if it is not loaded already.
if (!contains(me, "_LIBRARY_NAS_"))
io.load_nasal(library, me);
var load_if_needed = func(file, namespace)
if (!contains(globals, namespace))
io.load_nasal(file, namespace);
will probably need to play with namespaces a bit
TODO:
- document the toolkit better
- error handling: don't trust the user
me.speed_lsnr = setlistener("/sim/speed-up",
func(n) { me.sim_speed = n.getValue() },
startup = 1, runtime = 0);
me.speed_lsnr = setlistener(node: "/sim/speed-up",
fn: func(n) { me.sim_speed = n.getValue() },
init: 1, runtime: 0);
disable: func {
me.timer.stop();
me.reinit_lsnr and removelistener(me.reinit_lsnr);
me.speed_lsnr and removelistener(me.speed_lsnr);
}
enable: func {
var lsnr = setlistener("sim/signals/fdm-initialized", func {
removelistener(lsnr);
me.init();
me.timer.start();
});
}
var InputSwitcher = {
parents:[InstrumentComponent]
new: func(...) {
return {
parents: [me], ...
};
},
...
};
var InputSwitcher = {
new: func(...) {
return {
parents: [me, InstrumentCompenent], ...
};
},
...
};
if (dt == 0) return;
var dt = getprop("/sim/time/delta-sec")*getprop("/sim/speed-up");
when specifying named arguments, the : operator is used (just like if it is a hash) – not the = operator present in Python.
Two questions here:
Why do you want to stop the loop?
Why do you want to stop it only the first time?
Basically, my understanding is that your instruments would stop working on reset. (Apologies since I haven't tested it.)
Also, isn't the "enable" step better handled on creation of an instrument (i.e. the .new() method)?
In general, try to never use builtin variable names as local variables, like your "size" argument: soaring-instrumentation-sdk.nas @ L203. Good syntax highlighting helps with this, and is how I spotted . What editor do you use, btw?
For classes (that's a hint, classes vs objects) derived from InstrumentComponent, I think it's best to go this route:
I would also remove this line (a user might want to update the instrument again within the same frame, which as near as I can tell is when the condition would occur):
- Code: Select all
if (dt == 0) return;
and use this for dt instead (ref: aircraft.nas::lowpass, you can leave the me.sim_speed in there, though):
- Code: Select all
var dt = getprop("/sim/time/delta-sec")*getprop("/sim/speed-up");
I thought the script should cleanup all resources upon receiving the reinit signal, and assumed that the script would be called again afterwards, as in a fresh start. But that is not the case. The script shall leave its internal state as it should be just after initialization.
Basically, my understanding is that your instruments would stop working on reset. (Apologies since I haven't tested it.)Aparently, you don't even need to test it. That is exactly what it happens
On one side, I do like the enable() step, as I think it is easier to understand for users. It's a quite "mechanical" interface if you like: you define the instrument, and turn it on. Everybody can understand that. It also allows for better synchronization in more complex scripts, where you might want to prepare the runtime (i.e. acquire resources, etc) in a setup step, and then start several processes in a coordinated fashion.
and the question is: what should disable() actually do? With my previous understanding of how reinit worked, "unpluging" the instrument from the sim was the obvious choice. However, reinit works in a different way and this has to change. So my current line of thinking is to make enable()/disable() control the update loop, i.e. start/stop the internal timer, and do all resource acquisition in new().
setlistener("sim/signals/reinit", func {
m.timer.stop();
m.initialized = 0;
});
setlistener("sim/signals/fdm-initialized", func {
if (m.timer.isRunning) m.timer.stop();
call(me.init, [], m);
if (m.enabled) m.timer.start();
});
I wonder if it should just be integrated into SGTimer...
you should be saving each listener's ID (as you did previously), so that you can easily remove previously allocated listeners,
After having thought about it, ideally there will be some kind of load/unload property for every subsystem and for whole aircraft as well. Currently /sim/model/path might be a good indicator, otherwise I don't know if we store the path to -set.xml anywhere. I can see aircraft-specific objects, such as galvedro's nice library, having a .del() method to clean everything up and registering a listener for a change of aircraft that calls .del().
instead of manual timer/listener management, it would be really convenient to have some kind of Nasal wrapper to make objects with a "lifetime": once only (only applicable to listeners), per-aircraft (remove on aircraft change), or permanent (default, to ensure backwards-compatibility). That way it's just abstracted away, particularly for when things change. I know I would be the first to volunteer to overhaul outdated code for these purposes, let's just hope that outside aircraft won't need it.
Users browsing this forum: No registered users and 1 guest