From: Thomas Geymayer Date: Sun, 3 Mar 2013 22:39:26 +0000 (+0100) Subject: cppbind: refactor to_nasal for better name lookup. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=ceae2928aab1ce54412e8f45af93d57b1147bee5;p=simgear.git cppbind: refactor to_nasal for better name lookup. Using template parameter dependent name lookup it is now possible to create to_nasal_helper overloads for custom types and having them used for automatic type conversion with binding methods/member on nasal::Ghost objects. --- diff --git a/simgear/nasal/cppbind/CMakeLists.txt b/simgear/nasal/cppbind/CMakeLists.txt index ed8272fd..0439e6ed 100644 --- a/simgear/nasal/cppbind/CMakeLists.txt +++ b/simgear/nasal/cppbind/CMakeLists.txt @@ -4,21 +4,22 @@ set(HEADERS Ghost.hxx NasalHash.hxx NasalString.hxx - from_nasal_detail.hxx from_nasal.hxx - nasal_traits.hxx to_nasal.hxx ) set(DETAIL_HEADERS + detail/from_nasal_helper.hxx detail/functor_templates.hxx + detail/nasal_traits.hxx + detail/to_nasal_helper.hxx ) set(SOURCES NasalHash.cxx NasalString.cxx - from_nasal.cxx - to_nasal.cxx + detail/from_nasal_helper.cxx + detail/to_nasal_helper.cxx ) simgear_component(nasal/cppbind nasal/cppbind "${SOURCES}" "${HEADERS}") diff --git a/simgear/nasal/cppbind/cppbind_test.cxx b/simgear/nasal/cppbind/cppbind_test.cxx index 90bbf855..9508ca5d 100644 --- a/simgear/nasal/cppbind/cppbind_test.cxx +++ b/simgear/nasal/cppbind/cppbind_test.cxx @@ -50,18 +50,21 @@ struct DoubleDerived: { }; + +typedef boost::shared_ptr BasePtr; + struct DoubleDerived2: public Derived { - + const BasePtr& getBase() const{return _base;} + BasePtr _base; }; -typedef boost::shared_ptr BasePtr; typedef boost::shared_ptr DerivedPtr; typedef boost::shared_ptr DoubleDerivedPtr; typedef boost::shared_ptr DoubleDerived2Ptr; -naRef to_nasal(naContext c, const BasePtr& base) +naRef to_nasal_helper(naContext c, const BasePtr& base) { return nasal::Ghost::create(c, base); } @@ -159,7 +162,8 @@ int main(int argc, char* argv[]) Ghost::init("DoubleDerivedPtr") .bases(); Ghost::init("DoubleDerived2Ptr") - .bases< Ghost >(); + .bases< Ghost >() + .member("base", &DoubleDerived2::getBase); BasePtr d( new Derived ); naRef derived = Ghost::create(c, d); diff --git a/simgear/nasal/cppbind/detail/from_nasal_helper.cxx b/simgear/nasal/cppbind/detail/from_nasal_helper.cxx new file mode 100644 index 00000000..a094e4fb --- /dev/null +++ b/simgear/nasal/cppbind/detail/from_nasal_helper.cxx @@ -0,0 +1,84 @@ +// Conversion functions to convert Nasal types to C++ types +// +// Copyright (C) 2012 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#include "from_nasal_helper.hxx" +#include +#include + +#include + +namespace nasal +{ + //---------------------------------------------------------------------------- + bad_nasal_cast::bad_nasal_cast() + { + + } + + //---------------------------------------------------------------------------- + bad_nasal_cast::bad_nasal_cast(const std::string& msg): + _msg( msg ) + { + + } + + //---------------------------------------------------------------------------- + bad_nasal_cast::~bad_nasal_cast() throw() + { + + } + + //---------------------------------------------------------------------------- + const char* bad_nasal_cast::what() const throw() + { + return _msg.empty() ? bad_cast::what() : _msg.c_str(); + } + + //---------------------------------------------------------------------------- + std::string from_nasal_helper(naContext c, naRef ref, const std::string*) + { + naRef na_str = naStringValue(c, ref); + return std::string(naStr_data(na_str), naStr_len(na_str)); + } + + //---------------------------------------------------------------------------- + SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*) + { + naRef na_str = naStringValue(c, ref); + return SGPath(std::string(naStr_data(na_str), naStr_len(na_str))); + } + + //---------------------------------------------------------------------------- + Hash from_nasal_helper(naContext c, naRef ref, const Hash*) + { + if( !naIsHash(ref) ) + throw bad_nasal_cast("Not a hash"); + + return Hash(ref, c); + } + + //---------------------------------------------------------------------------- + String from_nasal_helper(naContext c, naRef ref, const String*) + { + if( !naIsString(ref) ) + throw bad_nasal_cast("Not a string"); + + return String(ref); + } + +} // namespace nasal diff --git a/simgear/nasal/cppbind/detail/from_nasal_helper.hxx b/simgear/nasal/cppbind/detail/from_nasal_helper.hxx new file mode 100644 index 00000000..865bc8d1 --- /dev/null +++ b/simgear/nasal/cppbind/detail/from_nasal_helper.hxx @@ -0,0 +1,148 @@ +///@file +/// Conversion helpers used by from_nasal(naContext, naRef) +/// +// Copyright (C) 2012 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#ifndef SG_FROM_NASAL_HELPER_HXX_ +#define SG_FROM_NASAL_HELPER_HXX_ + +#include "nasal_traits.hxx" + +#include + +#include +#include + +#include +#include // std::bad_cast +#include + +class SGPath; + +namespace nasal +{ + class Hash; + class String; + + /** + * Thrown when converting a type from/to Nasal has failed + */ + class bad_nasal_cast: + public std::bad_cast + { + public: + /** + * Construct with generic error message + */ + bad_nasal_cast(); + + /** + * Construct from an error message + * + * @param msg Error message/description + */ + explicit bad_nasal_cast(const std::string& msg); + + virtual ~bad_nasal_cast() throw(); + + /** + * Get a description of the cause of the failed cast. + */ + virtual const char* what() const throw(); + + protected: + std::string _msg; + }; + + /** + * Simple pass through for unified handling also of naRef. + */ + inline naRef from_nasal_helper(naContext, naRef ref, const naRef*) + { return ref; } + + /** + * Convert Nasal string to std::string + */ + std::string from_nasal_helper(naContext c, naRef ref, const std::string*); + + /** + * Convert a Nasal string to an SGPath + */ + SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*); + + /** + * Convert a Nasal hash to a nasal::Hash + */ + Hash from_nasal_helper(naContext c, naRef ref, const Hash*); + + /** + * Convert a Nasal string to a nasal::String + */ + String from_nasal_helper(naContext c, naRef ref, const String*); + + /** + * Convert a Nasal number to a C++ numeric type + */ + template + typename boost::enable_if< boost::is_arithmetic, + T + >::type + from_nasal_helper(naContext c, naRef ref, const T*) + { + naRef num = naNumValue(ref); + if( !naIsNum(num) ) + throw bad_nasal_cast("Not a number"); + + return static_cast(num.num); + } + + /** + * Convert a Nasal vector to a std::vector + */ + template + std::vector + from_nasal_helper(naContext c, naRef ref, const std::vector*) + { + if( !naIsVector(ref) ) + throw bad_nasal_cast("Not a vector"); + + int size = naVec_size(ref); + std::vector vec(size); + + for(int i = 0; i < size; ++i) + vec[i] = from_nasal_helper(c, naVec_get(ref, i), static_cast(0)); + + return vec; + } + + /** + * Convert a Nasal vector of 2 elements to a 2d vector + */ + template + typename boost::enable_if, Vec2>::type + from_nasal_helper(naContext c, naRef ref, const Vec2*) + { + std::vector vec = + from_nasal_helper(c, ref, static_cast*>(0)); + if( vec.size() != 2 ) + throw bad_nasal_cast("Expected vector with two elements"); + return Vec2(vec[0], vec[1]); + } + +} // namespace nasal + +#endif /* SG_FROM_NASAL_HELPER_HXX_ */ diff --git a/simgear/nasal/cppbind/detail/nasal_traits.hxx b/simgear/nasal/cppbind/detail/nasal_traits.hxx new file mode 100644 index 00000000..2e216305 --- /dev/null +++ b/simgear/nasal/cppbind/detail/nasal_traits.hxx @@ -0,0 +1,58 @@ +///@file +/// Type traits used for converting from and to Nasal types +/// +// Copyright (C) 2012 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#ifndef SG_NASAL_TRAITS_HXX_ +#define SG_NASAL_TRAITS_HXX_ + +#include + +namespace nasal +{ + template + struct is_vec2: public boost::integral_constant {}; + +#define SG_MAKE_TRAIT(templ,type,attr)\ + template templ\ + struct attr< type >:\ + public boost::integral_constant {}; + +#ifdef SGVec2_H + SG_MAKE_TRAIT(, SGVec2, is_vec2) +#endif + +#ifdef OSG_VEC2B + SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2) +#endif + +#ifdef OSG_VEC2D + SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2) +#endif + +#ifdef OSG_VEC2F + SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2) +#endif + +#ifdef OSG_VEC2S + SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2) +#endif + +#undef SG_MAKE_TRAIT + +} // namespace nasal +#endif /* SG_NASAL_TRAITS_HXX_ */ diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.cxx b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx new file mode 100644 index 00000000..bc1f25e2 --- /dev/null +++ b/simgear/nasal/cppbind/detail/to_nasal_helper.cxx @@ -0,0 +1,63 @@ +// Conversion functions to convert C++ types to Nasal types +// +// Copyright (C) 2012 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#include "to_nasal_helper.hxx" +#include + +#include + +namespace nasal +{ + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, const std::string& str) + { + naRef ret = naNewString(c); + naStr_fromdata(ret, str.c_str(), str.size()); + return ret; + } + + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, const char* str) + { + return to_nasal_helper(c, std::string(str)); + } + + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, naCFunction func) + { + return naNewFunc(c, naNewCCode(c, func)); + } + + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, const Hash& hash) + { + return hash.get_naRef(); + } + + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, const naRef& ref) + { + return ref; + } + + //---------------------------------------------------------------------------- + naRef to_nasal_helper(naContext c, const SGPath& path) + { + return to_nasal_helper(c, path.str()); + } +} // namespace nasal diff --git a/simgear/nasal/cppbind/detail/to_nasal_helper.hxx b/simgear/nasal/cppbind/detail/to_nasal_helper.hxx new file mode 100644 index 00000000..e367e00d --- /dev/null +++ b/simgear/nasal/cppbind/detail/to_nasal_helper.hxx @@ -0,0 +1,163 @@ +///@file +/// Conversion helpers used by to_nasal(naContext, T) +/// +// Copyright (C) 2012 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#ifndef SG_TO_NASAL_HELPER_HXX_ +#define SG_TO_NASAL_HELPER_HXX_ + +#include "nasal_traits.hxx" + +#include + +#include +#include +#include + +#include +#include +#include + +class SGPath; + +namespace nasal +{ + class Hash; + + /** + * Convert std::string to Nasal string + */ + naRef to_nasal_helper(naContext c, const std::string& str); + + /** + * Convert C-string to Nasal string + */ + // We need this to prevent the array overload of to_nasal being called + naRef to_nasal_helper(naContext c, const char* str); + + /** + * Convert function pointer to Nasal function + */ + naRef to_nasal_helper(naContext c, naCFunction func); + + /** + * Convert a nasal::Hash to a Nasal hash + */ + naRef to_nasal_helper(naContext c, const Hash& hash); + + /** + * Simple pass-through of naRef types to allow generic usage of to_nasal + */ + naRef to_nasal_helper(naContext c, const naRef& ref); + + naRef to_nasal_helper(naContext c, const SGPath& path); + + /** + * Convert a numeric type to Nasal number + */ + template + typename boost::enable_if< boost::is_arithmetic, naRef >::type + to_nasal_helper(naContext c, T num) + { + return naNum(num); + } + + /** + * Convert a 2d vector to Nasal vector with 2 elements + */ + template + typename boost::enable_if, naRef>::type + to_nasal_helper(naContext c, const Vec2& vec); + + /** + * Convert a std::map to a Nasal Hash + */ + template + naRef to_nasal_helper(naContext c, const std::map& map); + + /** + * Convert a fixed size array to a Nasal vector + */ + template + naRef to_nasal_helper(naContext c, const T(&array)[N]); + + /** + * Convert std::vector to Nasal vector + */ + template< template class Vector, + class T, + class Alloc + > + typename boost::enable_if< boost::is_same< Vector, + std::vector + >, + naRef + >::type + to_nasal_helper(naContext c, const Vector& vec) + { + naRef ret = naNewVector(c); + naVec_setsize(c, ret, vec.size()); + for(size_t i = 0; i < vec.size(); ++i) + naVec_set(ret, i, to_nasal_helper(c, vec[i])); + return ret; + } + + //---------------------------------------------------------------------------- + template + typename boost::enable_if, naRef>::type + to_nasal_helper(naContext c, const Vec2& vec) + { + // We take just double because in Nasal every number is represented as + // double + double nasal_vec[2] = {vec[0], vec[1]}; + return to_nasal_helper(c, nasal_vec); + } + + //---------------------------------------------------------------------------- + template + naRef to_nasal_helper(naContext c, const std::map& map) + { + naRef hash = naNewHash(c); + + typedef typename boost::call_traits::param_type param_type; + typedef typename std::map::const_iterator map_iterator; + + for( map_iterator it = map.begin(); it != map.end(); ++it ) + naHash_set + ( + hash, + to_nasal_helper(c, it->first), + to_nasal_helper(c, static_cast(it->second)) + ); + + return hash; + } + + //---------------------------------------------------------------------------- + template + naRef to_nasal_helper(naContext c, const T(&array)[N]) + { + naRef ret = naNewVector(c); + naVec_setsize(c, ret, N); + for(size_t i = 0; i < N; ++i) + naVec_set(ret, i, to_nasal_helper(c, array[i])); + return ret; + } + +} // namespace nasal + +#endif /* SG_TO_NASAL_HELPER_HXX_ */ diff --git a/simgear/nasal/cppbind/from_nasal.cxx b/simgear/nasal/cppbind/from_nasal.cxx deleted file mode 100644 index bed08e42..00000000 --- a/simgear/nasal/cppbind/from_nasal.cxx +++ /dev/null @@ -1,84 +0,0 @@ -// Conversion functions to convert Nasal types to C++ types -// -// Copyright (C) 2012 Thomas Geymayer -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -#include "from_nasal_detail.hxx" -#include "NasalHash.hxx" -#include "NasalString.hxx" - -#include - -namespace nasal -{ - //---------------------------------------------------------------------------- - bad_nasal_cast::bad_nasal_cast() - { - - } - - //---------------------------------------------------------------------------- - bad_nasal_cast::bad_nasal_cast(const std::string& msg): - _msg( msg ) - { - - } - - //---------------------------------------------------------------------------- - bad_nasal_cast::~bad_nasal_cast() throw() - { - - } - - //---------------------------------------------------------------------------- - const char* bad_nasal_cast::what() const throw() - { - return _msg.empty() ? bad_cast::what() : _msg.c_str(); - } - - //---------------------------------------------------------------------------- - std::string from_nasal_helper(naContext c, naRef ref, const std::string*) - { - naRef na_str = naStringValue(c, ref); - return std::string(naStr_data(na_str), naStr_len(na_str)); - } - - //---------------------------------------------------------------------------- - SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*) - { - naRef na_str = naStringValue(c, ref); - return SGPath(std::string(naStr_data(na_str), naStr_len(na_str))); - } - - //---------------------------------------------------------------------------- - Hash from_nasal_helper(naContext c, naRef ref, const Hash*) - { - if( !naIsHash(ref) ) - throw bad_nasal_cast("Not a hash"); - - return Hash(ref, c); - } - - //---------------------------------------------------------------------------- - String from_nasal_helper(naContext c, naRef ref, const String*) - { - if( !naIsString(ref) ) - throw bad_nasal_cast("Not a string"); - - return String(ref); - } - -} // namespace nasal diff --git a/simgear/nasal/cppbind/from_nasal.hxx b/simgear/nasal/cppbind/from_nasal.hxx index de152135..fe672c01 100644 --- a/simgear/nasal/cppbind/from_nasal.hxx +++ b/simgear/nasal/cppbind/from_nasal.hxx @@ -20,7 +20,7 @@ #ifndef SG_FROM_NASAL_HXX_ #define SG_FROM_NASAL_HXX_ -#include "from_nasal_detail.hxx" +#include namespace nasal { diff --git a/simgear/nasal/cppbind/from_nasal_detail.hxx b/simgear/nasal/cppbind/from_nasal_detail.hxx deleted file mode 100644 index 6ff72f25..00000000 --- a/simgear/nasal/cppbind/from_nasal_detail.hxx +++ /dev/null @@ -1,148 +0,0 @@ -///@file -/// Conversion helpers used by from_nasal(naContext, naRef) -/// -// Copyright (C) 2012 Thomas Geymayer -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -#ifndef SG_FROM_NASAL_DETAIL_HXX_ -#define SG_FROM_NASAL_DETAIL_HXX_ - -#include "nasal_traits.hxx" - -#include - -#include -#include - -#include -#include // std::bad_cast -#include - -class SGPath; - -namespace nasal -{ - class Hash; - class String; - - /** - * Thrown when converting a type from/to Nasal has failed - */ - class bad_nasal_cast: - public std::bad_cast - { - public: - /** - * Construct with generic error message - */ - bad_nasal_cast(); - - /** - * Construct from an error message - * - * @param msg Error message/description - */ - explicit bad_nasal_cast(const std::string& msg); - - virtual ~bad_nasal_cast() throw(); - - /** - * Get a description of the cause of the failed cast. - */ - virtual const char* what() const throw(); - - protected: - std::string _msg; - }; - - /** - * Simple pass through for unified handling also of naRef. - */ - inline naRef from_nasal_helper(naContext, naRef ref, const naRef*) - { return ref; } - - /** - * Convert Nasal string to std::string - */ - std::string from_nasal_helper(naContext c, naRef ref, const std::string*); - - /** - * Convert a Nasal string to an SGPath - */ - SGPath from_nasal_helper(naContext c, naRef ref, const SGPath*); - - /** - * Convert a Nasal hash to a nasal::Hash - */ - Hash from_nasal_helper(naContext c, naRef ref, const Hash*); - - /** - * Convert a Nasal string to a nasal::String - */ - String from_nasal_helper(naContext c, naRef ref, const String*); - - /** - * Convert a Nasal number to a C++ numeric type - */ - template - typename boost::enable_if< boost::is_arithmetic, - T - >::type - from_nasal_helper(naContext c, naRef ref, const T*) - { - naRef num = naNumValue(ref); - if( !naIsNum(num) ) - throw bad_nasal_cast("Not a number"); - - return static_cast(num.num); - } - - /** - * Convert a Nasal vector to a std::vector - */ - template - std::vector - from_nasal_helper(naContext c, naRef ref, const std::vector*) - { - if( !naIsVector(ref) ) - throw bad_nasal_cast("Not a vector"); - - int size = naVec_size(ref); - std::vector vec(size); - - for(int i = 0; i < size; ++i) - vec[i] = from_nasal_helper(c, naVec_get(ref, i), static_cast(0)); - - return vec; - } - - /** - * Convert a Nasal vector of 2 elements to a 2d vector - */ - template - typename boost::enable_if, Vec2>::type - from_nasal_helper(naContext c, naRef ref, const Vec2*) - { - std::vector vec = - from_nasal_helper(c, ref, static_cast*>(0)); - if( vec.size() != 2 ) - throw bad_nasal_cast("Expected vector with two elements"); - return Vec2(vec[0], vec[1]); - } - -} // namespace nasal - -#endif /* SG_FROM_NASAL_DETAIL_HXX_ */ diff --git a/simgear/nasal/cppbind/nasal_traits.hxx b/simgear/nasal/cppbind/nasal_traits.hxx deleted file mode 100644 index 2e216305..00000000 --- a/simgear/nasal/cppbind/nasal_traits.hxx +++ /dev/null @@ -1,58 +0,0 @@ -///@file -/// Type traits used for converting from and to Nasal types -/// -// Copyright (C) 2012 Thomas Geymayer -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -#ifndef SG_NASAL_TRAITS_HXX_ -#define SG_NASAL_TRAITS_HXX_ - -#include - -namespace nasal -{ - template - struct is_vec2: public boost::integral_constant {}; - -#define SG_MAKE_TRAIT(templ,type,attr)\ - template templ\ - struct attr< type >:\ - public boost::integral_constant {}; - -#ifdef SGVec2_H - SG_MAKE_TRAIT(, SGVec2, is_vec2) -#endif - -#ifdef OSG_VEC2B - SG_MAKE_TRAIT(<>, osg::Vec2b, is_vec2) -#endif - -#ifdef OSG_VEC2D - SG_MAKE_TRAIT(<>, osg::Vec2d, is_vec2) -#endif - -#ifdef OSG_VEC2F - SG_MAKE_TRAIT(<>, osg::Vec2f, is_vec2) -#endif - -#ifdef OSG_VEC2S - SG_MAKE_TRAIT(<>, osg::Vec2s, is_vec2) -#endif - -#undef SG_MAKE_TRAIT - -} // namespace nasal -#endif /* SG_NASAL_TRAITS_HXX_ */ diff --git a/simgear/nasal/cppbind/to_nasal.cxx b/simgear/nasal/cppbind/to_nasal.cxx deleted file mode 100644 index b5224ad2..00000000 --- a/simgear/nasal/cppbind/to_nasal.cxx +++ /dev/null @@ -1,63 +0,0 @@ -// Conversion functions to convert C++ types to Nasal types -// -// Copyright (C) 2012 Thomas Geymayer -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - -#include "to_nasal.hxx" -#include "NasalHash.hxx" - -#include - -namespace nasal -{ - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, const std::string& str) - { - naRef ret = naNewString(c); - naStr_fromdata(ret, str.c_str(), str.size()); - return ret; - } - - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, const char* str) - { - return to_nasal(c, std::string(str)); - } - - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, naCFunction func) - { - return naNewFunc(c, naNewCCode(c, func)); - } - - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, const Hash& hash) - { - return hash.get_naRef(); - } - - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, const naRef& ref) - { - return ref; - } - - //---------------------------------------------------------------------------- - naRef to_nasal(naContext c, const SGPath& path) - { - return to_nasal(c, path.str()); - } -} // namespace nasal diff --git a/simgear/nasal/cppbind/to_nasal.hxx b/simgear/nasal/cppbind/to_nasal.hxx index eeaf5a97..8d1437d1 100644 --- a/simgear/nasal/cppbind/to_nasal.hxx +++ b/simgear/nasal/cppbind/to_nasal.hxx @@ -20,100 +20,35 @@ #ifndef SG_TO_NASAL_HXX_ #define SG_TO_NASAL_HXX_ -#include "nasal_traits.hxx" - -#include - -#include -#include -#include - -#include -#include -#include - -class SGPath; +#include namespace nasal { - class Hash; - - /** - * Convert std::string to Nasal string - */ - naRef to_nasal(naContext c, const std::string& str); - - /** - * Convert C-string to Nasal string - */ - // We need this to prevent the array overload of to_nasal being called - naRef to_nasal(naContext c, const char* str); - - /** - * Convert function pointer to Nasal function - */ - naRef to_nasal(naContext c, naCFunction func); - - /** - * Convert a nasal::Hash to a Nasal hash - */ - naRef to_nasal(naContext c, const Hash& hash); - - /** - * Simple pass-through of naRef types to allow generic usage of to_nasal - */ - naRef to_nasal(naContext c, const naRef& ref); - - naRef to_nasal(naContext c, const SGPath& path); - /** - * Convert a numeric type to Nasal number + * Convert any supported C++ type to Nasal. + * + * @param c Active Nasal context + * @param arg C++ Object to be converted + * @tparam T Type of converted object + * + * @throws bad_nasal_cast if conversion is not possible + * + * @note Every type which should be supported needs a function with the + * following signature declared (Type needs to be a const reference + * for non-integral types): + * + * naRef to_nasal_helper(naContext, Type) */ template - typename boost::enable_if< boost::is_arithmetic, naRef >::type - to_nasal(naContext c, T num) + naRef to_nasal(naContext c, T arg) { - return naNum(num); + return to_nasal_helper(c, arg); } - /** - * Convert a 2d vector to Nasal vector with 2 elements - */ - template - typename boost::enable_if, naRef>::type - to_nasal(naContext c, const Vec2& vec); - - /** - * Convert a std::map to a Nasal Hash - */ - template - naRef to_nasal(naContext c, const std::map& map); - - /** - * Convert a fixed size array to a Nasal vector - */ template - naRef to_nasal(naContext c, const T(&array)[N]); - - /** - * Convert std::vector to Nasal vector - */ - template< template class Vector, - class T, - class Alloc - > - typename boost::enable_if< boost::is_same< Vector, - std::vector - >, - naRef - >::type - to_nasal(naContext c, const Vector& vec) + naRef to_nasal(naContext c, const T(&array)[N]) { - naRef ret = naNewVector(c); - naVec_setsize(c, ret, vec.size()); - for(size_t i = 0; i < vec.size(); ++i) - naVec_set(ret, i, to_nasal(c, vec[i])); - return ret; + return to_nasal_helper(c, array); } /** @@ -128,52 +63,9 @@ namespace nasal static type get() { - return static_cast(&to_nasal); + return &to_nasal; } }; - - //---------------------------------------------------------------------------- - template - typename boost::enable_if, naRef>::type - to_nasal(naContext c, const Vec2& vec) - { - // We take just double because in Nasal every number is represented as - // double - double nasal_vec[2] = {vec[0], vec[1]}; - return to_nasal(c, nasal_vec); - } - - //---------------------------------------------------------------------------- - template - naRef to_nasal(naContext c, const std::map& map) - { - naRef hash = naNewHash(c); - - typedef typename boost::call_traits::param_type param_type; - typedef typename std::map::const_iterator map_iterator; - - for( map_iterator it = map.begin(); it != map.end(); ++it ) - naHash_set - ( - hash, - to_nasal(c, it->first), - to_nasal(c, static_cast(it->second)) - ); - - return hash; - } - - //---------------------------------------------------------------------------- - template - naRef to_nasal(naContext c, const T(&array)[N]) - { - naRef ret = naNewVector(c); - naVec_setsize(c, ret, N); - for(size_t i = 0; i < N; ++i) - naVec_set(ret, i, to_nasal(c, array[i])); - return ret; - } - } // namespace nasal #endif /* SG_TO_NASAL_HXX_ */