diff options
author | Remko Tronçon <git@el-tramo.be> | 2013-09-20 20:32:57 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2013-09-21 06:41:34 (GMT) |
commit | 33f9dc5337f1a59932b7ac117b0dea56e1dafe1a (patch) | |
tree | 8aeae2309c1a1770313bca0797cb92f8bcee4721 /Sluift/ElementConvertors | |
parent | 577c0c8fd30ffc0df718a8958eb7b8784ec3b0ac (diff) | |
download | swift-33f9dc5337f1a59932b7ac117b0dea56e1dafe1a.zip swift-33f9dc5337f1a59932b7ac117b0dea56e1dafe1a.tar.bz2 |
Sluift: Add support for ad-hoc commands
Change-Id: I4ac2d0b07841b03086d9dbd9fa06d1f030f4e1ca
Diffstat (limited to 'Sluift/ElementConvertors')
-rw-r--r-- | Sluift/ElementConvertors/CommandConvertor.cpp | 195 | ||||
-rw-r--r-- | Sluift/ElementConvertors/CommandConvertor.h | 28 |
2 files changed, 223 insertions, 0 deletions
diff --git a/Sluift/ElementConvertors/CommandConvertor.cpp b/Sluift/ElementConvertors/CommandConvertor.cpp new file mode 100644 index 0000000..7fb7b22 --- /dev/null +++ b/Sluift/ElementConvertors/CommandConvertor.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include <Sluift/ElementConvertors/CommandConvertor.h> + +#include <lua.hpp> +#include <boost/smart_ptr/make_shared.hpp> +#include <boost/numeric/conversion/cast.hpp> + +#include <Swiften/Base/foreach.h> +#include <Sluift/Lua/Check.h> +#include <Sluift/Lua/Value.h> +#include <Sluift/LuaElementConvertors.h> + +using namespace Swift; + +static Command::Action convertActionFromString(const std::string& action) { + if (action == "cancel") { return Command::Cancel; } + else if (action == "execute") { return Command::Execute; } + else if (action == "complete") { return Command::Complete; } + else if (action == "prev") { return Command::Prev; } + else if (action == "next") { return Command::Next; } + return Command::NoAction; +} + +static std::string convertActionToString(Command::Action action) { + switch (action) { + case Command::Cancel: return "cancel"; + case Command::Execute: return "execute"; + case Command::Complete: return "complete"; + case Command::Prev: return "prev"; + case Command::Next: return "next"; + case Command::NoAction: assert(false); return ""; + } + assert(false); + return ""; +} + +CommandConvertor::CommandConvertor(LuaElementConvertors* convertors) : + GenericLuaElementConvertor<Command>("command"), + convertors(convertors) { +} + +CommandConvertor::~CommandConvertor() { +} + +boost::shared_ptr<Command> CommandConvertor::doConvertFromLua(lua_State* L) { + boost::shared_ptr<Command> result = boost::make_shared<Command>(); + + lua_getfield(L, -1, "node"); + if (!lua_isnil(L, -1)) { + result->setNode(std::string(Lua::checkString(L, -1))); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "session_id"); + if (!lua_isnil(L, -1)) { + result->setSessionID(std::string(Lua::checkString(L, -1))); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "status"); + if (!lua_isnil(L, -1)) { + std::string statusText = Lua::checkString(L, -1); + Command::Status status = Command::NoStatus; + if (statusText == "executing") { status = Command::Executing; } + else if (statusText == "completed") { status = Command::Completed; } + else if (statusText == "canceled") { status = Command::Canceled; } + result->setStatus(status); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "action"); + if (!lua_isnil(L, -1)) { + result->setAction(convertActionFromString(Lua::checkString(L, -1))); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "execute_action"); + if (!lua_isnil(L, -1)) { + result->setExecuteAction(convertActionFromString(Lua::checkString(L, -1))); + } + lua_pop(L, 1); + + lua_getfield(L, -1, "available_actions"); + if (!lua_isnil(L, -1)) { + Lua::checkType(L, -1, LUA_TTABLE); + lua_pushnil(L); + for (lua_pushnil(L); lua_next(L, -2) != 0; ) { + result->addAvailableAction(convertActionFromString(Lua::checkString(L, -1))); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, -1, "notes"); + if (!lua_isnil(L, -1)) { + Lua::checkType(L, -1, LUA_TTABLE); + lua_pushnil(L); + for (lua_pushnil(L); lua_next(L, -2) != 0; ) { + Lua::checkType(L, -1, LUA_TTABLE); + std::string note; + lua_getfield(L, -1, "note"); + if (!lua_isnil(L, -1)) { + note = Lua::checkString(L, -1); + } + lua_pop(L, 1); + + Command::Note::Type noteType = Command::Note::Info; + lua_getfield(L, -1, "type"); + if (!lua_isnil(L, -1)) { + std::string type = Lua::checkString(L, -1); + if (type == "info") { noteType = Command::Note::Info; } + else if (type == "warn") { noteType = Command::Note::Warn; } + else if (type == "error") { noteType = Command::Note::Error; } + } + lua_pop(L, 1); + + result->addNote(Command::Note(note, noteType)); + lua_pop(L, 1); + } + } + lua_pop(L, 1); + + lua_getfield(L, -1, "form"); + if (!lua_isnil(L, -1)) { + if (boost::shared_ptr<Form> form = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) { + result->setForm(form); + } + } + lua_pop(L, 1); + + return result; +} + +void CommandConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<Command> payload) { + Lua::Table result; + if (!payload->getNode().empty()) { + result["node"] = Lua::valueRef(payload->getNode()); + } + if (!payload->getSessionID().empty()) { + result["session_id"] = Lua::valueRef(payload->getSessionID()); + } + switch (payload->getStatus()) { + case Command::Executing: result["status"] = Lua::valueRef("executing"); break; + case Command::Completed: result["status"] = Lua::valueRef("completed"); break; + case Command::Canceled: result["status"] = Lua::valueRef("canceled"); break; + case Command::NoStatus: break; + } + + if (!payload->getNotes().empty()) { + std::vector<Lua::Value> notes; + foreach (const Command::Note& note, payload->getNotes()) { + Lua::Table noteTable; + if (!note.note.empty()) { + noteTable["note"] = Lua::valueRef(note.note); + } + switch (note.type) { + case Command::Note::Info: noteTable["type"] = Lua::valueRef("info"); break; + case Command::Note::Warn: noteTable["type"] = Lua::valueRef("warn"); break; + case Command::Note::Error: noteTable["type"] = Lua::valueRef("error"); break; + } + notes.push_back(noteTable); + } + result["notes"] = Lua::valueRef(notes); + } + + if (payload->getAction() != Command::NoAction) { + result["action"] = Lua::valueRef(convertActionToString(payload->getAction())); + } + + if (payload->getExecuteAction() != Command::NoAction) { + result["execute_action"] = Lua::valueRef(convertActionToString(payload->getAction())); + } + + if (!payload->getAvailableActions().empty()) { + std::vector<Lua::Value> availableActions; + foreach (const Command::Action& action, payload->getAvailableActions()) { + if (action != Command::NoAction) { + availableActions.push_back(convertActionToString(action)); + } + } + result["available_actions"] = Lua::valueRef(availableActions); + } + + Lua::pushValue(L, result); + + if (payload->getForm()) { + convertors->convertToLuaUntyped(L, payload->getForm()); + lua_setfield(L, -2, "form"); + } +} diff --git a/Sluift/ElementConvertors/CommandConvertor.h b/Sluift/ElementConvertors/CommandConvertor.h new file mode 100644 index 0000000..7008b50 --- /dev/null +++ b/Sluift/ElementConvertors/CommandConvertor.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include <Swiften/Base/Override.h> + +#include <Sluift/GenericLuaElementConvertor.h> +#include <Swiften/Elements/Command.h> + +namespace Swift { + class LuaElementConvertors; + + class CommandConvertor : public GenericLuaElementConvertor<Command> { + public: + CommandConvertor(LuaElementConvertors* convertors); + virtual ~CommandConvertor(); + + virtual boost::shared_ptr<Command> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE; + virtual void doConvertToLua(lua_State*, boost::shared_ptr<Command>) SWIFTEN_OVERRIDE; + + private: + LuaElementConvertors* convertors; + }; +} |