On 18 Apr 2006, at 15:14, Jim Wilson wrote:

What if instead of struggling with externally defined levels, subsystems 

were encapsulated to the extent that they were able to determine when 

the data they needed (dependencies) were satisfied.  Init() functions 

would be simple, and update() would check for data items it needed and 

only perform what it could each cycle until everything was up and running.


If each subsystem could keep track of its own requirements then it would 

be possible to make it not matter which order subsystems were loaded.  The 

subsystem superclass could have a "running" flag in order to reduce the 

code branches in update to a single check once the subsystem knew it had 

all it needed.  I'm not sure how the nasal scripts fit into all of this.  

While nasal is extremely useful,  I can see where these growing bits of 

code reading and updating on a global property tree could create quite 

a mess for a project as complex as FlightGear.


I would be pretty nervous about doing that granularity of checking in update(); I'd much rather keep the checks coarse: have a 'running' flag on SGSubsystem, and an a SGSubsystemMgr::isRunning (that's the same as the /sim/signals properties Melchior was suggesting), but it'd more or less guarantee the first few lines of every update() implementation look like:

void FooSystem::update(double dt)
{
SGSubsystemMgr* ssmgr = gloabls->get_subsystem_manager();
if (!ssmgr->isRunning("dependecy1") || !issmgr->isRunning("dependency2")) {
return;
}
}

Such a scheme would be doable (the overhead is trivial), and named subsystem groups reduce the number of tests, just as they do in the case of listeners. My concern is that this is 'level-triggered' when what some things need is 'edge-triggered' behavior. One possibility would be to have a listener mechanism on SGSubsystemMgr which is notified when subsystems start and stop - probably some kind of callback function pointer. That's essentially identical to Nasal listeners, but in code.

Regarding your comments on the complexity of dependencies for Nasal scripts, I think again the answer is to have the running status of each subsystem stored somewhere, and exposed via the property tree. The trick will be picking good groups, so most things have one or two dependencies, and having some documentation somewhere stating what's in each group.

I'm sure other people can propose potential groups, but I'd imagine:

early (nasal itself, GUI)
time based subsystems (ephemeris, datetime, warp, properties, interpolator)
environmental (weather fetch)
aircraft systems (FDM, electrical, cockpit?, instruments, failures, GPS)
scenery (tile manager, views, panels)
input 
IO subsystems - ATC, traffic, multiplayer
sound

(note I'm not claiming that as a proposed initialization order either!)

Melchior is probably the best person to comment on how appropriate or not these are for the Nasal scripts he's written.

James

Reply via email to