From 29e4e51e21b8902c82456cc85af46fa5f5889f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sun, 10 Oct 2010 15:31:39 +0200 Subject: Refactor responders to only start on start(). diff --git a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp index b0a76fd..98a63d6 100644 --- a/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp +++ b/Documentation/SwiftenDevelopersGuide/Examples/EchoBot/EchoBot5.cpp @@ -27,12 +27,14 @@ class EchoBot { //... softwareVersionResponder = new SoftwareVersionResponder( "EchoBot", "1.0", client->getIQRouter()); + softwareVersionResponder->start(); //... client->connect(); //... } ~EchoBot() { + softwareVersionResponder->stop(); delete softwareVersionResponder; //... delete tracer; diff --git a/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml b/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml index 1df3781..ab1b796 100644 --- a/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml +++ b/Documentation/SwiftenDevelopersGuide/Swiften Developers Guide.xml @@ -254,8 +254,9 @@ Using SoftwareVersionResponder is pretty straightforward, as can be seen in : - simply construct the responder with the correct - parameters, and it will automatically respond to the incoming + simply construct the responder, set the correct + parameters, call start(), and it will automatically respond to + the incoming requests. Other Responder classes may provide signals to notify of incoming requests, or may have some other behavior. For a detailed explanation of responders, see diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 41c5581..48cceca 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -196,10 +196,16 @@ void MainController::resetClient() { serverDiscoInfo_ = boost::shared_ptr(); delete mucSearchController_; mucSearchController_ = NULL; - delete discoResponder_; - discoResponder_ = NULL; - delete clientVersionResponder_; - clientVersionResponder_ = NULL; + if (discoResponder_) { + discoResponder_->stop(); + delete discoResponder_; + discoResponder_ = NULL; + } + if (clientVersionResponder_) { + clientVersionResponder_->stop(); + delete clientVersionResponder_; + clientVersionResponder_ = NULL; + } delete eventWindowController_; eventWindowController_ = NULL; delete xmppRosterController_; @@ -288,6 +294,7 @@ void MainController::handleConnected() { eventWindowController_ = new EventWindowController(eventController_, eventWindowFactory_); clientVersionResponder_ = new SoftwareVersionResponder(CLIENT_NAME, buildVersion, client_->getIQRouter()); + clientVersionResponder_->start(); loginWindow_->morphInto(rosterController_->getWindow()); DiscoInfo discoInfo; @@ -299,6 +306,7 @@ void MainController::handleConnected() { discoResponder_ = new DiscoInfoResponder(client_->getIQRouter()); discoResponder_->setDiscoInfo(discoInfo); discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo); + discoResponder_->start(); serverDiscoInfo_ = boost::shared_ptr(new DiscoInfo()); mucSearchController_ = new MUCSearchController(jid_, uiEventStream_, mucSearchWindowFactory_, client_->getIQRouter()); diff --git a/Swiften/Queries/Responder.h b/Swiften/Queries/Responder.h index b38c3c4..2333b5f 100644 --- a/Swiften/Queries/Responder.h +++ b/Swiften/Queries/Responder.h @@ -4,33 +4,78 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_Responder_H -#define SWIFTEN_Responder_H +#pragma once #include "Swiften/Queries/IQHandler.h" #include "Swiften/Queries/IQRouter.h" #include "Swiften/Elements/ErrorPayload.h" namespace Swift { + /** + * A class for handling incoming IQ Get and Set requests of a specific payload type. + * + * Concrete subclasses of this class need to implement handleGetRequest() and handleSetRequest() to + * implement the behavior of the responder. + * + * \tparam PAYLOAD_TYPE The type of payload this Responder handles. Only IQ requests containing this + * payload type will be passed to handleGetRequest() and handleSetRequest() + */ template class Responder : public IQHandler { public: Responder(IQRouter* router) : router_(router) { - router_->addHandler(this); } ~Responder() { + } + + /** + * Starts the responder. + * + * After the responder has started, it will start receiving and responding to requests. + * + * \see stop() + */ + void start() { + router_->addHandler(this); + } + + /** + * Stops the responder. + * + * When the responder is stopped, it will no longer receive incoming requests. + * + * \see start() + */ + void stop() { router_->removeHandler(this); } protected: + /** + * Handle an incoming IQ-Get request containing a payload of class PAYLOAD_TYPE. + * + * This method is implemented in the concrete subclasses. + */ virtual bool handleGetRequest(const JID& from, const String& id, boost::shared_ptr payload) = 0; + + /** + * Handle an incoming IQ-Set request containing a payload of class PAYLOAD_TYPE. + * + * This method is implemented in the concrete subclasses. + */ virtual bool handleSetRequest(const JID& from, const String& id, boost::shared_ptr payload) = 0; - void sendResponse(const JID& to, const String& id, boost::shared_ptr payload) { + /** + * Convenience function for sending an IQ response. + */ + void sendResponse(const JID& to, const String& id, boost::shared_ptr payload) { router_->sendIQ(IQ::createResult(to, id, payload)); } + /** + * Convenience function for responding with an error. + */ void sendError(const JID& to, const String& id, ErrorPayload::Condition condition, ErrorPayload::Type type) { router_->sendIQ(IQ::createError(to, id, condition, type)); } @@ -60,5 +105,3 @@ namespace Swift { IQRouter* router_; }; } - -#endif diff --git a/Swiften/Queries/Responders/RosterPushResponder.h b/Swiften/Queries/Responders/RosterPushResponder.h index 8c57fd3..48111a7 100644 --- a/Swiften/Queries/Responders/RosterPushResponder.h +++ b/Swiften/Queries/Responders/RosterPushResponder.h @@ -22,7 +22,7 @@ namespace Swift { private: virtual bool handleSetRequest(const JID& from, const String& id, boost::shared_ptr payload) { onRosterReceived(payload); - sendResponse(from, id, boost::shared_ptr()); + sendResponse(from, id, boost::shared_ptr()); return true; } }; diff --git a/Swiften/Queries/Responders/UnitTest/DiscoInfoResponderTest.cpp b/Swiften/Queries/Responders/UnitTest/DiscoInfoResponderTest.cpp index 62d9aca..20fa9ff 100644 --- a/Swiften/Queries/Responders/UnitTest/DiscoInfoResponderTest.cpp +++ b/Swiften/Queries/Responders/UnitTest/DiscoInfoResponderTest.cpp @@ -35,7 +35,8 @@ class DiscoInfoResponderTest : public CppUnit::TestFixture { } void testHandleRequest_GetToplevelInfo() { - DiscoInfoResponder testling(router_); + DiscoInfoResponder testling(router_); + testling.start(); DiscoInfo discoInfo; discoInfo.addFeature("foo"); testling.setDiscoInfo(discoInfo); @@ -48,10 +49,13 @@ class DiscoInfoResponderTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(payload); CPPUNIT_ASSERT_EQUAL(String(""), payload->getNode()); CPPUNIT_ASSERT(payload->hasFeature("foo")); + + testling.stop(); } void testHandleRequest_GetNodeInfo() { DiscoInfoResponder testling(router_); + testling.start(); DiscoInfo discoInfo; discoInfo.addFeature("foo"); testling.setDiscoInfo(discoInfo); @@ -68,6 +72,8 @@ class DiscoInfoResponderTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(payload); CPPUNIT_ASSERT_EQUAL(String("bar-node"), payload->getNode()); CPPUNIT_ASSERT(payload->hasFeature("bar")); + + testling.stop(); } void testHandleRequest_GetInvalidNodeInfo() { diff --git a/Swiften/Queries/UnitTest/ResponderTest.cpp b/Swiften/Queries/UnitTest/ResponderTest.cpp index 513c6ac..9824c98 100644 --- a/Swiften/Queries/UnitTest/ResponderTest.cpp +++ b/Swiften/Queries/UnitTest/ResponderTest.cpp @@ -20,6 +20,8 @@ class ResponderTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(ResponderTest); CPPUNIT_TEST(testConstructor); + CPPUNIT_TEST(testStart); + CPPUNIT_TEST(testStop); CPPUNIT_TEST(testHandleIQ_Set); CPPUNIT_TEST(testHandleIQ_Get); CPPUNIT_TEST(testHandleIQ_Error); @@ -46,9 +48,28 @@ class ResponderTest : public CppUnit::TestFixture channel_->onIQReceived(createRequest(IQ::Set)); + CPPUNIT_ASSERT_EQUAL(0, static_cast(testling.setPayloads_.size())); + } + + void testStart() { + MyResponder testling(router_); + + testling.start(); + channel_->onIQReceived(createRequest(IQ::Set)); + CPPUNIT_ASSERT_EQUAL(1, static_cast(testling.setPayloads_.size())); } + void testStop() { + MyResponder testling(router_); + + testling.start(); + testling.stop(); + channel_->onIQReceived(createRequest(IQ::Set)); + + CPPUNIT_ASSERT_EQUAL(0, static_cast(testling.setPayloads_.size())); + } + void testHandleIQ_Set() { MyResponder testling(router_); diff --git a/Swiften/Roster/XMPPRosterController.cpp b/Swiften/Roster/XMPPRosterController.cpp index 7743ec8..feaa7d4 100644 --- a/Swiften/Roster/XMPPRosterController.cpp +++ b/Swiften/Roster/XMPPRosterController.cpp @@ -25,6 +25,11 @@ namespace Swift { */ XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, XMPPRoster* xmppRoster) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster) { rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1)); + rosterPushResponder_.start(); +} + +XMPPRosterController::~XMPPRosterController() { + rosterPushResponder_.stop(); } void XMPPRosterController::requestRoster() { diff --git a/Swiften/Roster/XMPPRosterController.h b/Swiften/Roster/XMPPRosterController.h index 3ef7795..22a63ad 100644 --- a/Swiften/Roster/XMPPRosterController.h +++ b/Swiften/Roster/XMPPRosterController.h @@ -22,6 +22,7 @@ namespace Swift { class XMPPRosterController { public: XMPPRosterController(IQRouter *iqRouter, XMPPRoster* xmppRoster); + ~XMPPRosterController(); void requestRoster(); -- cgit v0.10.2-6-g49f6