diff options
Diffstat (limited to 'Sluift/component.cpp')
-rw-r--r-- | Sluift/component.cpp | 717 |
1 files changed, 357 insertions, 360 deletions
diff --git a/Sluift/component.cpp b/Sluift/component.cpp index a9ac2d9..df96d43 100644 --- a/Sluift/component.cpp +++ b/Sluift/component.cpp @@ -1,30 +1,14 @@ /* - * Copyright (c) 2014-2015 Isode Limited. + * Copyright (c) 2014-2016 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ -#include <iostream> - #include <boost/assign/list_of.hpp> #include <boost/lambda/bind.hpp> #include <boost/lambda/lambda.hpp> -#include <Sluift/ElementConvertors/IQConvertor.h> -#include <Sluift/ElementConvertors/MessageConvertor.h> -#include <Sluift/ElementConvertors/PresenceConvertor.h> -#include <Sluift/ElementConvertors/StanzaConvertor.h> -#include <Sluift/ElementConvertors/StatusShowConvertor.h> -#include <Sluift/Lua/Check.h> -#include <Sluift/Lua/Exception.h> -#include <Sluift/Lua/FunctionRegistration.h> -#include <Sluift/Lua/LuaUtils.h> -#include <Sluift/Lua/Value.h> -#include <Sluift/SluiftComponent.h> -#include <Sluift/globals.h> - #include <Swiften/Base/IDGenerator.h> -#include <Swiften/Base/foreach.h> #include <Swiften/Elements/DiscoInfo.h> #include <Swiften/Elements/MAMQuery.h> #include <Swiften/Elements/Message.h> @@ -43,427 +27,440 @@ #include <Swiften/Roster/XMPPRoster.h> #include <Swiften/Roster/XMPPRosterItem.h> +#include <Sluift/ElementConvertors/IQConvertor.h> +#include <Sluift/ElementConvertors/MessageConvertor.h> +#include <Sluift/ElementConvertors/PresenceConvertor.h> +#include <Sluift/ElementConvertors/StanzaConvertor.h> +#include <Sluift/ElementConvertors/StatusShowConvertor.h> +#include <Sluift/Lua/Check.h> +#include <Sluift/Lua/Exception.h> +#include <Sluift/Lua/FunctionRegistration.h> +#include <Sluift/Lua/LuaUtils.h> +#include <Sluift/Lua/Value.h> +#include <Sluift/SluiftComponent.h> +#include <Sluift/globals.h> + using namespace Swift; namespace lambda = boost::lambda; static inline SluiftComponent* getComponent(lua_State* L) { - return *Lua::checkUserData<SluiftComponent>(L, 1); + return *Lua::checkUserData<SluiftComponent>(L, 1); } static inline int getGlobalTimeout(lua_State* L) { - lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.moduleLibIndex); - lua_getfield(L, -1, "timeout"); - int result = boost::numeric_cast<int>(lua_tointeger(L, -1)); - lua_pop(L, 2); - return result; + lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.moduleLibIndex); + lua_getfield(L, -1, "timeout"); + int result = boost::numeric_cast<int>(lua_tointeger(L, -1)); + lua_pop(L, 2); + return result; } -static void addPayloadsToTable(lua_State* L, const std::vector<boost::shared_ptr<Payload> >& payloads) { - if (!payloads.empty()) { - lua_createtable(L, boost::numeric_cast<int>(payloads.size()), 0); - for (size_t i = 0; i < payloads.size(); ++i) { - Sluift::globals.elementConvertor.convertToLua(L, payloads[i]); - lua_rawseti(L, -2, boost::numeric_cast<int>(i+1)); - } - Lua::registerGetByTypeIndex(L, -1); - lua_setfield(L, -2, "payloads"); - } +static void addPayloadsToTable(lua_State* L, const std::vector<std::shared_ptr<Payload> >& payloads) { + if (!payloads.empty()) { + lua_createtable(L, boost::numeric_cast<int>(payloads.size()), 0); + for (size_t i = 0; i < payloads.size(); ++i) { + Sluift::globals.elementConvertor.convertToLua(L, payloads[i]); + lua_rawseti(L, -2, boost::numeric_cast<int>(i+1)); + } + Lua::registerGetByTypeIndex(L, -1); + lua_setfield(L, -2, "payloads"); + } } -static boost::shared_ptr<Payload> getPayload(lua_State* L, int index) { - if (lua_type(L, index) == LUA_TTABLE) { - return boost::dynamic_pointer_cast<Payload>(Sluift::globals.elementConvertor.convertFromLua(L, index)); - } - else if (lua_type(L, index) == LUA_TSTRING) { - return boost::make_shared<RawXMLPayload>(Lua::checkString(L, index)); - } - else { - return boost::shared_ptr<Payload>(); - } +static std::shared_ptr<Payload> getPayload(lua_State* L, int index) { + if (lua_type(L, index) == LUA_TTABLE) { + return std::dynamic_pointer_cast<Payload>(Sluift::globals.elementConvertor.convertFromLua(L, index)); + } + else if (lua_type(L, index) == LUA_TSTRING) { + return std::make_shared<RawXMLPayload>(Lua::checkString(L, index)); + } + else { + return std::shared_ptr<Payload>(); + } } -static std::vector< boost::shared_ptr<Payload> > getPayloadsFromTable(lua_State* L, int index) { - index = Lua::absoluteOffset(L, index); - std::vector< boost::shared_ptr<Payload> > result; - lua_getfield(L, index, "payloads"); - if (lua_istable(L, -1)) { - for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { - boost::shared_ptr<Payload> payload = getPayload(L, -1); - if (payload) { - result.push_back(payload); - } - } - } - lua_pop(L, 1); - return result; +static std::vector< std::shared_ptr<Payload> > getPayloadsFromTable(lua_State* L, int index) { + index = Lua::absoluteOffset(L, index); + std::vector< std::shared_ptr<Payload> > result; + lua_getfield(L, index, "payloads"); + if (lua_istable(L, -1)) { + for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { + std::shared_ptr<Payload> payload = getPayload(L, -1); + if (payload) { + result.push_back(payload); + } + } + } + lua_pop(L, 1); + return result; } SLUIFT_LUA_FUNCTION(Component, async_connect) { - SluiftComponent* component = getComponent(L); - - std::string host; - int port = 0; - if (lua_istable(L, 2)) { - if (boost::optional<std::string> hostString = Lua::getStringField(L, 2, "host")) { - host = *hostString; - } - if (boost::optional<int> portInt = Lua::getIntField(L, 2, "port")) { - port = *portInt; - } - } - component->connect(host, port); - return 0; + SluiftComponent* component = getComponent(L); + + std::string host; + int port = 0; + if (lua_istable(L, 2)) { + if (boost::optional<std::string> hostString = Lua::getStringField(L, 2, "host")) { + host = *hostString; + } + if (boost::optional<int> portInt = Lua::getIntField(L, 2, "port")) { + port = *portInt; + } + } + component->connect(host, port); + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, set_trace_enabled, - "Enable/disable tracing of the data sent/received.\n\n.", - "self\n" - "enable a boolean specifying whether to enable/disable tracing", - "" + Component, set_trace_enabled, + "Enable/disable tracing of the data sent/received.\n\n.", + "self\n" + "enable a boolean specifying whether to enable/disable tracing", + "" ) { - getComponent(L)->setTraceEnabled(lua_toboolean(L, 1)); - return 0; + getComponent(L)->setTraceEnabled(lua_toboolean(L, 1)); + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, wait_connected, - "Block until the component is connected.\n\nThis is useful after an `async_connect`.", - "self", - "" + Component, wait_connected, + "Block until the component is connected.\n\nThis is useful after an `async_connect`.", + "self", + "" ) { - getComponent(L)->waitConnected(getGlobalTimeout(L)); - return 0; + getComponent(L)->waitConnected(getGlobalTimeout(L)); + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, is_connected, - "Checks whether this component is still connected.\n\nReturns a boolean.", - "self\n", - "" + Component, is_connected, + "Checks whether this component is still connected.\n\nReturns a boolean.", + "self\n", + "" ) { - lua_pushboolean(L, getComponent(L)->isConnected()); - return 1; + lua_pushboolean(L, getComponent(L)->isConnected()); + return 1; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, disconnect, - "Disconnect from the server", - "self\n", - "" + Component, disconnect, + "Disconnect from the server", + "self\n", + "" ) { - Sluift::globals.eventLoop.runOnce(); - getComponent(L)->disconnect(); - return 0; + Sluift::globals.eventLoop.runOnce(); + getComponent(L)->disconnect(); + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, set_version, + Component, set_version, - "Sets the published version of this component.", + "Sets the published version of this component.", - "self", + "self", - "name the name of the component software\n" - "version the version identifier of this component\n" - "os the OS this component is running on\n" + "name the name of the component software\n" + "version the version identifier of this component\n" + "os the OS this component is running on\n" ) { - Sluift::globals.eventLoop.runOnce(); - SluiftComponent* component = getComponent(L); - if (boost::shared_ptr<SoftwareVersion> version = boost::dynamic_pointer_cast<SoftwareVersion>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "software_version"))) { - component->setSoftwareVersion(version->getName(), version->getVersion(), version->getOS()); - } - return 0; + Sluift::globals.eventLoop.runOnce(); + SluiftComponent* component = getComponent(L); + if (std::shared_ptr<SoftwareVersion> version = std::dynamic_pointer_cast<SoftwareVersion>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "software_version"))) { + component->setSoftwareVersion(version->getName(), version->getVersion(), version->getOS()); + } + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, send_message, - "Send a message.", - "self\n" - "to the JID to send the message to\n" - "body the body of the message. Can alternatively be specified using the `body` option\n", - - "to the JID to send the message to\n" - "body the body of the message\n" - "subject the subject of the MUC room to set\n" - "type the type of message to send (`normal`, `chat`, `error`, `groupchat`, `headline`)\n" - "payloads payloads to add to the message\n" + Component, send_message, + "Send a message.", + "self\n" + "to the JID to send the message to\n" + "body the body of the message. Can alternatively be specified using the `body` option\n", + + "to the JID to send the message to\n" + "body the body of the message\n" + "subject the subject of the MUC room to set\n" + "type the type of message to send (`normal`, `chat`, `error`, `groupchat`, `headline`)\n" + "payloads payloads to add to the message\n" ) { - Sluift::globals.eventLoop.runOnce(); - JID to; - boost::optional<std::string> from; - boost::optional<std::string> body; - boost::optional<std::string> subject; - std::vector<boost::shared_ptr<Payload> > payloads; - int index = 2; - Message::Type type = Message::Chat; - if (lua_isstring(L, index)) { - to = std::string(lua_tostring(L, index)); - ++index; - if (lua_isstring(L, index)) { - body = lua_tostring(L, index); - ++index; - } - } - if (lua_istable(L, index)) { - if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) { - to = *value; - } - - if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) { - from = value; - } - - if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) { - body = value; - } - - if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) { - type = MessageConvertor::convertMessageTypeFromString(*value); - } - - if (boost::optional<std::string> value = Lua::getStringField(L, index, "subject")) { - subject = value; - } - - payloads = getPayloadsFromTable(L, index); - } - - if (!to.isValid()) { - throw Lua::Exception("Missing 'to'"); - } - if ((!body || body->empty()) && !subject && payloads.empty()) { - throw Lua::Exception("Missing any of 'body', 'subject' or 'payloads'"); - } - Message::ref message = boost::make_shared<Message>(); - message->setTo(to); - if (from && !from->empty()) { - message->setFrom(*from); - } - if (body && !body->empty()) { - message->setBody(*body); - } - if (subject) { - message->setSubject(*subject); - } - message->addPayloads(payloads.begin(), payloads.end()); - message->setType(type); - getComponent(L)->getComponent()->sendMessage(message); - return 0; + Sluift::globals.eventLoop.runOnce(); + JID to; + boost::optional<std::string> from; + boost::optional<std::string> body; + boost::optional<std::string> subject; + std::vector<std::shared_ptr<Payload> > payloads; + int index = 2; + Message::Type type = Message::Chat; + if (lua_isstring(L, index)) { + to = std::string(lua_tostring(L, index)); + ++index; + if (lua_isstring(L, index)) { + body = lua_tostring(L, index); + ++index; + } + } + if (lua_istable(L, index)) { + if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) { + to = *value; + } + + if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) { + from = value; + } + + if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) { + body = value; + } + + if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) { + type = MessageConvertor::convertMessageTypeFromString(*value); + } + + if (boost::optional<std::string> value = Lua::getStringField(L, index, "subject")) { + subject = value; + } + + payloads = getPayloadsFromTable(L, index); + } + + if (!to.isValid()) { + throw Lua::Exception("Missing 'to'"); + } + if ((!body || body->empty()) && !subject && payloads.empty()) { + throw Lua::Exception("Missing any of 'body', 'subject' or 'payloads'"); + } + Message::ref message = std::make_shared<Message>(); + message->setTo(to); + if (from && !from->empty()) { + message->setFrom(*from); + } + if (body && !body->empty()) { + message->setBody(*body); + } + if (subject) { + message->setSubject(*subject); + } + message->addPayloads(payloads.begin(), payloads.end()); + message->setType(type); + getComponent(L)->getComponent()->sendMessage(message); + return 0; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, send_presence, - "Send presence.", - - "self\n" - "body the text of the presence. Can alternatively be specified using the `status` option\n", - - "to the JID to send the message to\n" - "from the JID to send the message from\n" - "status the text of the presence\n" - "show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n" - "priority the priority of the presence\n" - "type the type of message to send (`available`, `error`, `probe`, `subscribe`, `subscribed`, `unavailable`, `unsubscribe`, `unsubscribed`)\n" - "payloads payloads to add to the presence\n" + Component, send_presence, + "Send presence.", + + "self\n" + "body the text of the presence. Can alternatively be specified using the `status` option\n", + + "to the JID to send the message to\n" + "from the JID to send the message from\n" + "status the text of the presence\n" + "show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n" + "priority the priority of the presence\n" + "type the type of message to send (`available`, `error`, `probe`, `subscribe`, `subscribed`, `unavailable`, `unsubscribe`, `unsubscribed`)\n" + "payloads payloads to add to the presence\n" ) { - Sluift::globals.eventLoop.runOnce(); - boost::shared_ptr<Presence> presence = boost::make_shared<Presence>(); - - int index = 2; - if (lua_isstring(L, index)) { - presence->setStatus(lua_tostring(L, index)); - ++index; - } - if (lua_istable(L, index)) { - if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) { - presence->setTo(*value); - } - if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) { - presence->setFrom(*value); - } - if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) { - presence->setStatus(*value); - } - if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) { - presence->setPriority(*value); - } - if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) { - presence->setType(PresenceConvertor::convertPresenceTypeFromString(*value)); - } - if (boost::optional<std::string> value = Lua::getStringField(L, index, "show")) { - presence->setShow(StatusShowConvertor::convertStatusShowTypeFromString(*value)); - } - std::vector< boost::shared_ptr<Payload> > payloads = getPayloadsFromTable(L, index); - presence->addPayloads(payloads.begin(), payloads.end()); - } - - getComponent(L)->getComponent()->sendPresence(presence); - lua_pushvalue(L, 1); - return 0; + Sluift::globals.eventLoop.runOnce(); + std::shared_ptr<Presence> presence = std::make_shared<Presence>(); + + int index = 2; + if (lua_isstring(L, index)) { + presence->setStatus(lua_tostring(L, index)); + ++index; + } + if (lua_istable(L, index)) { + if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) { + presence->setTo(*value); + } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) { + presence->setFrom(*value); + } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) { + presence->setStatus(*value); + } + if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) { + presence->setPriority(*value); + } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) { + presence->setType(PresenceConvertor::convertPresenceTypeFromString(*value)); + } + if (boost::optional<std::string> value = Lua::getStringField(L, index, "show")) { + presence->setShow(StatusShowConvertor::convertStatusShowTypeFromString(*value)); + } + std::vector< std::shared_ptr<Payload> > payloads = getPayloadsFromTable(L, index); + presence->addPayloads(payloads.begin(), payloads.end()); + } + + getComponent(L)->getComponent()->sendPresence(presence); + lua_pushvalue(L, 1); + return 0; } static int sendQuery(lua_State* L, IQ::Type type) { - SluiftComponent* component = getComponent(L); - - JID to; - if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) { - to = JID(*toString); - } - - JID from; - if (boost::optional<std::string> fromString = Lua::getStringField(L, 2, "from")) { - from = JID(*fromString); - } - - int timeout = getGlobalTimeout(L); - if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) { - timeout = *timeoutInt; - } - - boost::shared_ptr<Payload> payload; - lua_getfield(L, 2, "query"); - payload = getPayload(L, -1); - lua_pop(L, 1); - - return component->sendRequest( - boost::make_shared< GenericRequest<Payload> >(type, from, to, payload, component->getComponent()->getIQRouter()), timeout).convertToLuaResult(L); + SluiftComponent* component = getComponent(L); + + JID to; + if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) { + to = JID(*toString); + } + + JID from; + if (boost::optional<std::string> fromString = Lua::getStringField(L, 2, "from")) { + from = JID(*fromString); + } + + int timeout = getGlobalTimeout(L); + if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) { + timeout = *timeoutInt; + } + + std::shared_ptr<Payload> payload; + lua_getfield(L, 2, "query"); + payload = getPayload(L, -1); + lua_pop(L, 1); + + return component->sendRequest( + std::make_shared< GenericRequest<Payload> >(type, from, to, payload, component->getComponent()->getIQRouter()), timeout).convertToLuaResult(L); } SLUIFT_LUA_FUNCTION(Component, get) { - return sendQuery(L, IQ::Get); + return sendQuery(L, IQ::Get); } SLUIFT_LUA_FUNCTION(Component, set) { - return sendQuery(L, IQ::Set); + return sendQuery(L, IQ::Set); } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, send, - "Sends a raw string", + Component, send, + "Sends a raw string", - "self\n" - "data the string to send\n", + "self\n" + "data the string to send\n", - "" + "" ) { - Sluift::globals.eventLoop.runOnce(); + Sluift::globals.eventLoop.runOnce(); - getComponent(L)->getComponent()->sendData(std::string(Lua::checkString(L, 2))); - lua_pushvalue(L, 1); - return 0; + getComponent(L)->getComponent()->sendData(std::string(Lua::checkString(L, 2))); + lua_pushvalue(L, 1); + return 0; } static void pushEvent(lua_State* L, const SluiftComponent::Event& event) { - switch (event.type) { - case SluiftComponent::Event::MessageType: { - Message::ref message = boost::dynamic_pointer_cast<Message>(event.stanza); - Lua::Table result = boost::assign::map_list_of - ("type", boost::make_shared<Lua::Value>(std::string("message"))) - ("from", boost::make_shared<Lua::Value>(message->getFrom().toString())) - ("to", boost::make_shared<Lua::Value>(message->getTo().toString())) - ("body", boost::make_shared<Lua::Value>(message->getBody().get_value_or(""))) - ("message_type", boost::make_shared<Lua::Value>(MessageConvertor::convertMessageTypeToString(message->getType()))); - Lua::pushValue(L, result); - addPayloadsToTable(L, message->getPayloads()); - Lua::registerTableToString(L, -1); - break; - } - case SluiftComponent::Event::PresenceType: { - Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event.stanza); - Lua::Table result = boost::assign::map_list_of - ("type", boost::make_shared<Lua::Value>(std::string("presence"))) - ("from", boost::make_shared<Lua::Value>(presence->getFrom().toString())) - ("to", boost::make_shared<Lua::Value>(presence->getTo().toString())) - ("status", boost::make_shared<Lua::Value>(presence->getStatus())) - ("presence_type", boost::make_shared<Lua::Value>(PresenceConvertor::convertPresenceTypeToString(presence->getType()))); - Lua::pushValue(L, result); - addPayloadsToTable(L, presence->getPayloads()); - Lua::registerTableToString(L, -1); - break; - } - } + switch (event.type) { + case SluiftComponent::Event::MessageType: { + Message::ref message = std::dynamic_pointer_cast<Message>(event.stanza); + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared<Lua::Value>(std::string("message"))) + ("from", std::make_shared<Lua::Value>(message->getFrom().toString())) + ("to", std::make_shared<Lua::Value>(message->getTo().toString())) + ("body", std::make_shared<Lua::Value>(message->getBody().get_value_or(""))) + ("message_type", std::make_shared<Lua::Value>(MessageConvertor::convertMessageTypeToString(message->getType()))); + Lua::pushValue(L, result); + addPayloadsToTable(L, message->getPayloads()); + Lua::registerTableToString(L, -1); + break; + } + case SluiftComponent::Event::PresenceType: { + Presence::ref presence = std::dynamic_pointer_cast<Presence>(event.stanza); + Lua::Table result = boost::assign::map_list_of + ("type", std::make_shared<Lua::Value>(std::string("presence"))) + ("from", std::make_shared<Lua::Value>(presence->getFrom().toString())) + ("to", std::make_shared<Lua::Value>(presence->getTo().toString())) + ("status", std::make_shared<Lua::Value>(presence->getStatus())) + ("presence_type", std::make_shared<Lua::Value>(PresenceConvertor::convertPresenceTypeToString(presence->getType()))); + Lua::pushValue(L, result); + addPayloadsToTable(L, presence->getPayloads()); + Lua::registerTableToString(L, -1); + break; + } + } } struct CallUnaryLuaPredicateOnEvent { - CallUnaryLuaPredicateOnEvent(lua_State* L, int index) : L(L), index(index) { - } - - bool operator()(const SluiftComponent::Event& event) { - lua_pushvalue(L, index); - pushEvent(L, event); - if (lua_pcall(L, 1, 1, 0) != 0) { - throw Lua::Exception(lua_tostring(L, -1)); - } - bool result = lua_toboolean(L, -1); - lua_pop(L, 1); - return result; - } - - lua_State* L; - int index; + CallUnaryLuaPredicateOnEvent(lua_State* L, int index) : L(L), index(index) { + } + + bool operator()(const SluiftComponent::Event& event) { + lua_pushvalue(L, index); + pushEvent(L, event); + if (lua_pcall(L, 1, 1, 0) != 0) { + throw Lua::Exception(lua_tostring(L, -1)); + } + bool result = lua_toboolean(L, -1); + lua_pop(L, 1); + return result; + } + + lua_State* L; + int index; }; SLUIFT_LUA_FUNCTION(Component, get_next_event) { - Sluift::globals.eventLoop.runOnce(); - SluiftComponent* component = getComponent(L); - - int timeout = getGlobalTimeout(L); - boost::optional<SluiftComponent::Event::Type> type; - int condition = 0; - if (lua_istable(L, 2)) { - if (boost::optional<std::string> typeString = Lua::getStringField(L, 2, "type")) { - if (*typeString == "message") { - type = SluiftComponent::Event::MessageType; - } - else if (*typeString == "presence") { - type = SluiftComponent::Event::PresenceType; - } - } - if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) { - timeout = *timeoutInt; - } - lua_getfield(L, 2, "if"); - if (lua_isfunction(L, -1)) { - condition = Lua::absoluteOffset(L, -1); - } - } - - boost::optional<SluiftComponent::Event> event; - if (condition) { - event = component->getNextEvent(timeout, CallUnaryLuaPredicateOnEvent(L, condition)); - } - else if (type) { - event = component->getNextEvent( - timeout, lambda::bind(&SluiftComponent::Event::type, lambda::_1) == *type); - } - else { - event = component->getNextEvent(timeout); - } - - if (event) { - pushEvent(L, *event); - } - else { - lua_pushnil(L); - } - return 1; + Sluift::globals.eventLoop.runOnce(); + SluiftComponent* component = getComponent(L); + + int timeout = getGlobalTimeout(L); + boost::optional<SluiftComponent::Event::Type> type; + int condition = 0; + if (lua_istable(L, 2)) { + if (boost::optional<std::string> typeString = Lua::getStringField(L, 2, "type")) { + if (*typeString == "message") { + type = SluiftComponent::Event::MessageType; + } + else if (*typeString == "presence") { + type = SluiftComponent::Event::PresenceType; + } + } + if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) { + timeout = *timeoutInt; + } + lua_getfield(L, 2, "if"); + if (lua_isfunction(L, -1)) { + condition = Lua::absoluteOffset(L, -1); + } + } + + boost::optional<SluiftComponent::Event> event; + if (condition) { + event = component->getNextEvent(timeout, CallUnaryLuaPredicateOnEvent(L, condition)); + } + else if (type) { + event = component->getNextEvent( + timeout, lambda::bind(&SluiftComponent::Event::type, lambda::_1) == *type); + } + else { + event = component->getNextEvent(timeout); + } + + if (event) { + pushEvent(L, *event); + } + else { + lua_pushnil(L); + } + return 1; } SLUIFT_LUA_FUNCTION_WITH_HELP( - Component, jid, - "Returns the JID of this component", - "self\n", - "" + Component, jid, + "Returns the JID of this component", + "self\n", + "" ) { - SluiftComponent* component = getComponent(L); - lua_pushstring(L, component->getComponent()->getJID().toString().c_str()); - return 1; + SluiftComponent* component = getComponent(L); + lua_pushstring(L, component->getComponent()->getJID().toString().c_str()); + return 1; } SLUIFT_LUA_FUNCTION(Component, __gc) { - SluiftComponent* component = getComponent(L); - delete component; - return 0; + SluiftComponent* component = getComponent(L); + delete component; + return 0; } |