Explorar el Código

Different Event prototype, one that allows std::bind

Marko Pintera hace 11 años
padre
commit
9c37abbdc3
Se han modificado 2 ficheros con 65 adiciones y 99 borrados
  1. 2 2
      BansheeEditor/Source/BsEditorApplication.cpp
  2. 63 97
      CamelotUtility/Include/BsEvent.h

+ 2 - 2
BansheeEditor/Source/BsEditorApplication.cpp

@@ -59,9 +59,9 @@ namespace BansheeEngine
 
 		TmpClass instance;
 		Event<void (int)> myEvent;
-		myEvent += delegate(&instance, &TmpClass::someMEthod);
-		myEvent -= delegate(&instance, &TmpClass::someMEthod);
+		HEvent evSomeMethod = myEvent.connect(std::bind(&TmpClass::someMEthod, instance, std::placeholders::_1));
 
+		evSomeMethod.disconnect();
 		myEvent(5);
 
 		// END DEBUG

+ 63 - 97
CamelotUtility/Include/BsEvent.h

@@ -6,145 +6,111 @@
 namespace BansheeEngine
 {
 	/************************************************************************/
-	/* 							ABSTRACT DELEGATE	                      	*/
-	/************************************************************************/
-
-	// 1 parameter
-	template <class P0, class RetType>
-	class Delegate1Abstract
-	{
-	public:
-		virtual RetType call(P0 p0) = 0;
-		virtual bool equals(const Delegate1Abstract<P0, RetType>& other) = 0;
-	};
-
-	/************************************************************************/
-	/* 						MEMBER FUNCTION DELEGATE                   		*/
+	/* 								EVENTS									*/
 	/************************************************************************/
-
-	// 1 parameter
-	template <class X, class Y, class P0, class RetType>
-	class Delegate1Member : public Delegate1Abstract<P0, RetType>
+	
+	class HEvent
 	{
 	public:
-		Delegate1Member(Y* instance, RetType (X::*func)(P0))
-			:mInstance(instance), mFunc(func)
+		HEvent(void* connection, void* event, void (*disconnectCallback) (void*, void*))
+			:mConnection(connection), mEvent(event), mDisconnectCallback(disconnectCallback)
 		{ }
 
-		RetType call(P0 p0)
+		void disconnect()
 		{
-			(mInstance->*mFunc)(p0);
-		}
-
-		bool equals(const Delegate1Abstract<P0, RetType>& other)
-		{
-			const Delegate1Member<X, Y, P0, RetType>& otherMemberDelegate = 
-				reinterpret_cast<const Delegate1Member<X, Y, P0, RetType>&>(other);
-
-			return otherMemberDelegate.mInstance == mInstance && otherMemberDelegate.mFunc == mFunc;
+			mDisconnectCallback(mConnection, mEvent);
 		}
 
 	private:
-		X* mInstance;
-		RetType (X::*mFunc)(P0);
-	};
-
-	template <class X, class Y, class P0, class RetType>
-	std::shared_ptr<Delegate1Member<X, Y, P0, RetType>> delegate(Y* instance, RetType (X::*func)(P0))
-	{
-		return cm_shared_ptr<Delegate1Member<X, Y, P0, RetType>>(instance, func);
-	}
-
-	/************************************************************************/
-	/* 							FUNCTION DELEGATE                      		*/
-	/************************************************************************/
+		void (*mDisconnectCallback) (void*, void*);
+		void* mConnection;
+		void* mEvent;
+	};	
 
 	// 1 parameter
 	template <class P0, class RetType>
-	class Delegate1Function : public Delegate1Abstract<P0, RetType>
+	class Event1
 	{
-	public:
-		Delegate1Function(RetType (*func)(P0))
-			:mInstance(instance), mFunc(func)
-		{ }
-
-		RetType call(P0 p0)
+		struct ConnectionData
 		{
-			(*mFunc)(p0);
-		}
+		public:
+			ConnectionData(std::function<RetType(P0)> func)
+				:func(func)
+			{ }
 
-		bool equals(const Delegate1Abstract<P0, RetType>& other)
-		{
-			const Delegate1Function<P0, RetType>& otherFunctionDelegate = 
-				reinterpret_cast<const Delegate1Function<P0, RetType>&>(other);
+			std::function<RetType(P0)> func;
+		};
 
-			return otherMemberDelegate.mFunc == mFunc;
-		}
-
-	private:
-		RetType (*mFunc)(P0);
-	};
-
-	template <class P0, class RetType>
-	std::shared_ptr<Delegate1Function<P0, RetType>> delegate(RetType (*func)(P0))
-	{
-		return cm_shared_ptr<Delegate1Function<P0, RetType>>(func);
-	}	
-
-	/************************************************************************/
-	/* 								EVENTS									*/
-	/************************************************************************/
-	
-	// 1 parameter
-	template <class P0, class RetType>
-	class Event1
-	{
-		typedef Delegate1Abstract<P0, RetType> TDelegate;
-		typedef std::shared_ptr<TDelegate> TDelegatePtr;
 	public:
-		void operator+= (const TDelegatePtr& delegate)
+		~Event1()
 		{
-			// TODO - Lock
-
-			mDelegates.push_back(delegate);
+			clear();
 		}
 
-		void operator-= (const TDelegatePtr& delegate)
+		HEvent connect(std::function<RetType(P0)> func)
 		{
 			// TODO - Lock
 
-			for(auto& iter = mDelegates.begin(); iter != mDelegates.end(); ++iter)
-			{
-				if((*iter)->equals(*delegate))
-				{
-					mDelegates.erase(iter);
-					return;
-				}
-			}
+			ConnectionData* connData = cm_new<ConnectionData>(func);
+			mConnections.push_back(connData);
+
+			return HEvent(connData, this, &Event1::disconnectCallback);
 		}
 
 		void operator() (P0 args)
 		{
 			// TODO - Lock each call separately using a spin lock
 
-			for(auto& delegate : mDelegates)
-				delegate->call(args);
+			for(auto& connection : mConnections)
+				connection->func(args);
 		}
 
 		void clear()
 		{
 			// TODO - Lock
-			mDelegates.clear();
+			
+			for(auto& connection : mConnections)
+			{
+				cm_delete(connection);
+			}
+
+			mConnections.clear();
 		}
 
 		bool empty()
 		{
 			// TODO - Lock
-			return mDelegates.size() == 0;
+			return mConnections.size() == 0;
 		}
 
 	private:
-		typename Vector<TDelegatePtr>::type mDelegates;
+		friend class EventHandle1;
+
+		typename Vector<ConnectionData*>::type mConnections;
+
+		static void disconnectCallback(void* connection, void* event)
+		{
+			Event1<P0, RetType>::ConnectionData* castConnection = 
+				reinterpret_cast<Event1<P0, RetType>::ConnectionData*>(connection);
+			Event1<P0, RetType>* castEvent = reinterpret_cast<Event1<P0, RetType>*>(event);
+
+			castEvent->disconnect(castConnection);
+		}
+
+		void disconnect(ConnectionData* connData)
+		{
+			// TODO - Lock
+
+			for(auto& iter = mConnections.begin(); iter != mConnections.end(); ++iter)
+			{
+				if((*iter) == connData)
+				{
+					cm_delete(connData);
+					mConnections.erase(iter);
+					return;
+				}
+			}
+		}
 	};
 
 	/************************************************************************/