Daniele Bartolini 12 лет назад
Родитель
Сommit
d6e8ed04d8
6 измененных файлов с 172 добавлено и 79 удалено
  1. 0 3
      engine/Device.cpp
  2. 10 1
      engine/input/Mouse.h
  3. 26 14
      engine/os/OsTypes.h
  4. 1 0
      engine/os/linux/OsWindow.h
  5. 29 0
      engine/os/linux/Semaphore.h
  6. 106 61
      engine/os/linux/main.cpp

+ 0 - 3
engine/Device.cpp

@@ -362,9 +362,6 @@ void Device::frame()
 		}
 
 		m_renderer->frame();
-
-		m_keyboard->update();
-		m_mouse->update();
 	}
 
 	m_frame_count++;

+ 10 - 1
engine/input/Mouse.h

@@ -132,6 +132,13 @@ public:
 		set_cursor_xy(Vec2(position.x * (float) m_width, position.y * (float) m_height));
 	}
 
+	//-----------------------------------------------------------------------------
+	void set_position(uint16_t x, uint16_t y)
+	{
+		m_x = x;
+		m_y = y;
+	}
+
 	//-----------------------------------------------------------------------------
 	void set_metrics(uint16_t width, uint16_t height)
 	{
@@ -140,8 +147,10 @@ public:
 	}
 
 	//-----------------------------------------------------------------------------
-	void set_button_state(MouseButton::Enum b, bool state)
+	void set_button_state(uint16_t x, uint16_t y, MouseButton::Enum b, bool state)
 	{
+		set_position(x, y);
+
 		m_last_button = b;
 		m_current_state[b] = state;
 	}

+ 26 - 14
engine/os/OsTypes.h

@@ -31,12 +31,32 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+struct OsMetricsEvent
+{
+	uint16_t x;
+	uint16_t y;
+	uint16_t width;
+	uint16_t height;
+};
+
+struct OsExitEvent
+{
+	int32_t code;
+};
+
 /// Represents an event fired by mouse.
 struct OsMouseEvent
 {
+	enum Enum
+	{
+		BUTTON,
+		MOVE
+	};
+
+	OsMouseEvent::Enum type;
 	MouseButton::Enum button;
-	uint32_t x;
-	uint32_t y;
+	uint16_t x;
+	uint16_t y;
 	bool pressed;
 };
 
@@ -51,9 +71,9 @@ struct OsKeyboardEvent
 /// Represents an event fired by touch screen.
 struct OsTouchEvent
 {
-	uint32_t pointer_id;
-	uint32_t x;
-	uint32_t y;
+	uint8_t pointer_id;
+	uint16_t x;
+	uint16_t y;
 };
 
 /// Represents an event fired by accelerometer.
@@ -76,18 +96,10 @@ struct OsEvent
 		TOUCH			= 3,
 		ACCELEROMETER	= 4,
 
+		METRICS,
 		// Exit from program
 		EXIT
 	};
-
-	OsEvent::Enum type;
-	union
-	{
-		OsMouseEvent mouse;
-		OsKeyboardEvent keyboard;
-		OsTouchEvent touch;
-		OsAccelerometerEvent accelerometer;
-	};
 };
 
 } // namespace crown

+ 1 - 0
engine/os/linux/OsWindow.h

@@ -1,4 +1,5 @@
 /*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
 Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
 
 Permission is hereby granted, free of charge, to any person

+ 29 - 0
engine/os/linux/Semaphore.h

@@ -0,0 +1,29 @@
+/*
+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 "../posix/Semaphore.h"

+ 106 - 61
engine/os/linux/main.cpp

@@ -31,9 +31,10 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Crown.h"
 #include "Device.h"
 #include "OsTypes.h"
-#include "EventQueue.h"
 #include "Config.h"
 #include "BundleCompiler.h"
+#include "EventBuffer.h"
+#include "Semaphore.h"
 
 namespace crown
 {
@@ -136,13 +137,9 @@ public:
 		, m_fullscreen(0)
 		, m_compile(0)
 		, m_continue(0)
-		, m_alloc(m_event_buffer, 1024 * 4)
-		, m_queue(m_alloc)
+		, m_read(&m_event[0])
+		, m_write(&m_event[1])
 	{
-		for (uint32_t i = 0; i < 1024; i++)
-		{
-			m_event_buffer[i] = 'a';
-		}
 	}
 
 	//-----------------------------------------------------------------------------
@@ -253,16 +250,26 @@ public:
 
 		while (!m_exit)
 		{
+			m_write_sem.wait();
+
 			while (XPending(m_x11_display))
 			{
 				LinuxDevice::pump_events();
 			}
+
+			// Swap event buffers
+			EventBuffer* temp = m_read;
+			m_read = m_write;
+			m_write = temp;
+
+			m_read_sem.post();
 		}
 
 		Log::d("Stopping game thread");
 
 		game_thread.stop();
 
+		LinuxDevice::shutdown();
 		XDestroyWindow(m_x11_display, m_x11_window);
 		XCloseDisplay(m_x11_display);
 
@@ -277,6 +284,9 @@ public:
 		while(!process_events() && is_running())
 		{
 			Device::frame();
+
+			m_keyboard->update();
+			m_mouse->update();
 		}
 
 		Device::shutdown();
@@ -295,23 +305,39 @@ public:
 	//-----------------------------------------------------------------------------
 	bool process_events()
 	{
-		OsEvent* event;
+		void* event;
+		uint32_t type;
+		size_t size;
 		do
 		{
-			event = (OsEvent*)m_queue.get_event();
+			event = m_read->get_next_event(type, size);
 
 			if (event != NULL)
 			{
-				switch (event->type)
+				switch (type)
 				{
 					case OsEvent::MOUSE:
 					{
-						m_mouse->set_button_state(event->mouse.button, event->mouse.pressed);
+						OsMouseEvent* ev = (OsMouseEvent*) event;
+						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;
+							default: CE_FATAL("Oops, unknown mouse event type"); break;
+						}
+
 						break;
 					}
 					case OsEvent::KEYBOARD:
 					{
-						m_keyboard->set_button_state(event->keyboard.button, event->keyboard.pressed);
+						OsKeyboardEvent* ev = (OsKeyboardEvent*) event;
+						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);
 						break;
 					}
 					case OsEvent::EXIT:
@@ -321,13 +347,16 @@ public:
 					default:
 					{
 						Log::d("Unmanaged");
-						//CE_FATAL("Oops, unknown Os event");
 						break;
 					}
 				}
 			}
 		}
-		while (event != 0);
+		while (event != NULL);
+
+		m_read->clear();
+		m_write_sem.post();
+		m_read_sem.wait();
 
 		return false;
 	}
@@ -344,26 +373,34 @@ public:
 			{
 				if ((Atom)event.xclient.data.l[0] == m_wm_delete_message)
 				{
-					OsEvent* os_event = new OsEvent;
-					os_event->type = OsEvent::EXIT;
-					m_queue.push_event(os_event);
+					OsExitEvent ev;
+					ev.code = 0;
+					m_write->push_event(OsEvent::EXIT, &ev, sizeof(OsExitEvent));
 				}
 				break;
 			}
-			// case ConfigureNotify:
-			// {
-			// 	m_x = event.xconfigure.x;
-			// 	m_y = event.xconfigure.y;
-			// 	m_width = event.xconfigure.width;
-			// 	m_height = event.xconfigure.height;
-			// 	break;
-			// }
+			case ConfigureNotify:
+			{
+				m_x = event.xconfigure.x;
+				m_y = event.xconfigure.y;
+				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_write->push_event(OsEvent::METRICS, &ev, sizeof(OsMetricsEvent));
+				Log::d("Configure notify");
+
+				break;
+			}
 			case ButtonPress:
 			case ButtonRelease:
 			{
-				OsEvent* os_event = new OsEvent;
-				OsMouseEvent& mouse_event = os_event->mouse;
-				os_event->type = OsEvent::MOUSE;
+				OsMouseEvent ev;
 
 				MouseButton::Enum mb;
 				switch (event.xbutton.button)
@@ -371,25 +408,32 @@ public:
 					case Button1: mb = MouseButton::LEFT; break;
 					case Button2: mb = MouseButton::MIDDLE; break;
 					case Button3: mb = MouseButton::RIGHT; break;
-					default: mb = MouseButton::COUNT; break;
+					default: mb = MouseButton::NONE; break;
 				}
 
-				if (mb != MouseButton::COUNT)
+				if (mb != MouseButton::NONE)
 				{
-					mouse_event.button = mb;
-					mouse_event.x = event.xbutton.x;
-					mouse_event.y = event.xbutton.y;
-					mouse_event.pressed = event.type == ButtonPress;
-					m_queue.push_event(os_event);
+					ev.type = OsMouseEvent::BUTTON;
+					ev.button = mb;
+					ev.x = event.xbutton.x;
+					ev.y = event.xbutton.y;
+					ev.pressed = event.type == ButtonPress;
+					m_write->push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
 				}
 
 				break;
 			}
-			// case MotionNotify:
-			// {
-			// 	push_event(OSET_MOTION_NOTIFY, data_button[0], data_button[1], data_button[2], data_button[3]);
-			// 	break;
-			// }
+			case MotionNotify:
+			{
+				OsMouseEvent ev;
+				ev.type = OsMouseEvent::MOVE;
+				ev.x = event.xmotion.x;
+				ev.y = event.xmotion.y;
+
+				m_write->push_event(OsEvent::MOUSE, &ev, sizeof(OsMouseEvent));
+
+				break;
+			}
 			case KeyPress:
 			case KeyRelease:
 			{
@@ -416,28 +460,26 @@ public:
 					(event.type == KeyPress) ? modifier_mask |= ModifierButton::ALT : modifier_mask &= ~ModifierButton::ALT;
 				}
 
-				OsEvent* os_event = new OsEvent;
-				OsKeyboardEvent& keyboard_event = os_event->keyboard;
-				os_event->type = OsEvent::KEYBOARD;
+				OsKeyboardEvent ev;
 
-				keyboard_event.button = kb;
-				keyboard_event.modifier = modifier_mask;
-				keyboard_event.pressed = event.type == KeyPress;
+				ev.button = kb;
+				ev.modifier = modifier_mask;
+				ev.pressed = event.type == KeyPress;
 
-				m_queue.push_event(os_event);
+				m_write->push_event(OsEvent::KEYBOARD, &ev, sizeof(OsKeyboardEvent));
 
-	//				// Text input part
-	//				if (event.type == KeyPress && len > 0)
-	//				{
-	//					//crownEvent.event_type = ET_TEXT;
-	//					//crownEvent.text.type = TET_TEXT_INPUT;
-	//					strncpy(keyboardEvent.text, string, 4);
+//				// Text input part
+//				if (event.type == KeyPress && len > 0)
+//				{
+//					//crownEvent.event_type = ET_TEXT;
+//					//crownEvent.text.type = TET_TEXT_INPUT;
+//					strncpy(keyboardEvent.text, string, 4);
 
-	//					if (mListener)
-	//					{
-	//						mListener->TextInput(keyboardEvent);
-	//					}
-	//				}
+//					if (mListener)
+//					{
+//						mListener->TextInput(keyboardEvent);
+//					}
+//				}
 
 				break;
 			}
@@ -595,9 +637,12 @@ private:
 	int32_t m_compile;
 	int32_t m_continue;
 
-	char m_event_buffer[1024 * 4];
-	LinearAllocator m_alloc;
-	EventQueue m_queue;
+	EventBuffer m_event[2];
+	EventBuffer* m_read;
+	EventBuffer* m_write;
+
+	Semaphore m_read_sem;
+	Semaphore m_write_sem;
 };
 
 } // namespace crown