From 8231ecc07c1c7d5e260a2795b0660de157501850 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Thu, 12 Nov 2009 20:48:32 +0100
Subject: Created a TimerFactory, and abstracted Timer.


diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 6614bf7..2a6d8a0 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -8,6 +8,7 @@
 #include "Swiften/StreamStack/PlatformTLSLayerFactory.h"
 #include "Swiften/Network/Connector.h"
 #include "Swiften/Network/BoostConnectionFactory.h"
+#include "Swiften/Network/BoostTimerFactory.h"
 #include "Swiften/Network/DomainNameResolveException.h"
 #include "Swiften/TLS/PKCS12Certificate.h"
 #include "Swiften/Session/BasicSessionStream.h"
@@ -17,6 +18,7 @@ namespace Swift {
 Client::Client(const JID& jid, const String& password) :
 		IQRouter(this), jid_(jid), password_(password) {
 	connectionFactory_ = new BoostConnectionFactory(&MainBoostIOServiceThread::getInstance().getIOService());
+	timerFactory_ = new BoostTimerFactory(&MainBoostIOServiceThread::getInstance().getIOService());
 	tlsLayerFactory_ = new PlatformTLSLayerFactory();
 }
 
@@ -25,6 +27,7 @@ Client::~Client() {
 		std::cerr << "Warning: Client not disconnected properly" << std::endl;
 	}
 	delete tlsLayerFactory_;
+	delete timerFactory_;
 	delete connectionFactory_;
 }
 
@@ -50,7 +53,7 @@ void Client::handleConnectorFinished(boost::shared_ptr<Connection> connection) {
 		connection_ = connection;
 
 		assert(!sessionStream_);
-		sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(connection_, &payloadParserFactories_, &payloadSerializers_, tlsLayerFactory_));
+		sessionStream_ = boost::shared_ptr<BasicSessionStream>(new BasicSessionStream(connection_, &payloadParserFactories_, &payloadSerializers_, tlsLayerFactory_, timerFactory_));
 		if (!certificate_.isEmpty()) {
 			sessionStream_->setTLSCertificate(PKCS12Certificate(certificate_, password_));
 		}
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index f09c916..444c136 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -1,5 +1,4 @@
-#ifndef SWIFTEN_Client_H
-#define SWIFTEN_Client_H
+#pragma once
 
 #include <boost/signals.hpp>
 #include <boost/shared_ptr.hpp>
@@ -21,6 +20,7 @@
 namespace Swift {
 	class TLSLayerFactory;
 	class ConnectionFactory;
+	class TimerFactory;
 	class ClientSession;
 	class BasicSessionStream;
 	class Connector;
@@ -66,6 +66,7 @@ namespace Swift {
 			IDGenerator idGenerator_;
 			boost::shared_ptr<Connector> connector_;
 			ConnectionFactory* connectionFactory_;
+			TimerFactory* timerFactory_;
 			TLSLayerFactory* tlsLayerFactory_;
 			FullPayloadParserFactoryCollection payloadParserFactories_;
 			FullPayloadSerializerCollection payloadSerializers_;
@@ -75,5 +76,3 @@ namespace Swift {
 			String certificate_;
 	};
 }
-
-#endif
diff --git a/Swiften/Network/BoostTimer.cpp b/Swiften/Network/BoostTimer.cpp
new file mode 100644
index 0000000..fdbd45d
--- /dev/null
+++ b/Swiften/Network/BoostTimer.cpp
@@ -0,0 +1,34 @@
+#include "Swiften/Network/BoostTimer.h"
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/asio.hpp>
+
+#include "Swiften/EventLoop/MainEventLoop.h"
+
+namespace Swift {
+
+BoostTimer::BoostTimer(int milliseconds, boost::asio::io_service* service) :
+		timeout(milliseconds), timer(*service) {
+}
+
+void BoostTimer::start() {
+	timer.expires_from_now(boost::posix_time::milliseconds(timeout));
+	timer.async_wait(boost::bind(&BoostTimer::handleTimerTick, shared_from_this(), boost::asio::placeholders::error));
+}
+
+void BoostTimer::stop() {
+	timer.cancel();
+}
+
+void BoostTimer::handleTimerTick(const boost::system::error_code& error) {
+	if (error) {
+		assert(error == boost::asio::error::operation_aborted);
+	}
+	else {
+		MainEventLoop::postEvent(boost::bind(boost::ref(onTick)), shared_from_this());
+		timer.expires_from_now(boost::posix_time::milliseconds(timeout));
+		timer.async_wait(boost::bind(&BoostTimer::handleTimerTick, shared_from_this(), boost::asio::placeholders::error));
+	}
+}
+
+}
diff --git a/Swiften/Network/BoostTimer.h b/Swiften/Network/BoostTimer.h
new file mode 100644
index 0000000..9b27cf9
--- /dev/null
+++ b/Swiften/Network/BoostTimer.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#include "Swiften/EventLoop/EventOwner.h"
+#include "Swiften/Network/Timer.h"
+
+namespace Swift {
+	class BoostTimer : public Timer, public EventOwner, public boost::enable_shared_from_this<BoostTimer> {
+		public:
+			BoostTimer(int milliseconds, boost::asio::io_service* service);
+
+			virtual void start();
+			virtual void stop();
+
+		private:
+			void handleTimerTick(const boost::system::error_code& error);
+
+		private:
+			int timeout;
+			boost::asio::deadline_timer timer;
+	};
+}
diff --git a/Swiften/Network/BoostTimerFactory.cpp b/Swiften/Network/BoostTimerFactory.cpp
new file mode 100644
index 0000000..bbcd83f
--- /dev/null
+++ b/Swiften/Network/BoostTimerFactory.cpp
@@ -0,0 +1,13 @@
+#include "Swiften/Network/BoostTimerFactory.h"
+#include "Swiften/Network/BoostTimer.h"
+
+namespace Swift {
+
+BoostTimerFactory::BoostTimerFactory(boost::asio::io_service* ioService) : ioService(ioService) {
+}
+
+boost::shared_ptr<Timer> BoostTimerFactory::createTimer(int milliseconds) {
+	return boost::shared_ptr<Timer>(new BoostTimer(milliseconds, ioService));
+}
+
+}
diff --git a/Swiften/Network/BoostTimerFactory.h b/Swiften/Network/BoostTimerFactory.h
new file mode 100644
index 0000000..e98c9de
--- /dev/null
+++ b/Swiften/Network/BoostTimerFactory.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <boost/asio.hpp>
+
+#include "Swiften/Network/TimerFactory.h"
+#include "Swiften/Network/BoostTimer.h"
+
+namespace Swift {
+	class BoostTimer;
+
+	class BoostTimerFactory : public TimerFactory {
+		public:
+			BoostTimerFactory(boost::asio::io_service*);
+
+			virtual boost::shared_ptr<Timer> createTimer(int milliseconds);
+
+		private:
+			boost::asio::io_service* ioService;
+	};
+}
diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript
index 652bda1..475d6e4 100644
--- a/Swiften/Network/SConscript
+++ b/Swiften/Network/SConscript
@@ -12,10 +12,13 @@ objects = myenv.StaticObject([
 			"ConnectionFactory.cpp",
 			"ConnectionServer.cpp",
       "Connector.cpp",
+			"TimerFactory.cpp",
+			"BoostTimerFactory.cpp",
 			"DomainNameResolver.cpp",
 			"PlatformDomainNameResolver.cpp",
 			"StaticDomainNameResolver.cpp",
 			"HostAddress.cpp",
 			"Timer.cpp",
+			"BoostTimer.cpp",
 		])
 swiften_env.Append(SWIFTEN_OBJECTS = [objects])
diff --git a/Swiften/Network/Timer.cpp b/Swiften/Network/Timer.cpp
index d6120e3..a8d17c3 100644
--- a/Swiften/Network/Timer.cpp
+++ b/Swiften/Network/Timer.cpp
@@ -1,37 +1,8 @@
 #include "Swiften/Network/Timer.h"
 
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-#include "Swiften/EventLoop/MainEventLoop.h"
-
 namespace Swift {
 
-Timer::Timer(int milliseconds, boost::asio::io_service* service) :
-		timeout(milliseconds), timer(*service) {
-}
-
 Timer::~Timer() {
-	stop();
-}
-
-void Timer::start() {
-	timer.expires_from_now(boost::posix_time::milliseconds(timeout));
-	timer.async_wait(boost::bind(&Timer::handleTimerTick, shared_from_this(), boost::asio::placeholders::error));
-}
-
-void Timer::stop() {
-	timer.cancel();
-}
-
-void Timer::handleTimerTick(const boost::system::error_code& error) {
-	if (error) {
-		assert(error == boost::asio::error::operation_aborted);
-	}
-	else {
-		MainEventLoop::postEvent(boost::bind(boost::ref(onTick)), shared_from_this());
-		timer.expires_from_now(boost::posix_time::milliseconds(timeout));
-		timer.async_wait(boost::bind(&Timer::handleTimerTick, shared_from_this(), boost::asio::placeholders::error));
-	}
 }
 
 }
diff --git a/Swiften/Network/Timer.h b/Swiften/Network/Timer.h
index 6474fe9..9b01a0d 100644
--- a/Swiften/Network/Timer.h
+++ b/Swiften/Network/Timer.h
@@ -1,29 +1,15 @@
 #pragma once
 
-#include <boost/asio.hpp>
 #include <boost/signals.hpp>
-#include <boost/thread.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#include "Swiften/EventLoop/EventOwner.h"
 
 namespace Swift {
-	class Timer : public EventOwner, public boost::enable_shared_from_this<Timer> {
+	class Timer {
 		public:
-			Timer(int milliseconds, boost::asio::io_service* service);
-			~Timer();
+			virtual ~Timer();
 
-			void start();
-			void stop();
+			virtual void start() = 0;
+			virtual void stop() = 0;
 
-		public:
 			boost::signal<void ()> onTick;
-
-		private:
-			void handleTimerTick(const boost::system::error_code& error);
-
-		private:
-			int timeout;
-			boost::asio::deadline_timer timer;
 	};
 }
diff --git a/Swiften/Network/TimerFactory.cpp b/Swiften/Network/TimerFactory.cpp
new file mode 100644
index 0000000..642ac52
--- /dev/null
+++ b/Swiften/Network/TimerFactory.cpp
@@ -0,0 +1,8 @@
+#include "Swiften/Network/TimerFactory.h"
+
+namespace Swift {
+
+TimerFactory::~TimerFactory() {
+}
+
+}
diff --git a/Swiften/Network/TimerFactory.h b/Swiften/Network/TimerFactory.h
new file mode 100644
index 0000000..f72a8fc
--- /dev/null
+++ b/Swiften/Network/TimerFactory.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+namespace Swift {
+	class Timer;
+
+	class TimerFactory {
+		public:
+			virtual ~TimerFactory();
+
+			virtual boost::shared_ptr<Timer> createTimer(int milliseconds) = 0;
+	};
+}
diff --git a/Swiften/QA/ClientTest/ClientTest.cpp b/Swiften/QA/ClientTest/ClientTest.cpp
index cf1c161..74ec908 100644
--- a/Swiften/QA/ClientTest/ClientTest.cpp
+++ b/Swiften/QA/ClientTest/ClientTest.cpp
@@ -2,7 +2,7 @@
 #include <boost/thread.hpp>
 
 #include "Swiften/Client/Client.h"
-#include "Swiften/Network/Timer.h"
+#include "Swiften/Network/BoostTimer.h"
 #include "Swiften/EventLoop/MainEventLoop.h"
 #include "Swiften/EventLoop/SimpleEventLoop.h"
 #include "Swiften/Queries/Requests/GetRosterRequest.h"
@@ -55,7 +55,7 @@ int main(int, char**) {
 	client->connect();
 
 	{
-		boost::shared_ptr<Timer> timer(new Timer(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
+		boost::shared_ptr<BoostTimer> timer(new BoostTimer(30000, &MainBoostIOServiceThread::getInstance().getIOService()));
 		timer->onTick.connect(boost::bind(&SimpleEventLoop::stop, &eventLoop));
 		timer->start();
 
diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp
index a9a3cb0..0d0f49f 100644
--- a/Swiften/Session/BasicSessionStream.cpp
+++ b/Swiften/Session/BasicSessionStream.cpp
@@ -11,7 +11,7 @@
 
 namespace Swift {
 
-BasicSessionStream::BasicSessionStream(boost::shared_ptr<Connection> connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, TLSLayerFactory* tlsLayerFactory) : available(false), connection(connection), payloadParserFactories(payloadParserFactories), payloadSerializers(payloadSerializers), tlsLayerFactory(tlsLayerFactory) {
+BasicSessionStream::BasicSessionStream(boost::shared_ptr<Connection> connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, TLSLayerFactory* tlsLayerFactory, TimerFactory* timerFactory) : available(false), connection(connection), payloadParserFactories(payloadParserFactories), payloadSerializers(payloadSerializers), tlsLayerFactory(tlsLayerFactory), timerFactory(timerFactory) {
 }
 
 void BasicSessionStream::initialize() {
@@ -77,7 +77,7 @@ void BasicSessionStream::addTLSEncryption() {
 void BasicSessionStream::setWhitespacePingEnabled(bool enabled) {
 	if (enabled) {
 		if (!whitespacePingLayer) {
-			whitespacePingLayer = boost::shared_ptr<WhitespacePingLayer>(new WhitespacePingLayer());
+			whitespacePingLayer = boost::shared_ptr<WhitespacePingLayer>(new WhitespacePingLayer(timerFactory));
 			streamStack->addLayer(whitespacePingLayer);
 		}
 		whitespacePingLayer->setActive();
diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h
index 07bae81..f36df83 100644
--- a/Swiften/Session/BasicSessionStream.h
+++ b/Swiften/Session/BasicSessionStream.h
@@ -9,6 +9,7 @@
 namespace Swift {
 	class TLSLayerFactory;
 	class TLSLayer;
+	class TimerFactory;
 	class WhitespacePingLayer;
 	class PayloadParserFactoryCollection;
 	class PayloadSerializerCollection;
@@ -24,7 +25,8 @@ namespace Swift {
 				boost::shared_ptr<Connection> connection,
 				PayloadParserFactoryCollection* payloadParserFactories, 
 				PayloadSerializerCollection* payloadSerializers,
-				TLSLayerFactory* tlsLayerFactory
+				TLSLayerFactory* tlsLayerFactory,
+				TimerFactory* whitespacePingLayerFactory
 			);
 			~BasicSessionStream();
 
@@ -59,6 +61,7 @@ namespace Swift {
 			PayloadParserFactoryCollection* payloadParserFactories;
 			PayloadSerializerCollection* payloadSerializers;
 			TLSLayerFactory* tlsLayerFactory;
+			TimerFactory* timerFactory;
 			boost::shared_ptr<XMPPLayer> xmppLayer;
 			boost::shared_ptr<ConnectionLayer> connectionLayer;
 			StreamStack* streamStack;
diff --git a/Swiften/StreamStack/WhitespacePingLayer.cpp b/Swiften/StreamStack/WhitespacePingLayer.cpp
index 939c4fa..5c1eb00 100644
--- a/Swiften/StreamStack/WhitespacePingLayer.cpp
+++ b/Swiften/StreamStack/WhitespacePingLayer.cpp
@@ -1,16 +1,16 @@
 #include "Swiften/StreamStack/WhitespacePingLayer.h"
 
-#include "Swiften/Network/BoostIOServiceThread.h"
-#include "Swiften/Network/MainBoostIOServiceThread.h"
+#include <boost/bind.hpp>
+
+#include "Swiften/Network/TimerFactory.h"
 #include "Swiften/Network/Timer.h"
 
 namespace Swift {
 
 static const int TIMEOUT_MILLISECONDS = 60000;
 
-WhitespacePingLayer::WhitespacePingLayer() : isActive(false) {
-	// FIXME: Create a BoostTimerFactory.
-	timer = boost::shared_ptr<Timer>(new Timer(TIMEOUT_MILLISECONDS, &MainBoostIOServiceThread::getInstance().getIOService()));
+WhitespacePingLayer::WhitespacePingLayer(TimerFactory* timerFactory) : isActive(false) {
+	timer = timerFactory->createTimer(TIMEOUT_MILLISECONDS);
 	timer->onTick.connect(boost::bind(&WhitespacePingLayer::handleTimerTick, this));
 }
 
diff --git a/Swiften/StreamStack/WhitespacePingLayer.h b/Swiften/StreamStack/WhitespacePingLayer.h
index 9d6957b..18ea39a 100644
--- a/Swiften/StreamStack/WhitespacePingLayer.h
+++ b/Swiften/StreamStack/WhitespacePingLayer.h
@@ -7,10 +7,11 @@
 
 namespace Swift {
 	class Timer;
+	class TimerFactory;
 
 	class WhitespacePingLayer : public StreamLayer, boost::noncopyable {
 		public:
-			WhitespacePingLayer();
+			WhitespacePingLayer(TimerFactory* timerFactory);
 
 			void setActive();
 			void setInactive();
-- 
cgit v0.10.2-6-g49f6