]> git.mxchange.org Git - simgear.git/commitdiff
cppbind: automatic conversion of SGReferenced derived pointers.
authorThomas Geymayer <tomgey@gmail.com>
Fri, 25 Oct 2013 22:40:52 +0000 (00:40 +0200)
committerThomas Geymayer <tomgey@gmail.com>
Fri, 25 Oct 2013 23:04:16 +0000 (01:04 +0200)
simgear/nasal/cppbind/Ghost.hxx
simgear/nasal/cppbind/cppbind_test.cxx
simgear/nasal/cppbind/detail/from_nasal_function_templates.hxx

index ac8449673298dbabc2e90a40a6afd6a328bde7b6..3142979d6cdd8086511b6319f3f5707c131f9482 100644 (file)
@@ -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<class T>
 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<class T>
 typename boost::enable_if<
@@ -929,4 +929,28 @@ from_nasal_helper(naContext c, naRef ref, const T*)
   return nasal::Ghost<T>::fromNasal(c, ref);
 }
 
+/**
+ * Convert any pointer to a SGReference based object to a ghost.
+ */
+template<class T>
+typename boost::enable_if<boost::is_base_of<SGReferenced, T>, naRef>::type
+to_nasal_helper(naContext c, T* ptr)
+{
+  return nasal::Ghost<SGSharedPtr<T> >::create(c, SGSharedPtr<T>(ptr));
+}
+
+/**
+ * Convert nasal ghosts/hashes to pointer (of a SGReference based ghost).
+ */
+template<class T>
+typename boost::enable_if<
+  boost::is_base_of<SGReferenced, typename boost::remove_pointer<T>::type>,
+  T
+>::type
+from_nasal_helper(naContext c, naRef ref, const T*)
+{
+  typedef SGSharedPtr<typename boost::remove_pointer<T>::type> TypeRef;
+  return nasal::Ghost<TypeRef>::fromNasal(c, ref).release();
+}
+
 #endif /* SG_NASAL_GHOST_HXX_ */
index 5b265964371230343572f9892118ca87735a35e8..ab62d534f32ed225b12662f452fdcaefaee29147 100644 (file)
@@ -69,9 +69,16 @@ struct DoubleDerived2:
   BaseVec doSomeBaseWork(const BaseVec& v) { return v; }
 };
 
+class SGReferenceBasedClass:
+  public SGReferenced
+{
+
+};
+
 typedef boost::shared_ptr<Derived> DerivedPtr;
 typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
 typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
+typedef SGSharedPtr<SGReferenceBasedClass> SGRefBasedPtr;
 
 typedef boost::weak_ptr<Derived> DerivedWeakPtr;
 
@@ -198,36 +205,44 @@ int main(int argc, char* argv[])
     .method("doIt", &DoubleDerived2::doSomeBaseWork);
 
   Ghost<DerivedWeakPtr>::init("DerivedWeakPtr");
+  Ghost<SGRefBasedPtr>::init("SGRefBasedPtr");
 
   VERIFY( Ghost<BasePtr>::isInit() );
   nasal::to_nasal(c, DoubleDerived2Ptr());
 
   BasePtr d( new Derived );
-  naRef derived = Ghost<BasePtr>::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<BasePtr>::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<BasePtr>::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<SGReferenceBasedClass*>(c, na_ref_based)
+          == ref_based.get() );
+  VERIFY( from_nasal<SGRefBasedPtr>(c, na_ref_based) == ref_based );
+
   VERIFY( Ghost<BasePtr>::isBaseOf(derived) );
   VERIFY( Ghost<DerivedPtr>::isBaseOf(derived) );
   VERIFY( Ghost<DoubleDerived2Ptr>::isBaseOf(derived) );
 
-  VERIFY( Ghost<BasePtr>::fromNasal(c, derived) == d3 );
-  VERIFY( Ghost<BasePtr>::fromNasal(c, derived) != d2 );
-  VERIFY(    Ghost<DerivedPtr>::fromNasal(c, derived)
+  VERIFY( from_nasal<BasePtr>(c, derived) == d3 );
+  VERIFY( from_nasal<BasePtr>(c, derived) != d2 );
+  VERIFY(    from_nasal<DerivedPtr>(c, derived)
           == boost::dynamic_pointer_cast<Derived>(d3) );
-  VERIFY(    Ghost<DoubleDerived2Ptr>::fromNasal(c, derived)
+  VERIFY(    from_nasal<DoubleDerived2Ptr>(c, derived)
           == boost::dynamic_pointer_cast<DoubleDerived2>(d3) );
-  VERIFY( !Ghost<DoubleDerivedPtr>::fromNasal(c, derived) );
+  VERIFY( !from_nasal<DoubleDerivedPtr>(c, derived) );
 
   std::map<std::string, BasePtr> 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<BasePtr>::fromNasal(c, obj.get_naRef()) == d3 );
+  VERIFY( from_nasal<BasePtr>(c, obj.get_naRef()) == d3 );
 
   // Check recursive parents (aka parent-of-parent)
   std::vector<naRef> parents2;
   parents2.push_back(obj.get_naRef());
   Hash derived_obj(c);
   derived_obj.set("parents", parents2);
-  VERIFY( Ghost<BasePtr>::fromNasal(c, derived_obj.get_naRef()) == d3 );
+  VERIFY( from_nasal<BasePtr>(c, derived_obj.get_naRef()) == d3 );
 
   std::vector<naRef> nasal_objects;
   nasal_objects.push_back( Ghost<BasePtr>::create(c, d) );
index 2b75b172038ed96c112a7e3506ab646663e77f3a..324e524d3da797cf523b497d30b2a7ee806d95c5 100644 (file)
@@ -8,7 +8,7 @@
 # define SG_CALL_TRAITS_PARAM(z, n, dummy)\
     typename boost::call_traits<A##n>::param_type a##n
 # define SG_CALL_ARG(z, n, dummy)\
-      to_nasal(ctx, a##n)
+      to_nasal<typename boost::call_traits<A##n>::param_type>(ctx, a##n)
 
   template<
     class Ret