Cpp 方便的 Lua 包装类 |
|
以下示例展示了如何将 Lua 脚本嵌入到一个类中。更多详情请访问 Yag2002 小组网站:http://yag2002.sourceforge.net
玩得开心。
--boto
print( "in Lua: starting script" ) print( "in Lua: calling exposed exposedMethods ..." ) -- exposed method1: [ std::string, float ] exposedMethod1(int, float) a, b = testScript.exposedMethod1(42, 0.42) print("in Lua:", a, b) -- exposed method2: void exposedMethod2( int, std::string) testScript.exposedMethod2( 65, "Hello" ) print("in Lua: exposed exposedMethods have been called") -- callable script function ( from entity ) function scriptFcn1(x) print("in Lua: scriptFcn1 has been called with argument: ", x) end function scriptFcn2(x, y) print("in Lua: scriptFcn2 has been called with arguments: ", x, ", ", y) return "result: ", x * 2, y *2 end
#include "vrc_script.h" //! Class for embedding a test script class EnTestScript : public vrc::BaseScript< EnTestScript > { public: EnTestScript( const std::string& scriptfile ); virtual ~EnTestScript(); //! Start loading and executing the test script void start(); //! test for an exposed method void exposedMethod1( const Params& arguments, Params& returnvalues ); //! test for an exposed method void exposedMethod2( const Params& arguments, Params& returnvalues ); protected: //! Script file std::string _scriptFile; }; EnTestScript::EnTestScript( const std::string& scriptfile ) _scriptFile( scriptfile ) { } EnTestScript::~EnTestScript() { } void EnTestScript::start() { try { // load script file and scope all exposed methods with 'testScript' loadScript( "testScript", _scriptFile ); // expose methods Params arguments; Params returnsvalues; //Note: for adding a parameter type into a Params container one can define an initial value ( which is normally ignored ). // it is important that the compiler can deduce the 'add' method by knowing the type which is added. // currently int, float, double, and std::string types are supported. // take also care on the order you define the arguments or return values. // expose method 1 having the pseudo-signatur: [ std::string, float ] method1( int, float ) { arguments.add( 0 ); // here just pass an int variable or a constant int, we take 0 arguments.add( 0.0f ); // here just pass a float variable or a constant float, we take 0.0f returnsvalues.add( std::string() ); returnsvalues.add( 0.0f ); exposeMethod( "exposedMethod1", &EnTestScript::exposedMethod1, arguments, returnsvalues ); } // some tests { size_t argumentcontainersize = arguments.size(); assert( argumentcontainersize == 2 ); size_t returnsvaluescontainersize = returnsvalues.size(); assert( returnsvaluescontainersize == 2 ); const type_info& typeofelementatindexZero = arguments.getTypeInfo( 0 ); assert( typeofelementatindexZero == typeid( int ) ); const type_info& typeofelementatindexOne = arguments.getTypeInfo( 1 ); assert( typeofelementatindexOne == typeid( float ) ); } arguments.clear(); returnsvalues.clear(); // expose method 2 having the pseudo-signatur: void method1( int, std::string ) { arguments.add( 0 ); arguments.add( std::string() ); exposeMethod( "exposedMethod2", &EnTestScript::exposedMethod2, arguments ); } // execute the script after exposing methods execute(); // call script function scriptFcn1: void scriptFcn1( int ) { Params args; args.add( 100.42 ); // the function has no return value callScriptFunction( "scriptFcn1", &args ); } // call script function scriptFcn2: [ std::string, int, int ] scriptFcn2( int, int ) { Params args; args.add( 100 ); args.add( 150 ); Params rets; rets.add( std::string() ); rets.add( 0 ); rets.add( 0 ); callScriptFunction( "scriptFcn2", &args, &rets ); std::stringstream msg; msg << "in Entity: scriptFcn2 returned: " << GET_SCRIPT_PARAMVALUE( rets, 0, std::string ) << " " << GET_SCRIPT_PARAMVALUE( rets, 1, int ) << " " << GET_SCRIPT_PARAMVALUE( rets, 2, int ); log_debug << msg.str() << std::endl; } // close the script and clean up its resources closeScript(); } catch( const ScriptingException& e ) { log_error << "TestScript: error occured during script test: " << e.what() << std::endl; } } void EnTestScript::exposedMethod1( const Params& arguments, Params& returnvalues ) { // get parameters std::stringstream msg; msg << "in Entity: exposedMethod1( " << GET_SCRIPT_PARAMVALUE( arguments, 0, int ) << " " << GET_SCRIPT_PARAMVALUE( arguments, 1, float ) << " )"; log_debug << msg.str() << std::endl; // set return values SET_SCRIPT_PARAMVALUE( returnvalues, 0, std::string, "returnvalue is: " ); SET_SCRIPT_PARAMVALUE( returnvalues, 1, float, 0.12345f ); } void EnTestScript::exposedMethod2( const Params& arguments, Params& returnvalues ) { std::stringstream msg; msg << "in Entity: exposedMethod2( " << GET_SCRIPT_PARAMVALUE( arguments, 0, int ) << ", " << GET_SCRIPT_PARAMVALUE( arguments, 1, std::string ) << " )"; log_debug << msg.str() << std::endl; } int main( int argc, char** argv ) { EnTestScript ts( "<path>/script.lua" ); ts.start(); return 0; }
in Lua: starting script in Lua: calling exposed exposedMethods ... in Entity: exposedMethod1( 42 0.42 ) in Lua: returnvalue is: 0.12345000356436 in Entity: exposedMethod2( 65, Hello ) in Lua: exposed exposedMethods have been called in Lua: scriptFcn1 has been called with argument: 100.42 in Lua: scriptFcn2 has been called with arguments: 100 , 150 in Entity: scriptFcn2 returned: result: 200 300