summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2013-09-20 20:32:57 (GMT)
committerRemko Tronçon <git@el-tramo.be>2013-09-21 06:41:34 (GMT)
commit33f9dc5337f1a59932b7ac117b0dea56e1dafe1a (patch)
tree8aeae2309c1a1770313bca0797cb92f8bcee4721 /Sluift/ElementConvertors
parent577c0c8fd30ffc0df718a8958eb7b8784ec3b0ac (diff)
downloadswift-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.cpp195
-rw-r--r--Sluift/ElementConvertors/CommandConvertor.h28
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;
+ };
+}