Jelajahi Sumber

Thread-safe events, adjustment Matrix for polygon picking

Ivan Safrin 13 tahun lalu
induk
melakukan
6e1940bf25

+ 1 - 0
Core/Contents/CMakeLists.txt

@@ -75,6 +75,7 @@ SET(polycore_SRCS
     Source/PolySoundManager.cpp
     Source/PolySoundManager.cpp
     Source/PolyString.cpp
     Source/PolyString.cpp
     Source/PolyTexture.cpp
     Source/PolyTexture.cpp
+    Source/PolyThreaded.cpp
     Source/PolyTimer.cpp
     Source/PolyTimer.cpp
     Source/PolyTimerManager.cpp
     Source/PolyTimerManager.cpp
     Source/PolyTween.cpp
     Source/PolyTween.cpp

+ 4 - 1
Core/Contents/Include/PolyCore.h

@@ -121,7 +121,7 @@ namespace Polycode {
 		* @param target Target threaded class.
 		* @param target Target threaded class.
 		* @see Threaded
 		* @see Threaded
 		*/		
 		*/		
-		virtual void createThread(Threaded *target) = 0;
+		virtual void createThread(Threaded *target);
 
 
 		/**
 		/**
 		* Locks a mutex.
 		* Locks a mutex.
@@ -338,6 +338,9 @@ namespace Polycode {
 		
 		
 		unsigned int lastSleepFrameTicks;
 		unsigned int lastSleepFrameTicks;
 		
 		
+		std::vector<Threaded*> threads;
+		CoreMutex *threadedEventMutex;
+		
 		int xRes;
 		int xRes;
 		int yRes;	
 		int yRes;	
 		
 		

+ 2 - 0
Core/Contents/Include/PolyEvent.h

@@ -63,6 +63,8 @@ namespace Polycode {
 			
 			
 			static const int COMPLETE_EVENT = 0;
 			static const int COMPLETE_EVENT = 0;
 			static const int CHANGE_EVENT = 1;
 			static const int CHANGE_EVENT = 1;
+			
+			bool deleteOnDispatch;
 						
 						
 		protected:
 		protected:
 			
 			

+ 2 - 2
Core/Contents/Include/PolyEventDispatcher.h

@@ -82,8 +82,8 @@ typedef struct {
 			* @see Event
 			* @see Event
 			* @see EventHandler			
 			* @see EventHandler			
 			*/														
 			*/														
-			void dispatchEvent(Event *event, int eventCode);
-			void dispatchEventNoDelete(Event *event, int eventCode);
+			virtual void dispatchEvent(Event *event, int eventCode);
+			virtual void dispatchEventNoDelete(Event *event, int eventCode);
 		
 		
 		protected:
 		protected:
 	
 	

+ 1 - 1
Core/Contents/Include/PolyRenderer.h

@@ -212,7 +212,7 @@ namespace Polycode {
 		
 		
 		void addShaderModule(PolycodeShaderModule *module);
 		void addShaderModule(PolycodeShaderModule *module);
 		
 		
-		virtual bool test2DCoordinateInPolygon(Number x, Number y, Polygon *poly, const Matrix4 &matrix, bool testBackfacing, bool ortho, bool billboardMode);
+		virtual bool test2DCoordinateInPolygon(Number x, Number y, Polygon *poly, const Matrix4 &matrix, bool testBackfacing, bool ortho, bool billboardMode, Matrix4 *adjustMatrix = NULL);
 		
 		
 		virtual Matrix4 getProjectionMatrix() = 0;
 		virtual Matrix4 getProjectionMatrix() = 0;
 		virtual Matrix4 getModelviewMatrix() = 0;
 		virtual Matrix4 getModelviewMatrix() = 0;

+ 19 - 6
Core/Contents/Include/PolyThreaded.h

@@ -22,8 +22,12 @@ THE SOFTWARE.
 
 
 #pragma once
 #pragma once
 #include "PolyGlobals.h"
 #include "PolyGlobals.h"
+#include "PolyEventDispatcher.h"
 
 
 namespace Polycode{
 namespace Polycode{
+
+	class Core;
+	class CoreMutex;
 	
 	
 	/**
 	/**
 	* An easy way to create threaded processes. If you subclass this class, you can implement the updateThread method, which will be called in its own thread repeatedly until threadRunning is false once the thread is created. If you only need to run through something once, make sure to set threadRunning to avoid it being called again. 
 	* An easy way to create threaded processes. If you subclass this class, you can implement the updateThread method, which will be called in its own thread repeatedly until threadRunning is false once the thread is created. If you only need to run through something once, make sure to set threadRunning to avoid it being called again. 
@@ -31,24 +35,33 @@ namespace Polycode{
 		To create the thread, pass your Threaded subclass to createThread method of Core.
 		To create the thread, pass your Threaded subclass to createThread method of Core.
 		@see Core
 		@see Core
 	*/
 	*/
-	class _PolyExport Threaded {
+	class _PolyExport Threaded : public EventDispatcher {
 	public:
 	public:
-		Threaded(){ threadRunning = true; }
+		Threaded();
 		virtual ~Threaded(){}
 		virtual ~Threaded(){}
 		
 		
 		/**
 		/**
 		* Sets the thread running flag to false.
 		* Sets the thread running flag to false.
 		*/ 
 		*/ 
-		virtual void killThread() { threadRunning = false; }		
-		
-		virtual void runThread(){while(threadRunning) updateThread(); }
+		virtual void killThread();	
+		virtual void runThread();
 		
 		
 		/**
 		/**
 		* Implement this method with your own code.
 		* Implement this method with your own code.
 		*/
 		*/
-		virtual void updateThread() = 0;
+		virtual void updateThread() {};
+		
+		void dispatchEvent(Event *event, int eventCode);		
+		void dispatchEventNoDelete(Event *event, int eventCode);
 		
 		
 		bool threadRunning;
 		bool threadRunning;
+		
+		Core *core;
+		
+		bool scheduledForRemoval;
+		
+		CoreMutex *eventMutex;		
+		std::vector<Event*> eventQueue;
 	};
 	};
 	
 	
 }
 }

+ 2 - 0
Core/Contents/Source/PolyCocoaCore.mm

@@ -262,10 +262,12 @@ CocoaCore::~CocoaCore() {
 void *ManagedThreadFunc(void *data) {
 void *ManagedThreadFunc(void *data) {
 	Threaded *target = static_cast<Threaded*>(data);
 	Threaded *target = static_cast<Threaded*>(data);
 	target->runThread();
 	target->runThread();
+	target->scheduledForRemoval = true;
 	return NULL;
 	return NULL;
 }
 }
 
 
 void CocoaCore::createThread(Threaded *target) {
 void CocoaCore::createThread(Threaded *target) {
+	Core::createThread(target);
 	pthread_t thread;
 	pthread_t thread;
 	pthread_create( &thread, NULL, ManagedThreadFunc, (void*)target);
 	pthread_create( &thread, NULL, ManagedThreadFunc, (void*)target);
 }
 }

+ 35 - 1
Core/Contents/Source/PolyCore.cpp

@@ -67,7 +67,8 @@ namespace Polycode {
 		
 		
 		this->monitorIndex = monitorIndex;
 		this->monitorIndex = monitorIndex;
 		
 		
-		refreshInterval = 1000 / frameRate;
+		refreshInterval = 1000 / frameRate;		
+		threadedEventMutex = NULL;
 	}
 	}
 	
 	
 	void Core::enableMouse(bool newval) {
 	void Core::enableMouse(bool newval) {
@@ -123,6 +124,18 @@ namespace Polycode {
 		setVideoMode(resList[index].w, resList[index].h, fullScreen, vSync, aaLevel, anisotropyLevel);
 		setVideoMode(resList[index].w, resList[index].h, fullScreen, vSync, aaLevel, anisotropyLevel);
 	}
 	}
 	
 	
+	void Core::createThread(Threaded *target) {
+		if(!threadedEventMutex) {
+			threadedEventMutex = createMutex();
+		}
+		target->eventMutex = threadedEventMutex;
+		target->core = this;
+		
+		lockMutex(threadedEventMutex);
+		threads.push_back(target);
+		unlockMutex(threadedEventMutex);			
+	}
+			
 	void Core::updateCore() {
 	void Core::updateCore() {
 		frames++;
 		frames++;
 		frameTicks = getTicks();
 		frameTicks = getTicks();
@@ -139,6 +152,27 @@ namespace Polycode {
 		}
 		}
 		lastFrameTicks = frameTicks;
 		lastFrameTicks = frameTicks;
 		
 		
+		if(threadedEventMutex){ 
+		lockMutex(threadedEventMutex);
+
+		std::vector<Threaded*>::iterator iter = threads.begin();
+		while (iter != threads.end()) {		
+			for(int j=0; j < (*iter)->eventQueue.size(); j++) {
+				Event *event = (*iter)->eventQueue[j];
+				(*iter)->__dispatchEvent(event, event->getEventCode());
+				if(event->deleteOnDispatch)
+					delete event;
+			}
+			(*iter)->eventQueue.clear();
+			if((*iter)->scheduledForRemoval) {
+				iter = threads.erase(iter);
+			} else {
+				++iter;
+			}
+		}
+		
+		unlockMutex(threadedEventMutex);
+		}
 	}
 	}
 	
 	
 	void Core::doSleep() {
 	void Core::doSleep() {

+ 1 - 0
Core/Contents/Source/PolyEvent.cpp

@@ -26,6 +26,7 @@ namespace Polycode {
 	
 	
 	Event::Event() {
 	Event::Event() {
 			eventType = "Event";
 			eventType = "Event";
+			deleteOnDispatch = true;
 	}
 	}
 	
 	
 	Event::Event(int eventCode) {
 	Event::Event(int eventCode) {

+ 5 - 1
Core/Contents/Source/PolyRenderer.cpp

@@ -78,7 +78,7 @@ void Renderer::setExposureLevel(Number level) {
 }
 }
 
 
 
 
-bool Renderer::test2DCoordinateInPolygon(Number x, Number y, Polycode::Polygon *poly, const Matrix4 &matrix, bool ortho, bool testBackfacing, bool billboardMode) {
+bool Renderer::test2DCoordinateInPolygon(Number x, Number y, Polycode::Polygon *poly, const Matrix4 &matrix, bool ortho, bool testBackfacing, bool billboardMode, Matrix4 *adjustMatrix) {
 
 
 	Vector3 dirVec;
 	Vector3 dirVec;
 	Vector3 origin;
 	Vector3 origin;
@@ -118,6 +118,10 @@ bool Renderer::test2DCoordinateInPolygon(Number x, Number y, Polycode::Polygon *
 		dirVec = camInverse.rotateVector(dirVec);
 		dirVec = camInverse.rotateVector(dirVec);
 	}
 	}
 	
 	
+	if(adjustMatrix) {
+			fullMatrix = (*adjustMatrix) * fullMatrix;
+	}	
+		
 	bool retStatus = false;	
 	bool retStatus = false;	
 	
 	
 	
 	

+ 35 - 0
Core/Contents/Source/PolyThreaded.cpp

@@ -0,0 +1,35 @@
+
+#include "PolyThreaded.h"
+#include "PolyCore.h"
+
+using namespace Polycode;
+
+Threaded::Threaded() : EventDispatcher() {
+	threadRunning = true;
+	scheduledForRemoval = false;
+}
+
+void Threaded::killThread() {
+	threadRunning = false;
+}
+
+void Threaded::runThread(){
+	while(threadRunning) {
+		updateThread();
+	}
+}
+
+void Threaded::dispatchEvent(Event *event, int eventCode) {
+	core->lockMutex(eventMutex);
+	event->setEventCode(eventCode);
+	eventQueue.push_back(event);
+	core->unlockMutex(eventMutex);	
+}
+		
+void Threaded::dispatchEventNoDelete(Event *event, int eventCode) {
+	core->lockMutex(eventMutex);
+	event->setEventCode(eventCode);
+	event->deleteOnDispatch = false;
+	eventQueue.push_back(event);	
+	core->unlockMutex(eventMutex);			
+}

+ 2 - 0
Modules/Contents/3DPhysics/Include/PolyPhysicsSceneEntity.h

@@ -50,6 +50,8 @@ namespace Polycode {
 		void setFriction(Number friction);		
 		void setFriction(Number friction);		
 		int getType() { return type; }	
 		int getType() { return type; }	
 		
 		
+		void setMass(Number mass);
+		
 			void setVelocity(Vector3 velocity);
 			void setVelocity(Vector3 velocity);
 			void warpTo(Vector3 position, bool resetRotation);
 			void warpTo(Vector3 position, bool resetRotation);
 			
 			

+ 4 - 0
Modules/Contents/3DPhysics/Source/PolyPhysicsSceneEntity.cpp

@@ -223,6 +223,10 @@ void PhysicsSceneEntity::setFriction(Number friction) {
 		rigidBody->setFriction(friction);
 		rigidBody->setFriction(friction);
 }
 }
 
 
+void PhysicsSceneEntity::setMass(Number mass) {
+	rigidBody->setMassProps(mass, btVector3(0.0, 0.0, 0.0));
+}
+
 void PhysicsSceneEntity::Update() {		
 void PhysicsSceneEntity::Update() {		
 	Matrix4 m;
 	Matrix4 m;
 		
 		

+ 5 - 3
Modules/Contents/Curl/PolycodeDownloader.cpp

@@ -23,11 +23,13 @@ String PolycodeDownloader::getDataAsString() {
 	return ret;
 	return ret;
 }
 }
 		
 		
-PolycodeDownloader::PolycodeDownloader(String url) {
-	
+PolycodeDownloader::PolycodeDownloader(String url) : Threaded() {
+	this->url = url;
 	data = (char*)malloc(0);
 	data = (char*)malloc(0);
 	size = 0;
 	size = 0;
-	
+}
+
+void PolycodeDownloader::runThread() {
 	curl = curl_easy_init();
 	curl = curl_easy_init();
 		
 		
 	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());	
 	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());	

+ 5 - 2
Modules/Contents/Curl/PolycodeDownloader.h

@@ -1,20 +1,23 @@
+#pragma once
 
 
 #include <Polycode.h>
 #include <Polycode.h>
 #include <curl/curl.h>
 #include <curl/curl.h>
 
 
 using namespace Polycode;
 using namespace Polycode;
 
 
-class PolycodeDownloader : public EventDispatcher {
+class PolycodeDownloader : public Threaded {
 	public:
 	public:
 		PolycodeDownloader(String url);
 		PolycodeDownloader(String url);
 		~PolycodeDownloader();		
 		~PolycodeDownloader();		
 		
 		
+		void runThread();
+		
 		String getDataAsString();
 		String getDataAsString();
 		
 		
 		char *data;
 		char *data;
 		size_t size;
 		size_t size;
 				
 				
 	protected:
 	protected:
-		
+		String url;		
 		CURL *curl;
 		CURL *curl;
 };
 };

+ 1 - 1
Modules/Contents/Networking/Include/PolyPeer.h

@@ -70,7 +70,7 @@ namespace Polycode {
 		Address address;
 		Address address;
 	};
 	};
 		
 		
-	class _PolyExport Peer : public Threaded, public EventDispatcher {
+	class _PolyExport Peer : public Threaded {
 		public:
 		public:
 			Peer(unsigned int port);
 			Peer(unsigned int port);
 			~Peer();
 			~Peer();

+ 1 - 1
Modules/Contents/Networking/Source/PolyPeer.cpp

@@ -36,7 +36,7 @@ void PeerConnection::ackPackets(unsigned int ack) {
 	}
 	}
 }
 }
 
 
-Peer::Peer(unsigned int port) : EventDispatcher(), Threaded() {
+Peer::Peer(unsigned int port) : Threaded() {
 	socket = new Socket(port);
 	socket = new Socket(port);
 	socket->addEventListener(this, SocketEvent::EVENT_DATA_RECEIVED);
 	socket->addEventListener(this, SocketEvent::EVENT_DATA_RECEIVED);