Board index FlightGear Development Nasal

Is it possible to reset Nasal at runtime?

Nasal is the scripting language of FlightGear.

Is it possible to reset Nasal at runtime?

Postby Autowings » Tue Nov 12, 2019 7:36 pm

Hi,

I'm testing a nasal script which includes several subscripts by io.include(). I work on the scripts in an external editor and perform the main script test.nas from the nasal console by

Code: Select all
io.load_nasal("~/.fgfs/Aircraft/Testflyer/Nasal/test.nas");


Changes at the script test.nas take effect whenever I save the file and press Execute. But the logical contents of the included files (which contain classes and hashes) is not updated unless I restart Flightgear. I think it's because any included file is loaded only once in the current context. To reload the file the current context has to be deleted.

The need to restart the simulator on every change at one of the sub files is very annoying and frustrating. In the Debug menu there are many options to restart the Network, Autopilot, HUD, Materials, Scenery etc. Why not an option to Restart/Reset Nasal?

Is there any way to restart/reset the nasal system or the current context without restarting the whole program? Or is there any other option to re-include the sub files or "undefine" hashes and classes defined there?

Any help is welcome. Thanks in advance.

Autowings
Autowings
 
Posts: 11
Joined: Thu Oct 31, 2019 9:09 am

Re: Is it possible to reset Nasal at runtime?

Postby Necolatis » Tue Nov 12, 2019 7:48 pm

I think you could make a quick little code snippet that deletes a context by iterating through all of its children.

See this code by Philosopher that list all content in a context, and modify it to delete it all instead of popping up a window and displaying it: http://codepad.org/14koLKeg
"Airplane travel is nature's way of making you look like your passport photo."
— Al Gore
User avatar
Necolatis
 
Posts: 2233
Joined: Mon Oct 29, 2012 1:40 am
Location: EKOD
Callsign: Leto
IRC name: Neco
Version: 2020.3.19
OS: Windows 10

Re: Is it possible to reset Nasal at runtime?

Postby Autowings » Tue Nov 12, 2019 8:12 pm

Thank you for your reply, but I think this won't solve the problem. The main thing is that io.include() does not reload the sub files.

For example, if I execute the script once, and after that I corrupt one of the subscripts by inserting some illegal syntax:

Code: Select all
var CFooClass =
{   new: func(par1,par2)
    {   var m = { parents: [CFooClass] };
        m.foo = par1;
        m.bar = par2;
        kkkkkkkkkkkkk                                    # nasal can not translate this for sure ;-)
        return m;
    }
}


When I try to execute the script a second time (after inserting the kkkkkkkkk) , the interpreter should throw a parse error, but it does not, because the file is simply not reloaded, and the interpreter performs the old version without the k's.

So I look for a way to reset the nasal system to the same state as after loading the aircraft.
Autowings
 
Posts: 11
Joined: Thu Oct 31, 2019 9:09 am

Re: Is it possible to reset Nasal at runtime?

Postby Hooray » Tue Nov 12, 2019 8:27 pm

this is about "hot-swapping", and like you said, you don't just need helpers for that, but you literally need to design your code around the use-case you have in mind, i.e. a signalling mechanism to load/stop/reload and resume code loaded.

We implemented parts of this in various Canvas/MapStructure modules, mainly for debugging/troubleshooting purposes, i.e. faster prototyping, being able to stop a routine and reload everything from disk, without touching the flightgear instance.

But again, it's not something for the faint of heart, i.e. you need a really solid understanding of advanced Nasal concepts, or some kind of CS/SE background to make heads and tails of managing all your resources properly.

"hello world" is trivial to stop/reload/resume - but anything involving timers, listeners, running loops, threads etc is a completely different beast.

You will basically want to create a helper class along the lines of "StoppableResumable" and then add routines for the main events of 1) load, 2) stop, 3) reload, 4) resume

Keep in mind that you will also need a way to deal with potentially running routines that may no longer live in the freshly loaded module, so your cleanup routines must be part of the original module.

Thorsten has created some fairly complex Nasal modules and is using all sorts of fancy control lops and "flags", so you could ask for his opinion to see if/how something like this could be made to work for an actual "application" that is not trivial at all.

But don't expect this to work "as is" - reset/re-init is a pretty fragile piece either way, despite really only having reset a single subsystem, but not even that works reliably - doing this in a selective fashion for certain code only, can become pretty complex pretty soon
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Is it possible to reset Nasal at runtime?

Postby Thorsten » Wed Nov 13, 2019 8:04 am

The need to restart the simulator on every change at one of the sub files is very annoying and frustrating.


Actually not nearly as much as you think - add your Nasal module in development to the ufo, select a small island as startup location, and FG will be up and running in 10-15 seconds - that's quite acceptable for a test cycle.

Just don't make the mistake of starting a complex aircraft in hires scenery over and over during development of a module.

In the Debug menu there are many options to restart the Network, Autopilot, HUD, Materials, Scenery etc. Why not an option to Restart/Reset Nasal?


Don't assume they all work without issues - restarting materials for instance needs to re-load the whole scenery, which is a good part of a full sim restart. Basically Nasal requires a context - which you wouldn't have when just restarting it.

Many bits of Nasal code are for instance loaded/started when the listener 'FDM initialized' fires - in a hypothetical Nasal restart, the currently running code is thrown out, new code is loaded but never started because the listener does not fire again. You're not getting back to the state you expect.

To get a clean Nasal start, you would have to do a full sim restart anyway, so the option would be redundant - you can actually restart the sim.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Is it possible to reset Nasal at runtime?

Postby jsb » Thu Nov 14, 2019 4:24 pm

Hi Autowings,

I recommend you have a look at the addon system which has a reload mechanism for rapid development. In most cases you will be able to reload your nasal script WITHOUT restarting the whole simulator. I added this feature to the addon system as I had exactly the same problem and I needed to restart a lot. The addon system will track nasal setlistener() and maketimer() for you and automatically and remove them on reload.
Have a look here: https://sourceforge.net/p/flightgear/fg ... nk/Addons/

You can download the Skeleton "addon" an base your work on it. If I recall correctly, the Skeleton has a lot of documentation in the files explaining how to use things - some files are optional and only for illustration so you may use them or skip them as needed.

Feel free to contact me in case of further questions
jsb
 
Posts: 285
Joined: Sat Oct 25, 2014 9:17 pm
Location: Hamburg, Germany
Callsign: D-JSB
Version: next
OS: Win7/Linux

Re: Is it possible to reset Nasal at runtime?

Postby Hooray » Fri Nov 15, 2019 4:58 pm

I do remember that we exchanged a number of messages about your implementation, so it might make sense to document your work (wiki) and maybe generalize is so that it can live inside $FG_ROOT/Nasal, so that others can use this more easily, and maybe even extend it as needed, i.e. think about versioning and backward compatibility.

It would also be possible to extend the low-level Nasal APIs (caller,closure,call, bind) to support this particular use-case more easily.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU


Return to Nasal

Who is online

Users browsing this forum: No registered users and 2 guests