/* @file tools/sdk/cpp/LuaConsole.hpp @author Luke Tokheim, luke@motionnode.com @version 1.1 (C) Copyright GLI Interactive LLC 2008. All rights reserved. The coded instructions, statements, computer programs, and/or related material (collectively the "Data") in these files contain unpublished information proprietary to GLI Interactive LLC, which is protected by US federal copyright law and by international treaties. The Data may not be disclosed or distributed to third parties, in whole or in part, without the prior written consent of GLI Interactive LLC. The Data is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose. */ #ifndef __MOTION_NODE_SDK_LUA_CONSOLE_HPP_ #define __MOTION_NODE_SDK_LUA_CONSOLE_HPP_ #include #include #include namespace MotionNode { namespace SDK { /** The LuaConsole class sends a Lua chunk to the MotionNode Console service,parses the result code, and returns the printed output. Requires anexisting Client connection to the MotionNode Console service. Example usage: @code try { using MotionNode::SDK::Client; using MotionNode::SDK::Console; // Send this chunk. Print something out. std::string chunk = "print('Hello World')"; // Connect to the MotionNode Console service. Client client("", 32075); LuaConsole::result_type result = LuaConsole::SendChunk(client, chunk); if (LuaConsole::Success == result.first) { // This should be "Hello World\n" std::cout << result.second; } else if (LuaConsole::Continue == result.first) { std::cerr << "incomplete Lua chunk: " << result.second << std::endl; } else { std::cerr << "command failed: " << result.second << std::endl; } } catch (std::runtime_error & e) { // The Client and LuaConsole class with throw std::runtime_error // for any unrecoverable conditions. } @endcode */ class LuaConsole { public: enum ResultCode { // The Lua chunk was successfully parsed and executed. The // printed results are in the result string. Success = 0, // The Lua chunk failed due to a compile time or execution // time error. An error description is in the result string. Failure = 1, // The Lua chunk was incomplete. The Console service is waiting // for a complete chunk before it executes. // For example, "if x > 1 then" is incomplete since it requires // and "end" token to close the "if" control statement. Continue = 2 }; typedef std::pair result_type; /** Write a general Lua chunk to the open Console service socket and read back the results. */ template static result_type SendChunk( ClientT & client, const std::string & chunk, const int & time_out_second=-1) { result_type result(Failure, std::string()); typename ClientT::data_type data(chunk.size()); std::copy( chunk.begin(), chunk.end(), data.begin()); if (client.writeData(data, time_out_second) && client.readData(data, time_out_second) && !data.empty()) { // First character is the response code. char code = data[0]; if ((code >= Success) && (code <= Continue)) { result.first = static_cast(code); // The rest of the message is any printed output from the // Lua environment. if (data.size() > 1) { result.second.resize(data.size() - 1); std::copy( data.begin() + 1, data.end(), result.second.begin()); } } else { throw std::runtime_error("unknown return code from Console service"); } } return result; } private: /** Hide the constructor. There is no need to instantiate the LuaConsole object. */ LuaConsole(); }; // class LuaConsole }} // namespace MotionNode::SDK #endif // __MOTION_NODE_SDK_LUA_CONSOLE_HPP_