From 7cbfa76be4eba1b3781a5bc88d0b33dfb50c5192 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sat, 26 Oct 2013 00:40:52 +0200 Subject: [PATCH] cppbind: automatic conversion of SGReferenced derived pointers. --- simgear/nasal/cppbind/Ghost.hxx | 28 +++++++++++++-- simgear/nasal/cppbind/cppbind_test.cxx | 35 +++++++++++++------ .../detail/from_nasal_function_templates.hxx | 2 +- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/simgear/nasal/cppbind/Ghost.hxx b/simgear/nasal/cppbind/Ghost.hxx index ac844967..3142979d 100644 --- a/simgear/nasal/cppbind/Ghost.hxx +++ b/simgear/nasal/cppbind/Ghost.hxx @@ -898,10 +898,10 @@ namespace nasal } // namespace nasal +// Needs to be outside any namespace to make ADL work /** * Convert every shared pointer to a ghost. */ -// Needs to be outside any namespace to mark ADL work template typename boost::enable_if< nasal::internal::has_element_type< @@ -915,7 +915,7 @@ to_nasal_helper(naContext c, T ptr) } /** - * Convert nasal ghosts/hashes to shared pointer (of a ghost) + * Convert nasal ghosts/hashes to shared pointer (of a ghost). */ template typename boost::enable_if< @@ -929,4 +929,28 @@ from_nasal_helper(naContext c, naRef ref, const T*) return nasal::Ghost::fromNasal(c, ref); } +/** + * Convert any pointer to a SGReference based object to a ghost. + */ +template +typename boost::enable_if, naRef>::type +to_nasal_helper(naContext c, T* ptr) +{ + return nasal::Ghost >::create(c, SGSharedPtr(ptr)); +} + +/** + * Convert nasal ghosts/hashes to pointer (of a SGReference based ghost). + */ +template +typename boost::enable_if< + boost::is_base_of::type>, + T +>::type +from_nasal_helper(naContext c, naRef ref, const T*) +{ + typedef SGSharedPtr::type> TypeRef; + return nasal::Ghost::fromNasal(c, ref).release(); +} + #endif /* SG_NASAL_GHOST_HXX_ */ diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index 5b265964..ab62d534 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -69,9 +69,16 @@ struct DoubleDerived2: BaseVec doSomeBaseWork(const BaseVec& v) { return v; } }; +class SGReferenceBasedClass: + public SGReferenced +{ + +}; + typedef boost::shared_ptr DerivedPtr; typedef boost::shared_ptr DoubleDerivedPtr; typedef boost::shared_ptr DoubleDerived2Ptr; +typedef SGSharedPtr SGRefBasedPtr; typedef boost::weak_ptr DerivedWeakPtr; @@ -198,36 +205,44 @@ int main(int argc, char* argv[]) .method("doIt", &DoubleDerived2::doSomeBaseWork); Ghost::init("DerivedWeakPtr"); + Ghost::init("SGRefBasedPtr"); VERIFY( Ghost::isInit() ); nasal::to_nasal(c, DoubleDerived2Ptr()); BasePtr d( new Derived ); - naRef derived = Ghost::create(c, d); + naRef derived = to_nasal(c, d); VERIFY( naIsGhost(derived) ); VERIFY( std::string("DerivedPtr") == naGhost_type(derived)->name ); BasePtr d2( new DoubleDerived ); - derived = Ghost::create(c, d2); + derived = to_nasal(c, d2); VERIFY( naIsGhost(derived) ); VERIFY( std::string("DoubleDerivedPtr") == naGhost_type(derived)->name ); BasePtr d3( new DoubleDerived2 ); - derived = Ghost::create(c, d3); + derived = to_nasal(c, d3); VERIFY( naIsGhost(derived) ); VERIFY( std::string("DoubleDerived2Ptr") == naGhost_type(derived)->name ); + SGRefBasedPtr ref_based( new SGReferenceBasedClass ); + naRef na_ref_based = to_nasal(c, ref_based.get()); + VERIFY( naIsGhost(na_ref_based) ); + VERIFY( from_nasal(c, na_ref_based) + == ref_based.get() ); + VERIFY( from_nasal(c, na_ref_based) == ref_based ); + VERIFY( Ghost::isBaseOf(derived) ); VERIFY( Ghost::isBaseOf(derived) ); VERIFY( Ghost::isBaseOf(derived) ); - VERIFY( Ghost::fromNasal(c, derived) == d3 ); - VERIFY( Ghost::fromNasal(c, derived) != d2 ); - VERIFY( Ghost::fromNasal(c, derived) + VERIFY( from_nasal(c, derived) == d3 ); + VERIFY( from_nasal(c, derived) != d2 ); + VERIFY( from_nasal(c, derived) == boost::dynamic_pointer_cast(d3) ); - VERIFY( Ghost::fromNasal(c, derived) + VERIFY( from_nasal(c, derived) == boost::dynamic_pointer_cast(d3) ); - VERIFY( !Ghost::fromNasal(c, derived) ); + VERIFY( !from_nasal(c, derived) ); std::map instances; VERIFY( naIsHash(to_nasal(c, instances)) ); @@ -249,14 +264,14 @@ int main(int argc, char* argv[]) Hash obj(c); obj.set("parents", parents); - VERIFY( Ghost::fromNasal(c, obj.get_naRef()) == d3 ); + VERIFY( from_nasal(c, obj.get_naRef()) == d3 ); // Check recursive parents (aka parent-of-parent) std::vector parents2; parents2.push_back(obj.get_naRef()); Hash derived_obj(c); derived_obj.set("parents", parents2); - VERIFY( Ghost::fromNasal(c, derived_obj.get_naRef()) == d3 ); + VERIFY( from_nasal(c, derived_obj.get_naRef()) == d3 ); std::vector nasal_objects; nasal_objects.push_back( Ghost::create(c, d) ); diff --git a/simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx b/simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx index 2b75b172..324e524d 100644 --- a/simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx +++ b/simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx @@ -8,7 +8,7 @@ # define SG_CALL_TRAITS_PARAM(z, n, dummy)\ typename boost::call_traits::param_type a##n # define SG_CALL_ARG(z, n, dummy)\ - to_nasal(ctx, a##n) + to_nasal::param_type>(ctx, a##n) template< class Ret -- 2.39.5