Talk:FGPythonSys: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
No edit summary
Line 51: Line 51:


: So it can be seen that the fundamental design is quite different to Nasal's implementation.  The Python design is more object oriented.  The IO redirection of sys.stdout and sys.stderr, and the IO stream object creation, is however set up via a subsystem ioRedirection() function, to allow for different logging classes to be used in the future.  The Nasal IO functions are located in the Nasal library, so it will require a lot of painful work to beat Nasal into shape to use proper IO redirection into SG_LOG.  Anyway, the actual implementation of this IO redirection is at a lower level than the subsystem interface.
: So it can be seen that the fundamental design is quite different to Nasal's implementation.  The Python design is more object oriented.  The IO redirection of sys.stdout and sys.stderr, and the IO stream object creation, is however set up via a subsystem ioRedirection() function, to allow for different logging classes to be used in the future.  The Nasal IO functions are located in the Nasal library, so it will require a lot of painful work to beat Nasal into shape to use proper IO redirection into SG_LOG.  Anyway, the actual implementation of this IO redirection is at a lower level than the subsystem interface.
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:28, 12 February 2016 (EST)
:: I saw your comments on the forum (and Philosopher's response) - I do agree that there are some subtle differences, but if they are more than just "subtle", my suggestion would be to maintain abstract methods in the base class and implement them in the child class for now. Apart from that, [[Nasal/CppBind]] should make it possible to come up with a mechanism that matches Python's semantics, i.e. regardless of logprint/printlog/printerror etc--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:21, 15 February 2016 (EST)


: Another issue is that Nasal needs a lot of work, almost open heart surgery, to be beaten into shape to act as a normal subsystem.  This issue is unfortunately pretty much a blocker for a scripting subsystem base class at the moment.  I hope though that the test suite and other infrastructure I am working on will help decouple Nasal from the rest of FG and allow this to eventually happen.
: Another issue is that Nasal needs a lot of work, almost open heart surgery, to be beaten into shape to act as a normal subsystem.  This issue is unfortunately pretty much a blocker for a scripting subsystem base class at the moment.  I hope though that the test suite and other infrastructure I am working on will help decouple Nasal from the rest of FG and allow this to eventually happen.


: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:28, 12 February 2016 (EST)
: [[User:Bugman|Bugman]] ([[User talk:Bugman|talk]]) 04:28, 12 February 2016 (EST)
:: Nasal is not a conventional subsystem in that its code is triggered by other subsystems, mainly via [[Callbacks]] through [[Timers]] and [[Listeners]], despite running in the main loop, so that actual Nasal overhead does not show up in the underlying Nasal subsystem, but in arbitrary subsystems modifying properties or running embedded Nasal code (think GUI, scenery, models etc). While that is common practice for the time being, there is nothing preventing us from registering a Nasal child class to inherit from SGSubsystem/Mgr to implement a more proper subsystem, this can be accomplished using [[Nasal/CppBind]] - and Tom is already doing that for many Canvas base-classes, see $FG_SRC/Scripting and any file there using cppbind (the headers) - it's roughly 20-30 lines of code to expose a C++ baseclass to scripting space so that it can be inherited from and registered (see Canvas widgets). 
:: In summary, you are correct of course, but it's more to do with existing code and features than with the Nasal the language/VM or the underlying subsystem.  The main issue here is 3-fold: 1) timers, 2) listeners, 3) tons of spaghetti code in $FG_ROOT/Nasal loaded/executed unconditionally.
:: Anyway, I am willing to help work out decoupling Nasal accordingly, including overlapping work that covers/touches FGPythonSys (i.e. common APIs).--[[User:Hooray|Hooray]] ([[User talk:Hooray|talk]]) 18:21, 15 February 2016 (EST)

Revision as of 23:21, 15 February 2016

FGNasalSys vs FGPythonSys - common baseclass

These are APIs that are sufficiently generic in nature to be moved to a common baseclass that can be shared by FGPythonSys/FGNasalSys:

  • fgvalidatePath()
  • loadResoureFile (fgdata access)
  • printlog(), i.e. wrapping SG_LOG() [1]
  • loadModule()
  • loadPropertyScripts()
  • addcommand()/removecomand()
  • runfgcommand() (with locking, e.g. using SGMutex)


class FGScriptingSystem : public SGSubsystem, public SGPropertyChangeListener {
public:
    FGScriptingSystem();
    virtual ~FGScriptingSystem();

   const char* readfile(const char* file, int* lenOut);

    // Subsystem functions.
    virtual void init();
    virtual void reinit();
    virtual void bind();
    virtual void unbind();
    virtual void update(double dt);
protected:
    // Load and execute a script.
    bool loadModule(SGPath file, const char *module) = 0;
    virtual void loadPropertyScripts() = 0;
    virtual void loadPropertyScripts(SGPropertyNode *n) = 0;

private:

};
I think this is a great idea, though through implementation I am seeing a number of major Nasal vs. Python differences that would require a lot of work on the Nasal side, to abstract that interface.
For example for IO streams, the Nasal logprint() vs. print() functions are very different to the design I am thinking for Python, where I will direct absolutely everything into SG_LOG, using SG_INFO for all STDOUT output, and SG_ALERT for all STDERR output. I am also considering IO stream objects for each of the simgear log priorities to be placed into the 'fg_sys' module (to replace 'sys' module functions), which can be directly written to in a Python script, for example with:
  • fg_sys.stdout.write() (The default STDOUT stream)
  • fg_sys.stderr.write() (The default STDERR stream)
  • fg_sys.stdin.write() (The default STDIN stream, which is totally useless for FlightGear)
  • fg_sys.stdbulk.write()
  • fg_sys.stddebug.write()
  • fg_sys.stdinfo.write()
  • fg_sys.stdwarn.write()
  • fg_sys.stdalert.write()
So it can be seen that the fundamental design is quite different to Nasal's implementation. The Python design is more object oriented. The IO redirection of sys.stdout and sys.stderr, and the IO stream object creation, is however set up via a subsystem ioRedirection() function, to allow for different logging classes to be used in the future. The Nasal IO functions are located in the Nasal library, so it will require a lot of painful work to beat Nasal into shape to use proper IO redirection into SG_LOG. Anyway, the actual implementation of this IO redirection is at a lower level than the subsystem interface.
Bugman (talk) 04:28, 12 February 2016 (EST)


I saw your comments on the forum (and Philosopher's response) - I do agree that there are some subtle differences, but if they are more than just "subtle", my suggestion would be to maintain abstract methods in the base class and implement them in the child class for now. Apart from that, Nasal/CppBind should make it possible to come up with a mechanism that matches Python's semantics, i.e. regardless of logprint/printlog/printerror etc--Hooray (talk) 18:21, 15 February 2016 (EST)
Another issue is that Nasal needs a lot of work, almost open heart surgery, to be beaten into shape to act as a normal subsystem. This issue is unfortunately pretty much a blocker for a scripting subsystem base class at the moment. I hope though that the test suite and other infrastructure I am working on will help decouple Nasal from the rest of FG and allow this to eventually happen.
Bugman (talk) 04:28, 12 February 2016 (EST)
Nasal is not a conventional subsystem in that its code is triggered by other subsystems, mainly via Callbacks through Timers and Listeners, despite running in the main loop, so that actual Nasal overhead does not show up in the underlying Nasal subsystem, but in arbitrary subsystems modifying properties or running embedded Nasal code (think GUI, scenery, models etc). While that is common practice for the time being, there is nothing preventing us from registering a Nasal child class to inherit from SGSubsystem/Mgr to implement a more proper subsystem, this can be accomplished using Nasal/CppBind - and Tom is already doing that for many Canvas base-classes, see $FG_SRC/Scripting and any file there using cppbind (the headers) - it's roughly 20-30 lines of code to expose a C++ baseclass to scripting space so that it can be inherited from and registered (see Canvas widgets).
In summary, you are correct of course, but it's more to do with existing code and features than with the Nasal the language/VM or the underlying subsystem. The main issue here is 3-fold: 1) timers, 2) listeners, 3) tons of spaghetti code in $FG_ROOT/Nasal loaded/executed unconditionally.
Anyway, I am willing to help work out decoupling Nasal accordingly, including overlapping work that covers/touches FGPythonSys (i.e. common APIs).--Hooray (talk) 18:21, 15 February 2016 (EST)