浏览代码

Use event queue in linux main

Daniele Bartolini 12 年之前
父节点
当前提交
0c46e709d1
共有 3 个文件被更改,包括 156 次插入66 次删除
  1. 59 28
      engine/EventQueue.h
  2. 76 0
      engine/os/linux/AtomicInt.h
  3. 21 38
      engine/os/linux/main.cpp

+ 59 - 28
engine/EventQueue.h

@@ -27,58 +27,89 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include <cstring>
-#include <stdio.h>
-#include "Mutex.h"
-#include "Queue.h"
-#include "Log.h"
+#include "OsTypes.h"
+#include "AtomicInt.h"
+
+#define QUEUE_SIZE 1024 * 4
 
 namespace crown
 {
 
-/// Represents an abstract queue of events
-class EventQueue
+struct EventQueue
 {
-public:
-
 	//-----------------------------------------------------------------------------
-	EventQueue(Allocator& a)
-		: m_queue(a)
+	EventQueue() 
+		: m_size(0), m_read(0)
 	{
 	}
 
-	//-----------------------------------------------------------------------------
-	void push_event(void* data)
+	int32_t space()
+	{
+		return QUEUE_SIZE - m_size;
+	}
+
+	bool empty()
 	{
-		m_mutex.lock();
-		m_queue.push_back(data);
-		m_mutex.unlock();
+		return m_read == m_size;
 	}
 
 	//-----------------------------------------------------------------------------
-	void* get_event()
+	void push_event(uint32_t event_type, void* event_data, size_t event_size)
 	{
-		m_mutex.lock();
+		int32_t next_size = 4 + 4 + event_size;
+
+		if (next_size >= space())
+		{
+			Log::d("queue full");
+			return;
+		}
+
+		int32_t cur_size = m_size;
+
+		*(&m_buffer[cur_size]) = event_type;
+		*(&m_buffer[cur_size] + 4) = event_size;
+		memcpy(&m_buffer[cur_size] + 8, event_data, event_size);
 
-		void* data;
-		if (m_queue.size() > 0)
+		m_size += next_size;
+	}
+
+	uint32_t event_type()
+	{
+		if (empty())
 		{
-			data = m_queue.front();
-			m_queue.pop_front();
+			return 0;
 		}
-		else
+
+		int32_t cur_read = m_read;
+		uint32_t type = (uint32_t) *(&m_buffer[cur_read]);
+
+		m_read += 4;
+
+		return type;
+	}
+
+	//-----------------------------------------------------------------------------
+	void get_next_event(void* data)
+	{
+		if (empty())
 		{
 			data = NULL;
 		}
 
-		m_mutex.unlock();
+		int32_t cur_read = m_read;
+
+		size_t event_size = (size_t) *(&m_buffer[cur_read]);
+		memcpy(data, &m_buffer[cur_read] + 4, event_size);
 
-		return data;
+		m_read += 4 + event_size;
 	}
 
-public:
+private:
 
-	Mutex m_mutex;
-	Queue<void*> m_queue;
+	char m_buffer[QUEUE_SIZE];
+	
+	AtomicInt m_size;
+	AtomicInt m_read;
 };
 
-} // namespace crown
+} // namespace crown

+ 76 - 0
engine/os/linux/AtomicInt.h

@@ -0,0 +1,76 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Types.h"
+
+namespace crown
+{
+
+struct AtomicInt
+{
+	explicit AtomicInt(int32_t value)
+	{
+		__sync_lock_test_and_set(&m_value, value);
+	}
+
+	AtomicInt& operator+=(int32_t value)
+	{
+		__sync_add_and_fetch(&m_value, value);
+		return *this;
+	}
+
+	AtomicInt& operator++(void)
+	{
+		__sync_add_and_fetch(&m_value, 1);
+		return *this;
+	}
+
+	AtomicInt& operator--(void)
+	{
+		__sync_sub_and_fetch(&m_value, 1);
+		return *this;
+	}
+
+	AtomicInt& operator=(int32_t value)
+	{
+		__sync_lock_test_and_set(&m_value, value);
+		return *this;
+	}
+
+	operator int32_t()
+	{
+		int32_t value = __sync_fetch_and_add(&m_value, 0);
+		return value;
+	}
+
+private:
+
+	int32_t m_value;
+};
+
+} // namespace crown

+ 21 - 38
engine/os/linux/main.cpp

@@ -35,6 +35,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "BundleCompiler.h"
 #include "EventBuffer.h"
 #include "Semaphore.h"
+#include "EventQueue.h"
 
 namespace crown
 {
@@ -137,8 +138,6 @@ public:
 		, m_fullscreen(0)
 		, m_compile(0)
 		, m_continue(0)
-		, m_read(&m_event[0])
-		, m_write(&m_event[1])
 	{
 	}
 
@@ -291,26 +290,23 @@ public:
 	//-----------------------------------------------------------------------------
 	bool process_events()
 	{
-		m_read_sem.wait();
-
-		void* event;
 		uint32_t type;
-		size_t size;
 		do
 		{
-			event = m_read->get_next_event(type, size);
+			type = m_queue.event_type();
 
-			if (event != NULL)
+			if (type != 0)
 			{
 				switch (type)
 				{
 					case OsEvent::MOUSE:
 					{
-						OsMouseEvent* ev = (OsMouseEvent*) event;
-						switch (ev->type)
+						OsMouseEvent ev;
+						m_queue.get_next_event(&ev);
+						switch (ev.type)
 						{
-							case OsMouseEvent::BUTTON: m_mouse->set_button_state(ev->x, ev->y, ev->button, ev->pressed); break;
-							case OsMouseEvent::MOVE: m_mouse->set_position(ev->x, ev->y); break;
+							case OsMouseEvent::BUTTON: m_mouse->set_button_state(ev.x, ev.y, ev.button, ev.pressed); break;
+							case OsMouseEvent::MOVE: m_mouse->set_position(ev.x, ev.y); break;
 							default: CE_FATAL("Oops, unknown mouse event type"); break;
 						}
 
@@ -318,14 +314,16 @@ public:
 					}
 					case OsEvent::KEYBOARD:
 					{
-						OsKeyboardEvent* ev = (OsKeyboardEvent*) event;
-						m_keyboard->set_button_state(ev->button, ev->pressed);
+						OsKeyboardEvent ev;
+						m_queue.get_next_event(&ev);
+						m_keyboard->set_button_state(ev.button, ev.pressed);
 						break;
 					}
 					case OsEvent::METRICS:
 					{
-						OsMetricsEvent* ev = (OsMetricsEvent*) event;
-						m_mouse->set_metrics(ev->width, ev->height);
+						OsMetricsEvent ev;
+						m_queue.get_next_event(&ev);
+						m_mouse->set_metrics(ev.width, ev.height);
 						break;
 					}
 					case OsEvent::EXIT:
@@ -340,10 +338,7 @@ public:
 				}
 			}
 		}
-		while (event != NULL);
-
-		m_read->clear();
-		m_write_sem.post();
+		while (type != 0);
 
 		return false;
 	}
@@ -364,7 +359,7 @@ public:
 					{
 						OsExitEvent ev;
 						ev.code = 0;
-						m_write->push_event(OsEvent::EXIT, &ev, sizeof(OsExitEvent));
+						m_queue.push_event(OsEvent::EXIT, &ev, sizeof(OsExitEvent));
 					}
 					break;
 				}
@@ -381,7 +376,7 @@ public:
 					ev.width = event.xconfigure.width;
 					ev.height = event.xconfigure.height;
 
-					m_write->push_event(OsEvent::METRICS, &ev, sizeof(OsMetricsEvent));
+					m_queue.push_event(OsEvent::METRICS, &ev, sizeof(OsMetricsEvent));
 
 					break;
 				}
@@ -406,7 +401,7 @@ public:
 						ev.x = event.xbutton.x;
 						ev.y = event.xbutton.y;
 						ev.pressed = event.type == ButtonPress;
-						m_write->push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
+						m_queue.push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
 					}
 
 					break;
@@ -418,7 +413,7 @@ public:
 					ev.x = event.xmotion.x;
 					ev.y = event.xmotion.y;
 
-					m_write->push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
+					m_queue.push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
 
 					break;
 				}
@@ -454,7 +449,7 @@ public:
 					ev.modifier = modifier_mask;
 					ev.pressed = event.type == KeyPress;
 
-					m_write->push_event(OsEvent::KEYBOARD, &ev, sizeof(OsKeyboardEvent));
+					m_queue.push_event(OsEvent::KEYBOARD, &ev, sizeof(OsKeyboardEvent));
 
 	//				// Text input part
 	//				if (event.type == KeyPress && len > 0)
@@ -482,13 +477,6 @@ public:
 				}
 			}
 		}
-
-		// Swap event buffers
-		EventBuffer* temp = m_read;
-		m_read = m_write;
-		m_write = temp;
-
-		m_read_sem.post();
 	}
 
 	//-----------------------------------------------------------------------------
@@ -633,12 +621,7 @@ private:
 	int32_t m_compile;
 	int32_t m_continue;
 
-	EventBuffer m_event[2];
-	EventBuffer* m_read;
-	EventBuffer* m_write;
-
-	Semaphore m_read_sem;
-	Semaphore m_write_sem;
+	EventQueue m_queue;
 };
 
 } // namespace crown