If all you need is SGPropertyNode access for standalone (non FG) projects, that is even easier to do, see the nasal-props.cxx code, all that would need changing there is using the Python APIs instead of the Nasal stuff. But I stand by my assertion that it is much easier to use a wrapping API like Boost and/or end up using SIP/SWIG to create those bindings automatically (it's working pretty much like IDL)

@Hooray: I have direct experience coding at the Python-C interface (for example this C module implementing a Python module). Using a wrapper layer is not the way to go. You'll see no additional wrapper layer in my code. It is quite popular for those who wish to avoid learning C. But if you know both Python and C, you should work at the raw interface. This is far more advanced and powerful than any wrapper ever could be. For exposing the FG internals to an embedded interpreter, having full control is quite important. If you read the documentation about the C->Python interface (embedding the interpreter), you'll see no mention of wrappers. The person who adds this to FG will need to know C, and therefore the wrapper layer is moot. More useful would be to write the C code to expose the internals of FG via Python functions (in special packages written in C), so that this can be the wrapper the Python developer uses.

@Curt: For the props Python object, I would suggest implementing this in C as a new type of Python object. You can then define the __getattr__(), __setattr__(), __delattr__() methods as C wrapper functions for user interaction with the object. I would suggest that __getattr__() simply be a wrapper for the fgGetNode() C++ function. The C++ property node object can then be presented as a Python object, set up the same way as 'props'. I would personally construct the props object tree in this way, as a fully custom Python object written in C, with the Python object property methods defined as wrappers for the current C interface to the property tree. This will give the control needed for creating a very powerful Python props object.

Using a wrapper layer is not the way to go [...]It is quite popular for those who wish to avoid learning C.

I suggested the use of a wrapper, like Boost.Python, not because people may not know C, but because it takes away from the low-level details of dealing with the low-level nature of C, (e.g. typing, pointers), i.e. due to concepts like RAII and ecapsulation of state (think C pointers, structs etc) that would otherwise need to be handled manually.

The person who adds this to FG will need to know C, and therefore the wrapper layer is moot.

If that were the case, we would not have the cppbind framework either.

I'd say that anybody able to use sophisticated C++ code like Boost.Python would/should also be able to use lower-level C, it's just more tedious obviously - just like assembly is more tedious than C. Obviously, the Nasal engine is also written in C, but the cppbind framework takes away many of the redundant, lower level, details of dealing with Nasal's C interface.

At the end of the day, it's obviously up to the people doing this (should anybody step up to tackle this).

Using a wrapper layer is not the way to go [...]It is quite popular for those who wish to avoid learning C.

I suggested the use of a wrapper, like Boost.Python, not because people may not know C, but because it takes away from the low-level details of dealing with the low-level nature of C,

wrappers add layers of code... layers of code add to processing time and, more importantly, code bloat for no real good reason...

one of my instructors years ago tasked out class with a project... one of the important tenants was that the code be "like a bikini. short and to the point."... wrappers ruin the bikini concept of code (and beaches) O:)

"You get more air close to the ground," said Angalo. "I read that in a book. You get lots of air low down, and not much when you go up.""Why not?" said Gurder."Dunno. It's frightened of heights, I guess."

wrappers add layers of code... layers of code add to processing time and, more importantly, code bloat for no real good reason...

Again, it's about the pain/gain ratio - otherwise, FG would be written in C, or even assembly language, and it would not be using OpenSceneGraph but OpenGL.

The degree of "code bloat" you are talking about is at the code generation level, i.e. is easy to optimize for a compiler's middle-end, in contrast to tons of explicit hand-written spaghetti code. Creating 1000 instances of a class, each having 10 methods and using virtual dispatch, the compiler can make assumptions about the layout of the code, that it simply cannot make when dealing with a similar amount of hand-written code in a lower level language - which even is a problem for RTL and SSA representations (you don't get much lower level than register transfer language or static-single-assignment form).

Thus, the difference is writing 100% of the code yourself, or using a more expressive form to have it generated for you (think classes, templates), by the compiler.Note that the gcc project used to be written entirely in C, but the FSF has meanwhile changed its standpoint and allows C++ as the implementation language for gcc.

So if you want to debate "code bloat", please pick the right audience (I suggest the gcc mailing list), but also make sure that you understand what you are talking about.

In this context, the only thing that matters is to come up with a simple prototype - a wrapper may significantly help with that, if you don't agree that's great - you are free to use C. The main technical argument in favor of not using a wrapper is that the lower-level APIs are much richer obviously, while some wrappers are fairly incomplete still

I am not sure what it is that you are doing, but I agree with bugman's earlier posting on how to proceed with prototyping this.I don't know how many people are actually interested in seeing this implemented - but maybe people should post their skills here to see if we can get this going.I could certainly post a patch within a couple of days to integrate Python according to Curt's experiments, i.e. using a dedicated SGSubsystem - but based on what I am seeing, it seems like a waste of time, unless there's actually someone willing to take it from there - i.e. ideally people who don't just want to "use" Python, but who are already able to patch/build fg and use git.

As far as I can tell, bugman is the only one to volunteer with the coding side of this - any other takers ?Anybody else familiar with C or C++ ?

Meanwhile I wrote a really quick/simple property tree implementation in python ... it doesn't do any of the fancy stuff the FlightGear property system does (like listeners, read/write tracing, etc.) But it does implement a basic shared property tree and allows (in python) direct referencing of property tree elements. https://github.com/AuraUAS/aura-core/bl ... n/props.py

In summary, I have implemented the FGPythonSys subsystem to provide access to the embedded Python interpreter and have implemented the 'props' data structure for accessing the property tree. The code is in the branches:

Here is an AttributeError, for luck:Traceback (most recent call last): File "/flightgear/hangar/py-ogel/test.py", line 1019, in <module> print(props.does_not_exist)AttributeError: The property tree node '/does-not-exist' does not exist.

Wow, that's quite an accomplishment for someone just recently claiming not to be a C++ programmer

I haven't actually built your branches, but went through your commits/patches and read your comments on the devel list.

So take my comments with a grain of salt (of course...), I am making them specifically with a focus on 1) the way Nasal scripting currently works in FlightGear (and the challenges resulting from that), and 2) your comments to hopefully provide Python support as a viable alternative for "software prototyping" and adopting HLA via scripting.

That being said, here's some feedback:

to bring the Python interface up to par with Nasal, timers and listeners would be useful - because those are currently the main building blocks to trigger scripted code in the FlightGear main loop.

Over time, this has become a bit problematic in FlightGear - and the core developers have come to the conclusion that RAII is needed for timer/listener management - which is to say that you would want to look at the OOP maketimer() API in FGNasalSys and explore having two similar APIs for wrapping timer/listener functionality in a makelistener() fashion.

One of the issues causing Nasal code to be a real challenge compared to its C++ counterpart is that none of the Nasal code is using the existing SGSubsystem interface - so if your comments on "software prototyping" were/are serious, we would probably want to look at exposing SGSubsystem as a base class which can be inherited from in Python space to register new subsystems that are implemented in Python.

Like you mentioned on the devel list, many things like the property tree/subsystems would ideally be using some form of IPC (like HLA) to interface with the rest of the simulation - but the logical first step is exposing conventional bindings for the property tree and subsystems.

The way your code is currently structured, it seems that you pretty much used FGNasalSys as a template, using copy & paste. As you probably noticed already, there is quite a bit of overlapping code/functionality, so that it /might/ make sense to introduce a common base class in the form of FGScriptingHost that inherit from SGSubsystem, from which FGPythonSys/FGNasalSys could then inherit their own child-classes, so that shared functionality can reside in the parent class (or customized/overridden accordingly).

Otherwise, I do applaud your effort to make the whole thing compatible with the ongoing reset/re-init work, because that could be cosidered a key part of the whole HLA thing, and most core developers continue to make commits that are basically incompatible with reset/re-init, i.e. complicating matters for Zakalawe tremendously (on the other hand, his reset/re-init and headless work admittedly didn't even make it to the "updated roadmap" either).

Another issue that FGNasalSys is suffering from is that it is designed to be a singleton - and it seems FGPythonSys is sharing this limitation. You may want to reconsider if that is ultimately what you are aiming for - simply because in FG, the whole thing of a scripting session depends largely on the "context" - and here FGNasalSys has become a rather messy part of FlightGear, because we don't even differentiate between different "types" of scripts (think aircraft vs. scenery vs. GUI vs. core etc).

I do think that this could also help address the security issues that Rebecca briefly touched on the devel list, and which I mentioned a few weeks ago on the forum, too

Had FGNasalSys been designed to support independent instances, we could have multiple Nasal interpreters running independently for different script types, and could also grant them different permissions ($FG_HOME, $FG_AIRCRAFT, $FG_SCENERY)

That is something that would greatly help simplify state management for reset/re-init, including use-cases where people may want to save/resume flights (in fact arbitrary simulator state).

For the time being, this is not possible and causing tons of Nasal related challenges for reset/re-init.

Equally, there is the very long standing issue of the Nasal interpreter not being available earlier, despite it being potentially useful.

As you can see on the wiki ("Initializing Nasal earlier"), James, Melchior and others were once contemplating to change that so that FlightGear scripting would become available sooner.

The main thing that prevents this currently for the Nasal VM is the fact that it has a plethora of SGSubsystem-specific "bindings" (basically subsystem-specific APIs) that are dumped into the globals context, and subsequently assumed to be available "automatically".

This is a fragile/broken assumption in an increasingly multi-threaded environment, especially because of the ongoing reset/re-init work, where subsystems may be shut down/restarted "on demand", i.e. their availability may change dynamically.

Like I mentioned previously in this thread, we can easily work around this issue by using the ::bind() and ::unbind() methods to register/remove certain API symbols that depend on other subsystems.

With Nasal it is kinda "too late" unfortunately, because of the plethora of APIs and subsystems currently exposed - for FGPythonSys, this may be much more straightforward, because it's still in its infancy.

In layman's terms that basically means that an API like maketimer() will depends on the events subsystem (in the case of Nasal), whereas maketimer() would depend on the property tree being around, and navDB related APIs would obviously depend on the navDB.

By the way, when it comes to main loop timers, you may want to consider having your own "python-events" subsystem to ensure that Nasal and Python related timers show up in different subsystems (i.e. in the performance monitor stats).

You may also want to provide a startup option to entirely disable Python to help ensure that people can troubleshoot issues and determine if they are affected by Python being active or not - i.e. Python being built-in but adding the subsystem is determined conditionally using a fgGetBool() and or logic in $FG_SRC/Main/options.cxx

I am just suggesting that because we have seen countless of posting where Nasal (and its GC) were said to be the culprit, and only when we walked people through removing all Nasal code from the aircraft (think Su15), they finally realized that Nasal was not the issue at all.

That is also one of the reasons why I believe that the whole "Singleton" assumption will become problematic over time, because if something like FGPythonSys is not a singleton, we can also much more easily stress-test it - while also being able to deal with scripts differently, i.e. depending on their "context" (scope) being aircraft/scenery or GUI related.

Equally, a FGPythonSys interpreter that is up and running very early could become really helpeful for debugging/troubleshooting purposes, but also help us implement benchmarking support.

Overall, my suggestion would really be to closely look at where Nasal "failed", and for which reasons - and try to learn from these lessons.

Incremental re-initialization and saving/loading state really is a crucial part of the simulation, and it would go a long way to come up with a new scripting option that does not suffer from certain restrictions, especially in an increasingly multi-threaded and distributed environment like HLA.

Finally, you did an outstanding job there with all the unit testing you implemented, which is another thing where Nasal failed.

Again, your mileage may vary - so if in doubt, raise any of this with some of the folks on the devel list who are willing to help review/commit your patches - my priorities are obviously biased due to my own experiences with FGNasalSys