// The MIT License (MIT) // Copyright (c) 2013 Danny Y., Rapptz // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of // the Software, and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef SOL_LUA_FUNC_HPP #define SOL_LUA_FUNC_HPP #include "functional.hpp" #include "stack.hpp" namespace sol { namespace detail { struct lua_func { virtual int operator () ( lua_State* L ) { throw sol_error( "Failure to call specialized wrapped C++ function from lua" ); } virtual ~lua_func( ) {}; }; template struct lambda_lua_func : public lua_func { typedef decltype( &TFx::operator() ) fx_t; typedef function_traits fx_traits; TFx fx; template lambda_lua_func( TFxn&&... fxn ) : fx( std::forward( fxn )... ) { } virtual int operator () ( lua_State* L ) override { return ( *this )( tuple_types( ), fx_traits::args_t( ), L ); } template int operator()( types, types t, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); return 0; } template int operator()( types, types t, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); stack::push( L, r ); return sizeof...( TRn ); } }; template ::value> struct explicit_lua_func : public lua_func { typedef typename std::remove_pointer::type>::type fx_t; typedef function_traits fx_traits; TFx fx; template explicit_lua_func( TFxn&&... fxn ) : fx( std::forward( fxn )... ) { } virtual int operator () ( lua_State* L ) override { return ( *this )( tuple_types( ), fx_traits::args_t( ), L ); } template int operator () ( types, types t, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); return 0; } template int operator () ( types, types t, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); stack::push( L, r ); return sizeof...( TRn ); } }; template struct explicit_lua_func : public lua_func { typedef typename std::remove_pointer::type>::type fx_t; typedef function_traits fx_traits; T* member; TFx fx; template explicit_lua_func( T* m, TFxn&&... fxn ) : member(m), fx( std::forward( fxn )... ) { } virtual int operator () ( lua_State* L ) override { return ( *this )( tuple_types( ), fx_traits::args_t( ), L ); } template int operator () ( types, types, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); return 0; } template int operator () ( types, types t, lua_State* L ) { auto r = stack::pop_call( L, fx, t ); stack::push( L, r ); return sizeof...( TRn ); } }; int lua_cfun( lua_State* L ) { void* bridgedata = lua_touserdata( L, lua_upvalueindex( 1 ) ); auto* fx = static_cast( bridgedata ); int r = fx->operator()( L ); return r; } } // detail } // sol #endif // SOL_LUA_FUNC_HPP