[Sorry I've been so long getting back to this; I had to go to Japan on
short notice and this is the first chance I've had in the hotel room
to catch up on personal stuff without jet-lag. :)]
Boris Koenig wrote:
> I don't seem to be able to access a method like gui.Widget.new()
> from an object defined in another module, even though I _think_ ;-)
> I'm doing the right thing, basically that is:
> two ".nas"-files stored in /Nasal/ whose contents will be made
> available as modules within Nasal.
This is an ordering issue. Remember that "loading" and "running"
a script are the same thing in Nasal. If the test2 module loads
before test1, then test1 will not be initialized when test2 tries
to use it.
Some of the Nasal files get around this issue by doing their
initialization work in a timer that is registered to run after a
zero-length timeout. Look for a function called INIT() in several
scripts; I believe one of them has an extensive comment talking about
how the mechanism works.
What would be a better, permanent solution would be to support an
"import" feature. Thus, test2 could execute something like
import("test1") which would stop execution and load the test1 module
before returning. Note that this is another reason to support
recursive interpreter contexts, which I talked about earlier.
> But I did meanwhile play around with the mechanism that you used in
> that example, and I'm surprised to see that it _seems_ already quite
> possible to dynamically create a gui ... I haven't yet tried to
> create every PUI - control, but so far it's already extremely
The current GUI system creates an interface out of a property tree.
That tree can be dynamically created with a Nasal script, so yes: what
you want to do is possible. Not every PUI binding is supported,
though. For example, you can create the interface dynamically, but
you can't change its structure at runtime (although you can destroy
and re-create the dialog, which might be good enough for many
> > If those get used, you can end up in a situation where the "old"
> > and "new" versions of the file are in use simultaneously.
> > Likewise, think of timers registered by
> > the "old" version that get run after the new one is loaded.
> but, this shouldn't happen if the other Nasal code gets reloaded, too -
> right ?
No. Timers and other references are not stored symbolically. That
is, they are stored in C++ space as a NaRef object, which contains a
pointer into the garbage collected Nasal storage. The timer does not
store something like "module.SomeFunction()" which would do the symbol
lookup when executed. If you reload a module, references to the older
objects will stay alive.
> Also, what's the preferred way of implementing a basic "event loop"
> using Nasal, I've played around with this by using either a
> normal loop, or a timer - what's the best choice to poll a certain
> node from the property tree and act upon it assuming a certain
> value ?
You can't "spin" in a Nasal loop at the moment; you will just hang the
simulator. This would require the "multiple contexts" feature to
implement -- the Nasal subsystem could let a script execute for N
instructions and then put it on a "save" list for execution the next
Even then, there are significant performance and resource issues with
that kind of programming. Right now, polling in a timer is probably
your best bet.
Flightgear-devel mailing list