可能是還在開發當中的緣故, 我感覺Nebula3中的lua指令碼系統不是很完善. 所有的調用都是封裝成Command來執行的, 並不像LuaBind那樣直接綁定到C++類對象; 而且, 對於C++呼叫指令碼的介面也不是很方便, 只有一個Eval()來執行一個字串. 如果要實際進行應用的話, 我想最好是自己擴充一下, 這裡有一篇不錯的文章: Integrating Lua into C++. 當然, 對於需求更高的使用者來說, 可以選擇使用LuaBind等第三方庫來整合指令碼系統.
Command(命令)
可以這麼說, 指令碼中調用的, 都是一個個的Command. 一個新的Command定義了一個指令碼語言獨立的新的指令碼命令, 你可以通過派生一個Command的子類並註冊到指令碼伺服器來實現. 也就是說, 新的命令不依賴於你具體使用的指令碼系統, 可以是lua, 也可以是python等等.
class Print : public Scripting::Command{ DeclareClass(Print);public: virtual void OnRegister(); virtual bool OnExecute(); virtual Util::String GetHelp() const;private: void Callback(const Util::String& str);};ScriptServer(指令碼伺服器)
ScriptServer是語言無雙的, 也就是說你可以自己派生一個相應語言的子來來支援一種指令碼言. Nebula3裡已經實現了一個LuaServer, 不過個感覺沒有LuaBind方便. 所有的指令碼執行都是通過LuaServer::Eval(const String& str)來完成的. 指令碼要調用C++代碼的話, 需要封裝一個Command, 然後用LuaServer::RegisterCommand()來註冊就可以用了. 具體可以參考Command命名空間裡的相關代碼.
scriptServer->RegisterCommand("print", Print::Create());應用執行個體
其實App::ConsoleApplication裡就有LuaServer, 並且已經註冊了一些IO命名. 我們派生一個從命令列讀取指令碼命令執行的來做測試:
class ScripTestApp : public App::ConsoleApplication<br />{<br />public:<br /> ScripTestApp(void);</p><p> /// open the application<br /> virtual bool Open();<br /> /// run the application, return when user wants to exit<br /> virtual void Run();<br />};</p><p> ScripTestApp::ScripTestApp(void)<br />{<br />}</p><p>bool ScripTestApp::Open()<br />{<br /> if (ConsoleApplication::Open())<br /> {<br /> return true;<br /> }<br /> return false;<br />}</p><p>void ScripTestApp::Run()<br />{<br /> Util::String input;<br /> while (true)<br /> {<br /> input = IO::Console::Instance()->GetInput();<br /> if (!input.IsEmpty())<br /> {<br /> this->scriptServer->Eval(input);<br /> }<br /> }<br />}
運行結果: