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.
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -50,18 +50,21 @@ struct DoubleDerived:
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<Base> BasePtr;
|
||||
|
||||
struct DoubleDerived2:
|
||||
public Derived
|
||||
{
|
||||
|
||||
const BasePtr& getBase() const{return _base;}
|
||||
BasePtr _base;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<Base> BasePtr;
|
||||
typedef boost::shared_ptr<Derived> DerivedPtr;
|
||||
typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
|
||||
typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
|
||||
|
||||
naRef to_nasal(naContext c, const BasePtr& base)
|
||||
naRef to_nasal_helper(naContext c, const BasePtr& base)
|
||||
{
|
||||
return nasal::Ghost<BasePtr>::create(c, base);
|
||||
}
|
||||
@@ -159,7 +162,8 @@ int main(int argc, char* argv[])
|
||||
Ghost<DoubleDerivedPtr>::init("DoubleDerivedPtr")
|
||||
.bases<DerivedPtr>();
|
||||
Ghost<DoubleDerived2Ptr>::init("DoubleDerived2Ptr")
|
||||
.bases< Ghost<DerivedPtr> >();
|
||||
.bases< Ghost<DerivedPtr> >()
|
||||
.member("base", &DoubleDerived2::getBase);
|
||||
|
||||
BasePtr d( new Derived );
|
||||
naRef derived = Ghost<BasePtr>::create(c, d);
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
// 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 "from_nasal_helper.hxx"
|
||||
#include <simgear/nasal/cppbind/NasalHash.hxx>
|
||||
#include <simgear/nasal/cppbind/NasalString.hxx>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
// 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_
|
||||
#ifndef SG_FROM_NASAL_HELPER_HXX_
|
||||
#define SG_FROM_NASAL_HELPER_HXX_
|
||||
|
||||
#include "nasal_traits.hxx"
|
||||
|
||||
@@ -145,4 +145,4 @@ namespace nasal
|
||||
|
||||
} // namespace nasal
|
||||
|
||||
#endif /* SG_FROM_NASAL_DETAIL_HXX_ */
|
||||
#endif /* SG_FROM_NASAL_HELPER_HXX_ */
|
||||
@@ -16,15 +16,15 @@
|
||||
// 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 "to_nasal_helper.hxx"
|
||||
#include <simgear/nasal/cppbind/NasalHash.hxx>
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, const std::string& str)
|
||||
naRef to_nasal_helper(naContext c, const std::string& str)
|
||||
{
|
||||
naRef ret = naNewString(c);
|
||||
naStr_fromdata(ret, str.c_str(), str.size());
|
||||
@@ -32,32 +32,32 @@ namespace nasal
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, const char* str)
|
||||
naRef to_nasal_helper(naContext c, const char* str)
|
||||
{
|
||||
return to_nasal(c, std::string(str));
|
||||
return to_nasal_helper(c, std::string(str));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, naCFunction func)
|
||||
naRef to_nasal_helper(naContext c, naCFunction func)
|
||||
{
|
||||
return naNewFunc(c, naNewCCode(c, func));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, const Hash& hash)
|
||||
naRef to_nasal_helper(naContext c, const Hash& hash)
|
||||
{
|
||||
return hash.get_naRef();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, const naRef& ref)
|
||||
naRef to_nasal_helper(naContext c, const naRef& ref)
|
||||
{
|
||||
return ref;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
naRef to_nasal(naContext c, const SGPath& path)
|
||||
naRef to_nasal_helper(naContext c, const SGPath& path)
|
||||
{
|
||||
return to_nasal(c, path.str());
|
||||
return to_nasal_helper(c, path.str());
|
||||
}
|
||||
} // namespace nasal
|
||||
163
simgear/nasal/cppbind/detail/to_nasal_helper.hxx
Normal file
163
simgear/nasal/cppbind/detail/to_nasal_helper.hxx
Normal file
@@ -0,0 +1,163 @@
|
||||
///@file
|
||||
/// Conversion helpers used by to_nasal<T>(naContext, T)
|
||||
///
|
||||
// Copyright (C) 2012 Thomas Geymayer <tomgey@gmail.com>
|
||||
//
|
||||
// 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 <simgear/nasal/nasal.h>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<class T>
|
||||
typename boost::enable_if< boost::is_arithmetic<T>, naRef >::type
|
||||
to_nasal_helper(naContext c, T num)
|
||||
{
|
||||
return naNum(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 2d vector to Nasal vector with 2 elements
|
||||
*/
|
||||
template<class Vec2>
|
||||
typename boost::enable_if<is_vec2<Vec2>, naRef>::type
|
||||
to_nasal_helper(naContext c, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Convert a std::map to a Nasal Hash
|
||||
*/
|
||||
template<class Value>
|
||||
naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map);
|
||||
|
||||
/**
|
||||
* Convert a fixed size array to a Nasal vector
|
||||
*/
|
||||
template<class T, size_t N>
|
||||
naRef to_nasal_helper(naContext c, const T(&array)[N]);
|
||||
|
||||
/**
|
||||
* Convert std::vector to Nasal vector
|
||||
*/
|
||||
template< template<class T, class Alloc> class Vector,
|
||||
class T,
|
||||
class Alloc
|
||||
>
|
||||
typename boost::enable_if< boost::is_same< Vector<T,Alloc>,
|
||||
std::vector<T,Alloc>
|
||||
>,
|
||||
naRef
|
||||
>::type
|
||||
to_nasal_helper(naContext c, const Vector<T, Alloc>& 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<class Vec2>
|
||||
typename boost::enable_if<is_vec2<Vec2>, 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<class Value>
|
||||
naRef to_nasal_helper(naContext c, const std::map<std::string, Value>& map)
|
||||
{
|
||||
naRef hash = naNewHash(c);
|
||||
|
||||
typedef typename boost::call_traits<Value>::param_type param_type;
|
||||
typedef typename std::map<std::string, Value>::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<param_type>(it->second))
|
||||
);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T, size_t N>
|
||||
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_ */
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef SG_FROM_NASAL_HXX_
|
||||
#define SG_FROM_NASAL_HXX_
|
||||
|
||||
#include "from_nasal_detail.hxx"
|
||||
#include <simgear/nasal/cppbind/detail/from_nasal_helper.hxx>
|
||||
|
||||
namespace nasal
|
||||
{
|
||||
|
||||
@@ -20,100 +20,35 @@
|
||||
#ifndef SG_TO_NASAL_HXX_
|
||||
#define SG_TO_NASAL_HXX_
|
||||
|
||||
#include "nasal_traits.hxx"
|
||||
|
||||
#include <simgear/nasal/nasal.h>
|
||||
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class SGPath;
|
||||
#include <simgear/nasal/cppbind/detail/to_nasal_helper.hxx>
|
||||
|
||||
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<class T>
|
||||
typename boost::enable_if< boost::is_arithmetic<T>, 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<class Vec2>
|
||||
typename boost::enable_if<is_vec2<Vec2>, naRef>::type
|
||||
to_nasal(naContext c, const Vec2& vec);
|
||||
|
||||
/**
|
||||
* Convert a std::map to a Nasal Hash
|
||||
*/
|
||||
template<class Value>
|
||||
naRef to_nasal(naContext c, const std::map<std::string, Value>& map);
|
||||
|
||||
/**
|
||||
* Convert a fixed size array to a Nasal vector
|
||||
*/
|
||||
template<class T, size_t N>
|
||||
naRef to_nasal(naContext c, const T(&array)[N]);
|
||||
|
||||
/**
|
||||
* Convert std::vector to Nasal vector
|
||||
*/
|
||||
template< template<class T, class Alloc> class Vector,
|
||||
class T,
|
||||
class Alloc
|
||||
>
|
||||
typename boost::enable_if< boost::is_same< Vector<T,Alloc>,
|
||||
std::vector<T,Alloc>
|
||||
>,
|
||||
naRef
|
||||
>::type
|
||||
to_nasal(naContext c, const Vector<T, Alloc>& 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<type>(&to_nasal);
|
||||
return &to_nasal<param_type>;
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class Vec2>
|
||||
typename boost::enable_if<is_vec2<Vec2>, 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<class Value>
|
||||
naRef to_nasal(naContext c, const std::map<std::string, Value>& map)
|
||||
{
|
||||
naRef hash = naNewHash(c);
|
||||
|
||||
typedef typename boost::call_traits<Value>::param_type param_type;
|
||||
typedef typename std::map<std::string, Value>::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<param_type>(it->second))
|
||||
);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template<class T, size_t N>
|
||||
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_ */
|
||||
|
||||
Reference in New Issue
Block a user