Hi fellow wiki editors!

To help newly registered users get more familiar with the wiki (and maybe older users too) there is now a {{Welcome to the wiki}} template. Have a look at it and feel free to add it to new users discussion pages (and perhaps your own).

I have tried to keep the template short, but meaningful. /Johan G

Changes

Jump to: navigation, search

Howto:Extend Nasal

3,163 bytes added, 17:33, 27 June 2012
m
Wrapping Classes as Nasal Objects (ghosts)
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 =
18,253
edits

Navigation menu