Some basic C++/Nasal binding helpers

- Add nasal::to_nasal for converting different C++ types
   to the according Nasal types.
 - Add nasal::Hash, an OOP wrapper around Nasal hashes.
This commit is contained in:
Thomas Geymayer
2012-11-09 19:28:27 +01:00
parent 4efcda534d
commit 54778ee1e1
7 changed files with 365 additions and 0 deletions

View File

@@ -11,6 +11,7 @@ foreach( mylibfolder
math
misc
nasal
nasal/cppbind
props
serial
structure

View File

@@ -0,0 +1,19 @@
include (SimGearComponent)
set(HEADERS
NasalHash.hxx
to_nasal.hxx
)
set(SOURCES
NasalHash.cxx
to_nasal.cxx
)
simgear_component(nasal/cppbind nasal/cppbind "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
add_executable(test_cppbind cppbind_test.cxx)
add_test(test_cppbind ${EXECUTABLE_OUTPUT_PATH}/test_cppbind)
target_link_libraries(test_cppbind SimGearCore)
endif(ENABLE_TESTS)

View File

@@ -0,0 +1,69 @@
// Wrapper class for Nasal hashes
//
// 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
#include "NasalHash.hxx"
#include "to_nasal.hxx"
#include <cassert>
namespace nasal
{
//----------------------------------------------------------------------------
Hash::Hash(naContext c):
_hash( naNewHash(c) ),
_context(c)
{
}
//----------------------------------------------------------------------------
Hash::Hash(const naRef& hash, naContext c):
_hash(hash),
_context(c)
{
assert( naIsHash(_hash) );
}
//----------------------------------------------------------------------------
void Hash::set(const std::string& name, naRef ref)
{
naHash_set(_hash, to_nasal(_context, name), ref);
}
//----------------------------------------------------------------------------
Hash Hash::createHash(const std::string& name)
{
Hash hash(_context);
set(name, hash);
return hash;
}
//----------------------------------------------------------------------------
void Hash::setContext(naContext context)
{
_context = context;
}
//----------------------------------------------------------------------------
const naRef Hash::get_naRef() const
{
return _hash;
}
} // namespace nasal

View File

@@ -0,0 +1,97 @@
// Wrapper class for Nasal hashes
//
// 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_NASAL_HASH_HXX_
#define SG_NASAL_HASH_HXX_
#include "to_nasal.hxx"
namespace nasal
{
/**
* A Nasal Hash
*/
class Hash
{
public:
/**
* Create a new Nasal Hash
*
* @param c Nasal context for creating the hash
*/
Hash(naContext c);
/**
* Initialize from an existing Nasal Hash
*
* @param hash Existing Nasal Hash
* @param c Nasal context for creating new Nasal objects
*/
Hash(const naRef& hash, naContext c);
/**
* Set member
*
* @param name Member name
* @param ref Reference to Nasal object (naRef)
*/
void set(const std::string& name, naRef ref);
/**
* Set member to anything convertible using to_nasal
*
* @param name Member name
* @param val Value (has to be convertible with to_nasal)
*/
template<class T>
void set(const std::string& name, const T& val)
{
set(name, to_nasal(_context, val));
}
/**
* Create a new child hash (module)
*
* @param name Name of the new hash inside this hash
*/
Hash createHash(const std::string& name);
/**
* Set a new Nasal context. Eg. in FlightGear the context changes every
* frame, so if using the same Hash instance for multiple frames you have
* to update the context before using the Hash object.
*/
void setContext(naContext context);
/**
* Get Nasal representation of Hash
*/
const naRef get_naRef() const;
protected:
naRef _hash;
naContext _context;
};
} // namespace nasal
#endif /* SG_NASAL_HASH_HXX_ */

View File

@@ -0,0 +1,50 @@
#include "NasalHash.hxx"
#include <cstring>
#include <iostream>
#define VERIFY(a) \
if( !(a) ) \
{ \
std::cerr << "failed:" << #a << std::endl; \
return 1; \
}
int main(int argc, char* argv[])
{
naContext c = naNewContext();
naRef r;
using namespace nasal;
r = to_nasal(c, "Test");
VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
r = to_nasal(c, std::string("Test"));
VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
r = to_nasal(c, 42);
VERIFY( naNumValue(r).num == 42 );
r = to_nasal(c, 4.2);
VERIFY( naNumValue(r).num == 4.2 );
std::vector<int> vec;
r = to_nasal(c, vec);
Hash hash(c);
hash.set("vec", r);
hash.set("vec2", vec);
hash.set("name", "my-name");
hash.set("string", std::string("blub"));
r = to_nasal(c, hash);
VERIFY( naIsHash(r) );
Hash mod = hash.createHash("mod");
mod.set("parent", hash);
naFreeContext(c);
return 0;
}

View File

@@ -0,0 +1,50 @@
// Conversion functions to convert C++ types to Nasal types
//
// 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
#include "to_nasal.hxx"
#include "NasalHash.hxx"
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, 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, naRef ref)
{
return ref;
}
} // namespace nasal

View File

@@ -0,0 +1,79 @@
// Conversion functions to convert C++ types to Nasal types
//
// 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_HXX_
#define SG_TO_NASAL_HXX_
#include <simgear/nasal/nasal.h>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_arithmetic.hpp>
#include <string>
#include <vector>
namespace nasal
{
class Hash;
/**
* Convert std::string to Nasal string
*/
naRef to_nasal(naContext c, const std::string& 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, naRef ref);
/**
* Convert a numeric type to Nasal number
*/
template<class T>
typename boost::enable_if< boost::is_arithmetic<T>, naRef >::type
to_nasal(naContext c, T num)
{
return naNum(num);
}
/**
* Convert std::vector to Nasal vector
*/
template<class T>
naRef to_nasal(naContext c, const std::vector<T>& 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(c, vec[i]));
return ret;
}
} // namespace nasal
#endif /* SG_TO_NASAL_HXX_ */