From 3760140b77f1cf568a7cdf824502ff6568e62fc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sun, 10 Oct 2010 18:07:31 +0200 Subject: Client refactoring. Removing inheritance from StanzaChannel to trim down the public API. diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 53b9ab0..c219ae9 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -285,7 +285,7 @@ void MainController::handleConnected() { rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2)); rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); - chatsManager_ = new ChatsManager(jid_, client_, client_->getIQRouter(), eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_, mucRegistry_, entityCapsManager_); + chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, chatWindowFactory_, nickResolver_, presenceOracle_, serverDiscoInfo_, presenceSender_, uiEventStream_, chatListWindowFactory_, useDelayForLatency_, &timerFactory_, mucRegistry_, entityCapsManager_); client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1)); chatsManager_->setAvatarManager(avatarManager_); @@ -420,17 +420,17 @@ void MainController::performLoginFromCachedCredentials() { } if (!client_) { client_ = new Swift::Client(jid_, password_); - presenceSender_ = new PresenceSender(client_); - presenceOracle_ = new PresenceOracle(client_); + presenceSender_ = new PresenceSender(client_->getStanzaChannel()); + presenceOracle_ = new PresenceOracle(client_->getStanzaChannel()); mucRegistry_ = new MUCRegistry(); xmppRoster_ = new XMPPRoster(); vcardManager_ = new VCardManager(jid_, client_->getIQRouter(), getVCardStorageForProfile(jid_)); vcardManager_->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2)); nickResolver_ = new NickResolver(this->jid_.toBare(), xmppRoster_, vcardManager_, mucRegistry_); - avatarManager_ = new AvatarManagerImpl(vcardManager_, client_, avatarStorage_, mucRegistry_); - capsManager_ = new CapsManager(capsStorage_, client_, client_->getIQRouter()); - entityCapsManager_ = new EntityCapsManager(capsManager_, client_); - presenceNotifier_ = new PresenceNotifier(client_, notifier_, mucRegistry_, avatarManager_, nickResolver_, presenceOracle_, &timerFactory_); + avatarManager_ = new AvatarManagerImpl(vcardManager_, client_->getStanzaChannel(), avatarStorage_, mucRegistry_); + capsManager_ = new CapsManager(capsStorage_, client_->getStanzaChannel(), client_->getIQRouter()); + entityCapsManager_ = new EntityCapsManager(capsManager_, client_->getStanzaChannel()); + presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, mucRegistry_, avatarManager_, nickResolver_, presenceOracle_, &timerFactory_); presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); eventNotifier_ = new EventNotifier(eventController_, notifier_, avatarManager_, nickResolver_); eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 5b57672..120a8fb 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -18,11 +18,19 @@ #include "Swiften/TLS/PKCS12Certificate.h" #include "Swiften/Session/BasicSessionStream.h" #include "Swiften/Queries/IQRouter.h" +#include "Swiften/Base/IDGenerator.h" +#include "Swiften/Client/ClientSessionStanzaChannel.h" namespace Swift { Client::Client(const JID& jid, const String& password) : jid_(jid), password_(password), disconnectRequested_(false) { - iqRouter_ = new IQRouter(this); + stanzaChannel_ = new ClientSessionStanzaChannel(); + stanzaChannel_->onMessageReceived.connect(boost::ref(onMessageReceived)); + stanzaChannel_->onPresenceReceived.connect(boost::ref(onPresenceReceived)); + stanzaChannel_->onStanzaAcked.connect(boost::ref(onStanzaAcked)); + stanzaChannel_->onAvailableChanged.connect(boost::bind(&Client::handleStanzaChannelAvailableChanged, this, _1)); + + iqRouter_ = new IQRouter(stanzaChannel_); connectionFactory_ = new BoostConnectionFactory(&MainBoostIOServiceThread::getInstance().getIOService()); timerFactory_ = new BoostTimerFactory(&MainBoostIOServiceThread::getInstance().getIOService()); tlsLayerFactory_ = new PlatformTLSLayerFactory(); @@ -36,10 +44,12 @@ Client::~Client() { delete timerFactory_; delete connectionFactory_; delete iqRouter_; -} -bool Client::isAvailable() { - return session_ && session_->getState() == ClientSession::Initialized; + stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&Client::handleStanzaChannelAvailableChanged, this, _1)); + stanzaChannel_->onMessageReceived.disconnect(boost::ref(onMessageReceived)); + stanzaChannel_->onPresenceReceived.disconnect(boost::ref(onPresenceReceived)); + stanzaChannel_->onStanzaAcked.disconnect(boost::ref(onStanzaAcked)); + delete stanzaChannel_; } void Client::connect() { @@ -81,11 +91,9 @@ void Client::handleConnectorFinished(boost::shared_ptr connection) { sessionStream_->initialize(); session_ = ClientSession::create(jid_, sessionStream_); - session_->onInitialized.connect(boost::bind(&Client::handleSessionInitialized, this)); - session_->onStanzaAcked.connect(boost::bind(&Client::handleStanzaAcked, this, _1)); + stanzaChannel_->setSession(session_); session_->onFinished.connect(boost::bind(&Client::handleSessionFinished, this, _1)); session_->onNeedCredentials.connect(boost::bind(&Client::handleNeedCredentials, this)); - session_->onStanzaReceived.connect(boost::bind(&Client::handleStanza, this, _1)); session_->start(); } } @@ -107,60 +115,13 @@ void Client::disconnect() { disconnectRequested_ = false; } -void Client::send(boost::shared_ptr stanza) { - if (!isAvailable()) { - std::cerr << "Warning: Client: Trying to send a stanza while disconnected." << std::endl; - return; - } - session_->sendStanza(stanza); -} - -void Client::sendIQ(boost::shared_ptr iq) { - send(iq); -} - -void Client::sendMessage(boost::shared_ptr message) { - send(message); -} - -void Client::sendPresence(boost::shared_ptr presence) { - send(presence); -} - -String Client::getNewIQID() { - return idGenerator_.generateID(); -} - -void Client::handleStanza(boost::shared_ptr stanza) { - boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); - if (message) { - onMessageReceived(message); - return; - } - - boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); - if (presence) { - onPresenceReceived(presence); - return; - } - - boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); - if (iq) { - onIQReceived(iq); - return; - } -} - void Client::setCertificate(const String& certificate) { certificate_ = certificate; } void Client::handleSessionFinished(boost::shared_ptr error) { - session_->onInitialized.disconnect(boost::bind(&Client::handleSessionInitialized, this)); - session_->onStanzaAcked.disconnect(boost::bind(&Client::handleStanzaAcked, this, _1)); session_->onFinished.disconnect(boost::bind(&Client::handleSessionFinished, this, _1)); session_->onNeedCredentials.disconnect(boost::bind(&Client::handleNeedCredentials, this)); - session_->onStanzaReceived.disconnect(boost::bind(&Client::handleStanza, this, _1)); session_.reset(); sessionStream_->onDataRead.disconnect(boost::bind(&Client::handleDataRead, this, _1)); @@ -170,8 +131,6 @@ void Client::handleSessionFinished(boost::shared_ptr error) { connection_->disconnect(); connection_.reset(); - onAvailableChanged(false); - if (error) { ClientError clientError; if (boost::shared_ptr actualError = boost::dynamic_pointer_cast(error)) { @@ -233,13 +192,6 @@ void Client::handleNeedCredentials() { session_->sendCredentials(password_); } -bool Client::getStreamManagementEnabled() const { - if (session_) { - return session_->getStreamManagementEnabled(); - } - return false; -} - void Client::handleDataRead(const String& data) { onDataRead(data); } @@ -248,14 +200,18 @@ void Client::handleDataWritten(const String& data) { onDataWritten(data); } -void Client::handleStanzaAcked(boost::shared_ptr stanza) { - onStanzaAcked(stanza); +void Client::handleStanzaChannelAvailableChanged(bool available) { + if (available) { + onConnected(); + } +} + +void Client::sendMessage(boost::shared_ptr message) { + stanzaChannel_->sendMessage(message); } -void Client::handleSessionInitialized() { - jid_ = session_->getLocalJID(); - onConnected(); - onAvailableChanged(true); +void Client::sendPresence(boost::shared_ptr presence) { + stanzaChannel_->sendPresence(presence); } } diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index 5432920..4319eaa 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -18,11 +18,11 @@ #include "Swiften/Elements/Message.h" #include "Swiften/JID/JID.h" #include "Swiften/Base/String.h" -#include "Swiften/Base/IDGenerator.h" #include "Swiften/Client/StanzaChannel.h" #include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h" #include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h" #include "Swiften/Base/Shared.h" +#include "Swiften/Client/ClientSessionStanzaChannel.h" namespace Swift { class IQRouter; @@ -32,7 +32,7 @@ namespace Swift { class ClientSession; class BasicSessionStream; - class Client : public StanzaChannel, public boost::bsignals::trackable { + class Client { public: Client(const JID& jid, const String& password); ~Client(); @@ -44,24 +44,32 @@ namespace Swift { void connect(const String& host); void disconnect(); - bool isAvailable(); - - bool getStreamManagementEnabled() const; - - virtual void sendIQ(boost::shared_ptr); - virtual void sendMessage(boost::shared_ptr); - virtual void sendPresence(boost::shared_ptr); + void sendMessage(boost::shared_ptr); + void sendPresence(boost::shared_ptr); IQRouter* getIQRouter() const { return iqRouter_; } + StanzaChannel* getStanzaChannel() const { + return stanzaChannel_; + } + + bool isAvailable() const { + return stanzaChannel_->isAvailable(); + } + /** * Returns the JID of the client. * After the session was initialized, this returns the bound JID. */ const JID& getJID() const { - return jid_; + if (session_) { + return session_->getLocalJID(); + } + else { + return jid_; + } } public: @@ -70,23 +78,23 @@ namespace Swift { boost::signal onDataRead; boost::signal onDataWritten; + boost::signal)> onMessageReceived; + boost::signal) > onPresenceReceived; + boost::signal)> onStanzaAcked; + private: void handleConnectorFinished(boost::shared_ptr); - void handleSessionInitialized(); - void send(boost::shared_ptr); - virtual String getNewIQID(); - void handleStanza(boost::shared_ptr); + void handleStanzaChannelAvailableChanged(bool available); void handleSessionFinished(boost::shared_ptr); void handleNeedCredentials(); void handleDataRead(const String&); void handleDataWritten(const String&); - void handleStanzaAcked(boost::shared_ptr); private: PlatformDomainNameResolver resolver_; JID jid_; String password_; - IDGenerator idGenerator_; + ClientSessionStanzaChannel* stanzaChannel_; IQRouter* iqRouter_; Connector::ref connector_; ConnectionFactory* connectionFactory_; diff --git a/Swiften/Client/ClientSessionStanzaChannel.cpp b/Swiften/Client/ClientSessionStanzaChannel.cpp new file mode 100644 index 0000000..7656d06 --- /dev/null +++ b/Swiften/Client/ClientSessionStanzaChannel.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Client/ClientSessionStanzaChannel.h" + +#include + +namespace Swift { + +void ClientSessionStanzaChannel::setSession(boost::shared_ptr session) { + assert(!this->session); + this->session = session; + session->onInitialized.connect(boost::bind(&ClientSessionStanzaChannel::handleSessionInitialized, this)); + session->onFinished.connect(boost::bind(&ClientSessionStanzaChannel::handleSessionFinished, this, _1)); + session->onStanzaReceived.connect(boost::bind(&ClientSessionStanzaChannel::handleStanza, this, _1)); + session->onStanzaAcked.connect(boost::bind(&ClientSessionStanzaChannel::handleStanzaAcked, this, _1)); +} + +void ClientSessionStanzaChannel::sendIQ(boost::shared_ptr iq) { + send(iq); +} + +void ClientSessionStanzaChannel::sendMessage(boost::shared_ptr message) { + send(message); +} + +void ClientSessionStanzaChannel::sendPresence(boost::shared_ptr presence) { + send(presence); +} + +String ClientSessionStanzaChannel::getNewIQID() { + return idGenerator.generateID(); +} + +void ClientSessionStanzaChannel::send(boost::shared_ptr stanza) { + if (!isAvailable()) { + std::cerr << "Warning: Client: Trying to send a stanza while disconnected." << std::endl; + return; + } + session->sendStanza(stanza); +} + +void ClientSessionStanzaChannel::handleSessionFinished(boost::shared_ptr error) { + session->onFinished.disconnect(boost::bind(&ClientSessionStanzaChannel::handleSessionFinished, this, _1)); + session->onStanzaReceived.disconnect(boost::bind(&ClientSessionStanzaChannel::handleStanza, this, _1)); + session->onStanzaAcked.disconnect(boost::bind(&ClientSessionStanzaChannel::handleStanzaAcked, this, _1)); + session->onInitialized.disconnect(boost::bind(&ClientSessionStanzaChannel::handleSessionInitialized, this)); + session.reset(); + + onAvailableChanged(false); +} + +void ClientSessionStanzaChannel::handleStanza(boost::shared_ptr stanza) { + boost::shared_ptr message = boost::dynamic_pointer_cast(stanza); + if (message) { + onMessageReceived(message); + return; + } + + boost::shared_ptr presence = boost::dynamic_pointer_cast(stanza); + if (presence) { + onPresenceReceived(presence); + return; + } + + boost::shared_ptr iq = boost::dynamic_pointer_cast(stanza); + if (iq) { + onIQReceived(iq); + return; + } +} + + +bool ClientSessionStanzaChannel::getStreamManagementEnabled() const { + if (session) { + return session->getStreamManagementEnabled(); + } + return false; +} + +void ClientSessionStanzaChannel::handleStanzaAcked(boost::shared_ptr stanza) { + onStanzaAcked(stanza); +} + + +void ClientSessionStanzaChannel::handleSessionInitialized() { + onAvailableChanged(true); +} + +} diff --git a/Swiften/Client/ClientSessionStanzaChannel.h b/Swiften/Client/ClientSessionStanzaChannel.h new file mode 100644 index 0000000..d3fd093 --- /dev/null +++ b/Swiften/Client/ClientSessionStanzaChannel.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include + +#include "Swiften/Base/IDGenerator.h" +#include "Swiften/Client/ClientSession.h" +#include "Swiften/Client/StanzaChannel.h" +#include "Swiften/Elements/Message.h" +#include "Swiften/Elements/IQ.h" +#include "Swiften/Elements/Presence.h" + +namespace Swift { + /** + * StanzaChannel implementation around a ClientSession. + */ + class ClientSessionStanzaChannel : public StanzaChannel { + public: + void setSession(boost::shared_ptr session); + + void sendIQ(boost::shared_ptr iq); + void sendMessage(boost::shared_ptr message); + void sendPresence(boost::shared_ptr presence); + bool getStreamManagementEnabled() const; + + bool isAvailable() const { + return session && session->getState() == ClientSession::Initialized; + } + + private: + String getNewIQID(); + void send(boost::shared_ptr stanza); + void handleSessionFinished(boost::shared_ptr error); + void handleStanza(boost::shared_ptr stanza); + void handleStanzaAcked(boost::shared_ptr stanza); + void handleSessionInitialized(); + + private: + IDGenerator idGenerator; + boost::shared_ptr session; + }; + +} diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h index f13e587..b8ae545 100644 --- a/Swiften/Client/DummyStanzaChannel.h +++ b/Swiften/Client/DummyStanzaChannel.h @@ -40,7 +40,7 @@ namespace Swift { return "test-id"; } - virtual bool isAvailable() { + virtual bool isAvailable() const { return available_; } diff --git a/Swiften/Client/StanzaChannel.h b/Swiften/Client/StanzaChannel.h index f7bb26a..4d6392c 100644 --- a/Swiften/Client/StanzaChannel.h +++ b/Swiften/Client/StanzaChannel.h @@ -18,7 +18,7 @@ namespace Swift { public: virtual void sendMessage(boost::shared_ptr) = 0; virtual void sendPresence(boost::shared_ptr) = 0; - virtual bool isAvailable() = 0; + virtual bool isAvailable() const = 0; virtual bool getStreamManagementEnabled() const = 0; boost::signal onAvailableChanged; diff --git a/Swiften/Queries/DummyIQChannel.h b/Swiften/Queries/DummyIQChannel.h index e327beb..92b7f2b 100644 --- a/Swiften/Queries/DummyIQChannel.h +++ b/Swiften/Queries/DummyIQChannel.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_DummyIQChannel_H -#define SWIFTEN_DummyIQChannel_H +#pragma once #include @@ -24,12 +23,10 @@ namespace Swift { return "test-id"; } - virtual bool isAvailable() { + virtual bool isAvailable() const { return true; } std::vector > iqs_; }; } - -#endif diff --git a/Swiften/Queries/IQChannel.h b/Swiften/Queries/IQChannel.h index 2f18111..e700b51 100644 --- a/Swiften/Queries/IQChannel.h +++ b/Swiften/Queries/IQChannel.h @@ -21,7 +21,7 @@ namespace Swift { virtual void sendIQ(boost::shared_ptr) = 0; virtual String getNewIQID() = 0; - virtual bool isAvailable() = 0; + virtual bool isAvailable() const = 0; boost::signal)> onIQReceived; }; diff --git a/Swiften/SConscript b/Swiften/SConscript index ace9ab7..981b714 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -29,6 +29,7 @@ if env["SCONS_STAGE"] == "build" : "Chat/ChatStateTracker.cpp", "Chat/ChatStateNotifier.cpp", "Chat/ChatStateMessageSender.cpp", + "Client/ClientSessionStanzaChannel.cpp", "Client/Client.cpp", "Client/ClientSession.cpp", "Compress/ZLibCodecompressor.cpp", -- cgit v0.10.2-6-g49f6