mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
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:
parent
c145759da8
commit
359848f371
118
main.cpp
Normal file
118
main.cpp
Normal 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" );
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user