20,741
edits
Line 340: | Line 340: | ||
There's a plan to eventually unify all those helpers and provide them as part of the FGNasalSys class (or some custom abstract base class that C++ classes should implement to expose objects to Nasal), so that they automatically become available to all users of the Nasal subsystem. | There's a plan to eventually unify all those helpers and provide them as part of the FGNasalSys class (or some custom abstract base class that C++ classes should implement to expose objects to Nasal), so that they automatically become available to all users of the Nasal subsystem. | ||
Looking at the code in NasalPositioned.cxx: http://gitorious.org/fg/flightgear/blobs/78afdb3c2227e75fc1542b3992dcea26181d98cf/src/Scripting/NasalPositioned.cxx#line139 | |||
The function bodies for these helpers are largely identical: | |||
* naRef ghostForPositioned(naContext c, const FGPositioned* pos); | |||
* naRef ghostForAirport(naContext c, const FGAirport* apt) | |||
* naRef ghostForNavaid(naContext c, const FGNavRecord* n) | |||
* naRef ghostForRunway(naContext c, const FGRunway* r) | |||
* naRef ghostForWaypt(naContext c, const flightgear::Waypt* wpt) | |||
So they could be replaced by a single template: | |||
<syntaxhighlight lang="cpp"> | |||
template <class T> | |||
static T* | |||
getGhost(naRef r) | |||
{ | |||
if( naGhost_type(r) == &T::GhostType) | |||
return (T*) naGhost_ptr(r); | |||
return 0; | |||
} | |||
</syntaxhighlight> | |||
This would only require adding a new "[b]naGhostType[/b]" member to the FGPositioned class (and automatically to FGAirport, FGNavRecord, FGRunway because they are derived from FGPositioned). | |||
So it would make sense to simply use a new "FGNasalWrapper" class, add it to the top of NasalSys.hxx, i.e. for C++ classes that are intended to be exposed to Nasal ? | |||
<syntaxhighlight lang="cpp"> | |||
class FGNasalWrapper { | |||
public: | |||
protected: | |||
naGhostType GhostType; | |||
private: | |||
}; | |||
</syntaxhighlight> | |||
This would provide an opportunity to come up with an interface that is required to expose C++ classes as Nasal ghosts. | |||
And then, by changing positioned.hxx such that it derives from the new "FGNasalWrapper" class: | |||
<syntaxhighlight lang="cpp"> | |||
class FGPositioned : public SGReferenced, public FGNasalOOPWrapper { .... }; | |||
</syntaxhighlight> | |||
Once each instance/subclass of FGPositioned, has such a "GhostType" field, the getMember() wrappers you created [http://gitorious.org/fg/flightgear/blobs/78afdb3c2227e75fc1542b3992dcea26181d98cf/src/Scripting/NasalPositioned.cxx#line55 at the top of NasalPositioned.hxx], could be moved to the new FGNasalWrapper class, so that the GhostType field could be initialized by the ctor, using its own getMember() method: | |||
<syntaxhighlight lang="cpp"> | |||
class FGNasalWrapper { | |||
public: | |||
FGNasalWrapper(void *ghost_destructor, const char* ghost_name | |||
const char* getMember(naContext c, void* g, naRef field, naRef* out); | |||
protected: | |||
naGhostType GhostType; | |||
private: | |||
}; | |||
</syntaxhighlight lang="cpp"> | |||
The ghost_destructor could also be implemented as a method of FGNasalWrapper (rather than being a global void* function), so that each C++ class that is to be exposed to Nasal, would only need to implement the class-specific methods. | |||
Ultimately, this would also make it possible to reimplement the ghostFor* helpers as a template: http://gitorious.org/fg/flightgear/blobs/78afdb3c2227e75fc1542b3992dcea26181d98cf/src/Scripting/NasalPositioned.cxx#line139 | |||
* ghostForPositioned(); | |||
* ghostForAirport(); | |||
* ghostForNavaid(); | |||
* ghostForRunway(); | |||
* ghostForWaypt(); | |||
So that the "getGhost" method could be a part of the NasalWrapper class: | |||
<syntaxhighlight lang="cpp"> | |||
template <class T> | |||
naRef getGhost(naContext c, const T* pos) | |||
{ | |||
if (!pos) { | |||
return naNil(); | |||
} | |||
T::get(pos); // take a ref | |||
return naNewGhost2(c, &T::GhostType, (void*) pos); | |||
} | |||
</syntaxhighlight> | |||
= Passing Pointers to Nasal scripts = | = Passing Pointers to Nasal scripts = |