From: Thomas Geymayer Date: Mon, 12 Nov 2012 11:13:06 +0000 (+0100) Subject: More cleanup an move of helper classes to simgear X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=892806cb3fd6c905a18bfcf0ee081c9734a3cd82;p=flightgear.git More cleanup an move of helper classes to simgear --- diff --git a/src/Scripting/NasalCanvas.cxx b/src/Scripting/NasalCanvas.cxx index 2e136ff2d..6ef49d19a 100644 --- a/src/Scripting/NasalCanvas.cxx +++ b/src/Scripting/NasalCanvas.cxx @@ -31,8 +31,6 @@ //#include #include -#include -#include #include #include #include @@ -42,8 +40,10 @@ #include #include +#include #include #include +#include extern naRef propNodeGhostCreate(naContext c, SGPropertyNode* n); @@ -60,275 +60,6 @@ naRef canvasGetNode(naContext c, sc::Canvas* canvas) return propNodeGhostCreate(c, canvas->getProps()); } -namespace nasal -{ - - template - struct class_traits - { - typedef boost::false_type::type is_shared; - typedef T raw_type; - }; - - template - struct class_traits > - { - typedef boost::true_type::type is_shared; - typedef T raw_type; - }; - - template - struct class_traits > - { - typedef boost::true_type::type is_shared; - typedef T raw_type; - }; - - template - struct class_traits > - { - typedef boost::true_type::type is_shared; - typedef T raw_type; - }; - - template - struct SharedPointerPolicy - { - typedef typename class_traits::raw_type raw_type; - - /** - * Create a shared pointer on the heap to handle the reference counting for - * the passed shared pointer while it is used in Nasal space. - */ - static T* createInstance(const T& ptr) - { - return new T(ptr); - } - - static raw_type* getRawPtr(void* ptr) - { - return static_cast(ptr)->get(); - } - }; - - template - struct RawPointerPolicy - { - typedef typename class_traits::raw_type raw_type; - - static T* createInstance() - { - return new T(); - } - - static raw_type* getRawPtr(void* ptr) - { - BOOST_STATIC_ASSERT((boost::is_same::value)); - return static_cast(ptr); - } - }; - - class class_metadata - { - public: - void addNasalBase(const naRef& parent) - { - assert( naIsHash(parent) ); - _parents.push_back(parent); - } - - protected: - const std::string _name; - naGhostType _ghost_type; - std::vector _base_classes; - std::vector _parents; - - explicit class_metadata(const std::string& name): - _name(name) - { - - } - - void addBaseClass(class_metadata* base) - { - assert(base); - std::cout << _name << ": addBase(" << base->_name << ")" << std::endl; - _base_classes.push_back(base); - } - - naRef getParents(naContext c) - { - return nasal::to_nasal(c, _parents); - } - }; - - /** - * Class for exposing C++ objects to Nasal - */ - template - class class_: - public class_metadata, - protected boost::mpl::if_< typename class_traits::is_shared, - SharedPointerPolicy, - RawPointerPolicy >::type - { - private: - typedef typename class_traits::raw_type raw_type; - - public: - - typedef boost::function getter_t; - typedef std::map GetterMap; - - static class_& init(const std::string& name) - { - getSingletonHolder().reset( new class_(name) ); - return *getSingletonPtr(); - } - - static naRef f_create(naContext c, naRef me, int argc, naRef* args) - { - return create(c); - } - - static naRef create( naContext c ) - { - return makeGhost(c, class_::createInstance()); - } - - // TODO use variadic template when supporting C++11 - template - static naRef create( naContext c, const A1& a1 ) - { - return makeGhost(c, class_::createInstance(a1)); - } - - class_& bases(const naRef& parent) - { - addNasalBase(parent); - return *this; - } - - template - typename boost::enable_if - < boost::is_convertible, - class_ - >::type& - bases() - { - Base* base = Base::getSingletonPtr(); - addBaseClass( base ); - - // Replace any getter that is not available in the current class. - // TODO check if this is the correct behavior of function overriding - const typename Base::GetterMap& base_getter = base->getGetter(); - for( typename Base::GetterMap::const_iterator getter = - base_getter.begin(); - getter != base_getter.end(); - ++getter ) - { - if( _getter.find(getter->first) == _getter.end() ) - _getter.insert( *getter ); - } - - return *this; - } - - template - typename boost::enable_if_c - < !boost::is_convertible< Type, class_metadata>::value, - class_ - >::type& - bases() - { - return bases< class_ >(); - } - - template - class_& member( const std::string& field, - Var (raw_type::*getter)() const, - void (raw_type::*setter)(const Var&) = 0 ) - { - naRef (*to_nasal)(naContext, Var) = &nasal::to_nasal; - _getter[field] = boost::bind( to_nasal, - _1, - boost::bind(getter, _2) ); - return *this; - } - - class_& member( const std::string& field, - const getter_t& getter ) - { - _getter[field] = getter; - return *this; - } - - static class_* getSingletonPtr() - { - return getSingletonHolder().get(); - } - - const GetterMap& getGetter() const - { - return _getter; - } - - private: - - typedef std::auto_ptr class_ptr; - GetterMap _getter; - - explicit class_(const std::string& name): - class_metadata( name ) - { - _ghost_type.destroy = &destroyGhost; - _ghost_type.name = _name.c_str(); - _ghost_type.get_member = &getMember; - _ghost_type.set_member = 0; - } - - static class_ptr& getSingletonHolder() - { - static class_ptr instance; - return instance; - } - - static naRef makeGhost(naContext c, void *ptr) - { - std::cout << "makeGhost " << ptr << std::endl; - return naNewGhost2(c, &getSingletonPtr()->_ghost_type, ptr); - } - - static void destroyGhost(void *ptr) - { - std::cout << "destroyGhost " << ptr << std::endl; - delete (T*)ptr; - } - - static const char* getMember(naContext c, void* g, naRef field, naRef* out) - { - const std::string key = naStr_data(field); - if( key == "parents" ) - { - if( getSingletonPtr()->_parents.empty() ) - return 0; - - *out = getSingletonPtr()->getParents(c); - return ""; - } - - typename GetterMap::iterator getter = - getSingletonPtr()->_getter.find(key); - - if( getter == getSingletonPtr()->_getter.end() ) - return 0; - - *out = getter->second(c, class_::getRawPtr(g)); - return ""; - } - }; -} - struct Base { int getInt() const @@ -342,25 +73,32 @@ struct Test: { Test(): x(1) {} int x; + void setX(int x_) { x = x_; } + naRef test(int argc, naRef* args) + { + return naNil(); + } }; -typedef nasal::class_ NasalCanvas; +typedef nasal::Ghost NasalCanvas; -void initCanvas() +void initCanvas(naContext c) { NasalCanvas::init("Canvas") .member("_node_ghost", &canvasGetNode) .member("size_x", &sc::Canvas::getSizeX) .member("size_y", &sc::Canvas::getSizeY); - nasal::class_::init("canvas.Element"); - nasal::class_::init("canvas.Group") + nasal::Ghost::init("canvas.Element"); + nasal::Ghost::init("canvas.Group") .bases(); - nasal::class_::init("BaseClass") + nasal::Ghost::init("BaseClass") .member("int", &Base::getInt); - nasal::class_::init("TestClass") - .bases(); + nasal::Ghost::init("TestClass") + .bases() + .member("x", &Test::setX) + .method<&Test::test>("test"); } #if 0 @@ -432,11 +170,11 @@ class NasalObject // TODO switch to boost::/std::function (with C++11 lambdas this can make // adding setters easier and shorter) typedef naRef (Derived::*getter_t)(naContext, const T&); - typedef std::map GetterMap; + typedef std::map MemberMap; const std::string _ghost_name; std::vector _parents; - GetterMap _getter; + MemberMap _members; NasalObject(const std::string& ghost_name): _ghost_name( ghost_name ) @@ -446,7 +184,7 @@ class NasalObject _ghost_type.get_member = &Derived::getMember; _ghost_type.set_member = 0; - _getter["parents"] = &NasalObject::getParents; + _members["parents"] = &NasalObject::getParents; } naRef getParents(naContext c, const T&) @@ -471,10 +209,10 @@ class NasalObject static const char* getMember(naContext c, void* g, naRef field, naRef* out) { - typename GetterMap::iterator getter = - getInstance()._getter.find(naStr_data(field)); + typename MemberMap::iterator getter = + getInstance()._members.find(naStr_data(field)); - if( getter == getInstance()._getter.end() ) + if( getter == getInstance()._members.end() ) return 0; *out = (getInstance().*getter->second)(c, *static_cast(g)); @@ -497,7 +235,7 @@ class NasalCanvasEvent: NasalCanvasEvent(): NasalObject("CanvasEvent") { - _getter["type"] = &NasalCanvasEvent::getEventType; + _members["type"] = &NasalCanvasEvent::getEventType; } naRef getEventType(naContext c, const GUIEventPtr& event) @@ -616,9 +354,9 @@ naRef initNasalCanvas(naRef globals, naContext c, naRef gcSave) canvas_module = globals_module.createHash("canvas"); canvas_module.set("_new", f_createCanvas); - canvas_module.set("testClass", nasal::class_::f_create); + canvas_module.set("testClass", nasal::Ghost::f_create); - initCanvas(); + initCanvas(c); return naNil(); }