Demangler is alive, it seems. But honestly, MSVC is kind of crappy about it: perhaps, later, we'll just take a string indicating the name of the class.

main.cpp contains the test implementation for the lua classes -- woo!
This commit is contained in:
ThePhD 2014-04-25 09:25:08 -04:00 committed by Rapptz
parent c145759da8
commit 359848f371
2 changed files with 135 additions and 4 deletions

118
main.cpp Normal file
View File

@ -0,0 +1,118 @@
#include <sol.hpp>
#include <sol/demangle.hpp>
namespace sol {
template <typename... Tn>
struct constructors;
template <typename T>
class lua_class {
public:
static const std::string classname;
static const std::string meta;
private:
std::string luaname;
std::vector<std::string> functionnames;
std::vector<class_lua_func> functions;
std::vector<luaL_Reg> functiontable;
std::vector<luaL_Reg> metatable;
struct maker {
static int construct( lua_State* L ) {
// First argument is now a table that represent the class to instantiate
luaL_checktype( L, 1, LUA_TTABLE );
lua_newtable( L ); // Create table to represent instance
// Set first argument of new to metatable of instance
lua_pushvalue( L, 1 );
lua_setmetatable( L, -2 );
// Do function lookups in metatable
lua_pushvalue( L, 1 );
lua_setfield( L, 1, "__index" );
void* userdata = lua_newuserdata( L, sizeof( T ) );
T* obj = static_cast<T*>( userdata );
std::allocator<T> alloc{ };
alloc.construct( obj );
}
template <std::size_t n>
static int destruct( lua_State* L ) {
void* userdata = lua_touserdata( L, 0 );
T* obj = static_cast<T*>( userdata );
std::allocator<T> alloc{ };
alloc.destroy( obj );
}
};
void build_function_tables( ) {
}
template <typename... Args, typename Ret, typename... MArgs>
void build_function_tables( Ret( T::* func )( MArgs... ), std::string name, Args&&... args ) {
functionnames.push_back( std::move( name ) );
functions.emplace_back( std::move( func ) );
functiontable.push_back( { functionnames.back().c_str(), &lua_func::call } );
build_function_tables( std::forward<Args>( args )... );
}
public:
template <typename... Args>
lua_class( Args&&... args ) : lua_class( classname, std::forward<Args>( args )... ) {
}
template <typename... Args>
lua_class( std::string name, Args&&... args ) : lua_class( name, constructors<>(), std::forward<Args>( args )... ) {
}
template <typename... Args, typename... CArgs>
lua_class( std::string name, constructors<CArgs...> c, Args&&... args ) : luaname( std::move( name ) ) {
functionnames.reserve( sizeof...( args ) );
functiontable.reserve( sizeof...( args ) );
metatable.reserve( sizeof...( args ) );
build_function_tables( std::forward<Args>( args )... );
functiontable.
}
};
template <typename T>
const std::string lua_class<T>::classname = detail::demangle( typeid( T ) );
template <typename T>
const std::string lua_class<T>::meta = std::string( "sol.stateful." ).append( classname );
}
struct f {
int x;
f( ) : x( 1 ) {
}
f( int x ) : x( x ) {
}
int add( int y ) {
return x + y;
}
};
#include <iostream>
int main( ) {
sol::state s;
f x( 20 );
sol::lua_class<f> lc{ };
std::cout << lc.classname << std::endl;
std::cout << lc.meta << std::endl;
s.set_function( "add", &f::add, f(10) );
s.script( "t = add(20)" );
std::cout << s.get<int>( "t" );
}

View File

@ -25,19 +25,32 @@
#include <string>
#ifdef _MSC_VER
#include <windows.h>
/*#include <windows.h>
#include <DbgHelp.h>
*/
namespace sol {
namespace detail {
std::string demangle(const std::type_info& id) {
std::string realname(2048, '\0');
DWORD result = UnDecorateSymbolName(id.raw_name(), realname.data(), realname.size(), UNDNAME_32_BIT_DECODE);
/*std::string realname(2048, '\0');
DWORD result = UnDecorateSymbolName(id.raw_name(), &realname[0],
static_cast<DWORD>(realname.size()), UNDNAME_NAME_ONLY | UNDNAME_32_BIT_DECODE);
if (result == 0)
return "";
realname.resize(result);
*/
const static std::string removals[ 2 ] = {
"struct ",
"class "
};
std::string realname = id.name( );
for ( std::size_t r = 0; r < 2; ++r ) {
auto found = realname.find( removals[ r ] );
if ( found == std::string::npos )
continue;
realname.erase( found, removals[r].size() );
}
return realname;
}