Kaynağa Gözat

Fix os event queue

Daniele Bartolini 12 yıl önce
ebeveyn
işleme
79cd4ae246

+ 0 - 115
engine/EventQueue.h

@@ -1,115 +0,0 @@
-/*
-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 <cstring>
-#include "OsTypes.h"
-#include "AtomicInt.h"
-
-#define QUEUE_SIZE 1024 * 4
-
-namespace crown
-{
-
-struct EventQueue
-{
-	//-----------------------------------------------------------------------------
-	EventQueue() 
-		: m_size(0), m_read(0)
-	{
-	}
-
-	int32_t space()
-	{
-		return QUEUE_SIZE - m_size;
-	}
-
-	bool empty()
-	{
-		return m_read == m_size;
-	}
-
-	//-----------------------------------------------------------------------------
-	void push_event(uint32_t event_type, void* event_data, size_t event_size)
-	{
-		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);
-
-		m_size += next_size;
-	}
-
-	uint32_t event_type()
-	{
-		if (empty())
-		{
-			return 0;
-		}
-
-		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;
-		}
-
-		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);
-
-		m_read += 4 + event_size;
-	}
-
-private:
-
-	char m_buffer[QUEUE_SIZE];
-	
-	AtomicInt m_size;
-	AtomicInt m_read;
-};
-
-} // namespace crown

+ 142 - 0
engine/os/OsEventQueue.h

@@ -0,0 +1,142 @@
+/*
+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 <cstring>
+#include "Queue.h"
+#include "Mutex.h"
+#include "ProxyAllocator.h"
+#include "OsTypes.h"
+
+namespace crown
+{
+
+struct OsEventQueue
+{
+	//-----------------------------------------------------------------------------
+	OsEventQueue() 
+		: m_allocator("os-event-queue", default_allocator()), m_queue(m_allocator)
+	{
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_mouse_event(uint16_t x, uint16_t y)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::MOUSE;
+		ev.mouse.type = OsMouseEvent::MOVE;
+		ev.mouse.x = x;
+		ev.mouse.y = y;
+
+		push_event(&ev);
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_mouse_event(uint16_t x, uint16_t y, MouseButton::Enum b, bool pressed)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::MOUSE;
+		ev.mouse.type = OsMouseEvent::BUTTON;
+		ev.mouse.x = x;
+		ev.mouse.y = y;
+		ev.mouse.button = b;
+		ev.mouse.pressed = pressed;
+
+		push_event(&ev);
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_keyboard_event(uint32_t modifier, KeyboardButton::Enum b, bool pressed)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::KEYBOARD;
+		ev.keyboard.button = b;
+		ev.keyboard.modifier = modifier;
+		ev.keyboard.pressed = pressed;
+
+		push_event(&ev);
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_exit_event(int32_t code)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::EXIT;
+		ev.exit.code = code;
+
+		push_event(&ev);
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_metrics_event(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
+	{
+		OsEvent ev;
+		ev.type = OsEvent::METRICS;
+		ev.metrics.x = x;
+		ev.metrics.y = y;
+		ev.metrics.width = width;
+		ev.metrics.height = height;
+
+		push_event(&ev);
+	}
+
+	//-----------------------------------------------------------------------------
+	void push_event(OsEvent* ev)
+	{
+		CE_ASSERT_NOT_NULL(ev);
+
+		m_mutex.lock();
+		m_queue.push(ev, sizeof(OsEvent));
+		m_mutex.unlock();
+	}
+
+	//-----------------------------------------------------------------------------
+	void pop_event(OsEvent* ev)
+	{
+		CE_ASSERT_NOT_NULL(ev);
+
+		m_mutex.lock();
+		if (m_queue.size() > 0)
+		{
+			memcpy(ev, m_queue.begin(), sizeof(OsEvent));
+			m_queue.pop(sizeof(OsEvent));
+		}
+		else
+		{
+			ev->type = OsEvent::NONE;
+		}
+		m_mutex.unlock();
+	}
+
+private:
+
+	ProxyAllocator m_allocator;
+	Queue<OsEvent> m_queue;
+	Mutex m_mutex;
+};
+
+} // namespace crown

+ 11 - 0
engine/os/OsTypes.h

@@ -100,6 +100,17 @@ struct OsEvent
 		// Exit from program
 		EXIT
 	};
+
+	OsEvent::Enum type;
+	union
+	{
+		OsMetricsEvent metrics;
+		OsExitEvent exit;
+		OsMouseEvent mouse;
+		OsKeyboardEvent keyboard;
+		OsTouchEvent touch;
+		OsAccelerometerEvent accelerometer;
+	};
 };
 
 } // namespace crown

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

@@ -1,76 +0,0 @@
-/*
-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

+ 17 - 48
engine/os/linux/main.cpp

@@ -28,14 +28,12 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
 #include <X11/XKBlib.h>
+#include "Config.h"
 #include "Crown.h"
 #include "Device.h"
 #include "OsTypes.h"
-#include "Config.h"
+#include "OsEventQueue.h"
 #include "BundleCompiler.h"
-#include "EventBuffer.h"
-#include "Semaphore.h"
-#include "EventQueue.h"
 
 namespace crown
 {
@@ -290,19 +288,18 @@ public:
 	//-----------------------------------------------------------------------------
 	bool process_events()
 	{
-		uint32_t type;
+		OsEvent event;
 		do
 		{
-			type = m_queue.event_type();
+			m_queue.pop_event(&event);
 
-			if (type != 0)
+			if (event.type != OsEvent::NONE)
 			{
-				switch (type)
+				switch (event.type)
 				{
 					case OsEvent::MOUSE:
 					{
-						OsMouseEvent ev;
-						m_queue.get_next_event(&ev);
+						const OsMouseEvent& ev = event.mouse;
 						switch (ev.type)
 						{
 							case OsMouseEvent::BUTTON: m_mouse->set_button_state(ev.x, ev.y, ev.button, ev.pressed); break;
@@ -314,15 +311,13 @@ public:
 					}
 					case OsEvent::KEYBOARD:
 					{
-						OsKeyboardEvent ev;
-						m_queue.get_next_event(&ev);
+						const OsKeyboardEvent& ev = event.keyboard;
 						m_keyboard->set_button_state(ev.button, ev.pressed);
 						break;
 					}
 					case OsEvent::METRICS:
 					{
-						OsMetricsEvent ev;
-						m_queue.get_next_event(&ev);
+						const OsMetricsEvent& ev = event.metrics;
 						m_mouse->set_metrics(ev.width, ev.height);
 						break;
 					}
@@ -338,7 +333,7 @@ public:
 				}
 			}
 		}
-		while (type != 0);
+		while (event.type != OsEvent::NONE);
 
 		return false;
 	}
@@ -357,9 +352,7 @@ public:
 				{
 					if ((Atom)event.xclient.data.l[0] == m_wm_delete_message)
 					{
-						OsExitEvent ev;
-						ev.code = 0;
-						m_queue.push_event(OsEvent::EXIT, &ev, sizeof(OsExitEvent));
+						m_queue.push_exit_event(0);
 					}
 					break;
 				}
@@ -370,21 +363,14 @@ public:
 					m_width = event.xconfigure.width;
 					m_height = event.xconfigure.height;
 
-					OsMetricsEvent ev;
-					ev.x = event.xconfigure.x;
-					ev.y = event.xconfigure.y;
-					ev.width = event.xconfigure.width;
-					ev.height = event.xconfigure.height;
-
-					m_queue.push_event(OsEvent::METRICS, &ev, sizeof(OsMetricsEvent));
+					m_queue.push_metrics_event(event.xconfigure.x, event.xconfigure.y,
+												event.xconfigure.width, event.xconfigure.height);
 
 					break;
 				}
 				case ButtonPress:
 				case ButtonRelease:
 				{
-					OsMouseEvent ev;
-
 					MouseButton::Enum mb;
 					switch (event.xbutton.button)
 					{
@@ -396,25 +382,14 @@ public:
 
 					if (mb != MouseButton::NONE)
 					{
-						ev.type = OsMouseEvent::BUTTON;
-						ev.button = mb;
-						ev.x = event.xbutton.x;
-						ev.y = event.xbutton.y;
-						ev.pressed = event.type == ButtonPress;
-						m_queue.push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
+						m_queue.push_mouse_event(event.xbutton.x, event.xbutton.y, mb, event.type == ButtonPress);
 					}
 
 					break;
 				}
 				case MotionNotify:
 				{
-					OsMouseEvent ev;
-					ev.type = OsMouseEvent::MOVE;
-					ev.x = event.xmotion.x;
-					ev.y = event.xmotion.y;
-
-					m_queue.push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
-
+					m_queue.push_mouse_event(event.xmotion.x, event.xmotion.y);
 					break;
 				}
 				case KeyPress:
@@ -443,13 +418,7 @@ public:
 						(event.type == KeyPress) ? modifier_mask |= ModifierButton::ALT : modifier_mask &= ~ModifierButton::ALT;
 					}
 
-					OsKeyboardEvent ev;
-
-					ev.button = kb;
-					ev.modifier = modifier_mask;
-					ev.pressed = event.type == KeyPress;
-
-					m_queue.push_event(OsEvent::KEYBOARD, &ev, sizeof(OsKeyboardEvent));
+					m_queue.push_keyboard_event(modifier_mask, kb, event.type == KeyPress);
 
 	//				// Text input part
 	//				if (event.type == KeyPress && len > 0)
@@ -621,7 +590,7 @@ private:
 	int32_t m_compile;
 	int32_t m_continue;
 
-	EventQueue m_queue;
+	OsEventQueue m_queue;
 };
 
 } // namespace crown