Utility/Window: Replace NAZARA_UTILITY_THREADED_WINDOW by a runtime flag (WIP)

This commit is contained in:
Jérôme Leclercq 2016-11-07 02:01:09 +01:00
parent 2f11529669
commit cf2bf52701
10 changed files with 176 additions and 186 deletions

View File

@ -38,9 +38,6 @@
// Lors du parsage d'une ressource, déclenche un avertissement si une erreur non-critique est repérée dans une ressource (Plus lent) // Lors du parsage d'une ressource, déclenche un avertissement si une erreur non-critique est repérée dans une ressource (Plus lent)
#define NAZARA_UTILITY_STRICT_RESOURCE_PARSING 1 #define NAZARA_UTILITY_STRICT_RESOURCE_PARSING 1
// Fait tourner chaque fenêtre dans un thread séparé si le système le supporte
#define NAZARA_UTILITY_THREADED_WINDOW 0
// Protège les classes des accès concurrentiels // Protège les classes des accès concurrentiels
//#define NAZARA_UTILITY_THREADSAFE 1 //#define NAZARA_UTILITY_THREADSAFE 1

View File

@ -432,12 +432,14 @@ namespace Nz
enum WindowStyleFlags enum WindowStyleFlags
{ {
WindowStyle_None = 0x0, WindowStyle_None = 0x0, ///< Window has no border nor titlebar.
WindowStyle_Fullscreen = 0x1, WindowStyle_Fullscreen = 0x1, ///< At the window creation, the OS tries to set it in fullscreen.
WindowStyle_Closable = 0x2, WindowStyle_Closable = 0x2, ///< Allows the window to be closed by a button in the titlebar, generating a Quit event.
WindowStyle_Resizable = 0x4, WindowStyle_Resizable = 0x4, ///< Allows the window to be resized by dragging its corners or by a button of the titlebar.
WindowStyle_Titlebar = 0x8, WindowStyle_Titlebar = 0x8, ///< Adds a titlebar to the window, this option is automatically enabled if buttons of the titlebar are enabled.
WindowStyle_Threaded = 0x10, ///< Runs the window into a thread, allowing the application to keep updating while resizing/dragging the window.
WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar, WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar,
WindowStyle_Max = WindowStyle_Titlebar*2-1 WindowStyle_Max = WindowStyle_Titlebar*2-1

View File

@ -24,6 +24,9 @@ namespace Nz
inline void Dispatch(const WindowEvent& event); inline void Dispatch(const WindowEvent& event);
EventHandler& operator=(const EventHandler&) = delete;
EventHandler& operator=(EventHandler&&) = default;
NazaraSignal(OnEvent, const EventHandler* /*eventHandler*/, const WindowEvent& /*event*/); NazaraSignal(OnEvent, const EventHandler* /*eventHandler*/, const WindowEvent& /*event*/);
NazaraSignal(OnGainedFocus, const EventHandler* /*eventHandler*/); NazaraSignal(OnGainedFocus, const EventHandler* /*eventHandler*/);
NazaraSignal(OnLostFocus, const EventHandler* /*eventHandler*/); NazaraSignal(OnLostFocus, const EventHandler* /*eventHandler*/);

View File

@ -10,6 +10,8 @@
#define NAZARA_WINDOW_HPP #define NAZARA_WINDOW_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Core/String.hpp> #include <Nazara/Core/String.hpp>
#include <Nazara/Math/Vector2.hpp> #include <Nazara/Math/Vector2.hpp>
#include <Nazara/Utility/Config.hpp> #include <Nazara/Utility/Config.hpp>
@ -19,11 +21,6 @@
#include <Nazara/Utility/WindowHandle.hpp> #include <Nazara/Utility/WindowHandle.hpp>
#include <queue> #include <queue>
#if NAZARA_UTILITY_THREADED_WINDOW
#include <Nazara/Core/ConditionVariable.hpp>
#include <Nazara/Core/Mutex.hpp>
#endif
namespace Nz namespace Nz
{ {
class Cursor; class Cursor;
@ -114,23 +111,24 @@ namespace Nz
private: private:
void IgnoreNextMouseEvent(int mouseX, int mouseY) const; void IgnoreNextMouseEvent(int mouseX, int mouseY) const;
inline void HandleEvent(const WindowEvent& event);
inline void PushEvent(const WindowEvent& event); inline void PushEvent(const WindowEvent& event);
static bool Initialize(); static bool Initialize();
static void Uninitialize(); static void Uninitialize();
std::queue<WindowEvent> m_events; std::queue<WindowEvent> m_events;
#if NAZARA_UTILITY_THREADED_WINDOW std::vector<WindowEvent> m_pendingEvents;
ConditionVariable m_eventCondition; ConditionVariable m_eventCondition;
EventHandler m_eventHandler;
Mutex m_eventMutex; Mutex m_eventMutex;
Mutex m_eventConditionMutex; Mutex m_eventConditionMutex;
bool m_waitForEvent; bool m_asyncWindow;
#endif
EventHandler m_eventHandler;
bool m_closed; bool m_closed;
bool m_closeOnQuit; bool m_closeOnQuit;
bool m_eventPolling; bool m_eventPolling;
bool m_ownsWindow; bool m_ownsWindow;
bool m_waitForEvent;
}; };
} }

View File

@ -4,6 +4,7 @@
#include <Nazara/Utility/Window.hpp> #include <Nazara/Utility/Window.hpp>
#include <Nazara/Core/ErrorFlags.hpp> #include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Utility/Debug.hpp> #include <Nazara/Utility/Debug.hpp>
namespace Nz namespace Nz
@ -13,11 +14,10 @@ namespace Nz
*/ */
inline Window::Window() : inline Window::Window() :
m_impl(nullptr), m_impl(nullptr),
#if NAZARA_UTILITY_THREADED_WINDOW m_asyncWindow(false),
m_waitForEvent(false),
#endif
m_closeOnQuit(true), m_closeOnQuit(true),
m_eventPolling(false) m_eventPolling(false),
m_waitForEvent(false)
{ {
} }
@ -41,16 +41,16 @@ namespace Nz
inline Window::Window(Window&& window) noexcept : inline Window::Window(Window&& window) noexcept :
m_impl(window.m_impl), m_impl(window.m_impl),
m_events(std::move(window.m_events)), m_events(std::move(window.m_events)),
#if NAZARA_UTILITY_THREADED_WINDOW m_pendingEvents(std::move(window.m_pendingEvents)),
m_eventCondition(std::move(window.m_eventCondition)), m_eventCondition(std::move(window.m_eventCondition)),
m_eventHandler(std::move(window.m_eventHandler)),
m_eventMutex(std::move(window.m_eventMutex)), m_eventMutex(std::move(window.m_eventMutex)),
m_eventConditionMutex(std::move(window.m_eventConditionMutex)), m_eventConditionMutex(std::move(window.m_eventConditionMutex)),
m_waitForEvent(window.m_waitForEvent),
#endif
m_closed(window.m_closed), m_closed(window.m_closed),
m_closeOnQuit(window.m_closeOnQuit), m_closeOnQuit(window.m_closeOnQuit),
m_eventPolling(window.m_eventPolling), m_eventPolling(window.m_eventPolling),
m_ownsWindow(window.m_ownsWindow) m_ownsWindow(window.m_ownsWindow),
m_waitForEvent(window.m_waitForEvent)
{ {
window.m_impl = nullptr; window.m_impl = nullptr;
} }
@ -104,12 +104,8 @@ namespace Nz
return m_impl != nullptr; return m_impl != nullptr;
} }
inline void Window::PushEvent(const WindowEvent& event) inline void Window::HandleEvent(const WindowEvent& event)
{ {
#if NAZARA_UTILITY_THREADED_WINDOW
m_eventMutex.Lock();
#endif
if (m_eventPolling) if (m_eventPolling)
m_events.push(event); m_events.push(event);
@ -120,9 +116,19 @@ namespace Nz
if (event.type == WindowEventType_Quit && m_closeOnQuit) if (event.type == WindowEventType_Quit && m_closeOnQuit)
Close(); Close();
}
#if NAZARA_UTILITY_THREADED_WINDOW inline void Window::PushEvent(const WindowEvent& event)
m_eventMutex.Unlock(); {
if (!m_asyncWindow)
HandleEvent(event);
else
{
{
LockGuard eventLock(m_eventMutex);
m_pendingEvents.push_back(event);
}
if (m_waitForEvent) if (m_waitForEvent)
{ {
@ -130,7 +136,7 @@ namespace Nz
m_eventCondition.Signal(); m_eventCondition.Signal();
m_eventConditionMutex.Unlock(); m_eventConditionMutex.Unlock();
} }
#endif }
} }
/*! /*!
@ -143,20 +149,19 @@ namespace Nz
m_closed = window.m_closed; m_closed = window.m_closed;
m_closeOnQuit = window.m_closeOnQuit; m_closeOnQuit = window.m_closeOnQuit;
m_eventCondition = std::move(window.m_eventCondition);
m_eventConditionMutex = std::move(window.m_eventConditionMutex);
m_eventHandler = std::move(window.m_eventHandler);
m_eventMutex = std::move(window.m_eventMutex);
m_eventPolling = window.m_eventPolling; m_eventPolling = window.m_eventPolling;
m_impl = window.m_impl; m_impl = window.m_impl;
m_events = std::move(window.m_events); m_events = std::move(window.m_events);
m_pendingEvents = std::move(window.m_pendingEvents);
m_ownsWindow = window.m_ownsWindow; m_ownsWindow = window.m_ownsWindow;
m_waitForEvent = window.m_waitForEvent;
window.m_impl = nullptr; window.m_impl = nullptr;
#if NAZARA_UTILITY_THREADED_WINDOW
m_eventCondition = std::move(window.m_eventCondition);
m_eventMutex = std::move(window.m_eventMutex);
m_eventConditionMutex = std::move(window.m_eventConditionMutex);
m_waitForEvent = window.m_waitForEvent;
#endif
return *this; return *this;
} }
} }

View File

@ -83,6 +83,7 @@ namespace Nz
bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style) bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style)
{ {
bool async = (style & WindowStyle_Threaded) != 0;
bool fullscreen = (style & WindowStyle_Fullscreen) != 0; bool fullscreen = (style & WindowStyle_Fullscreen) != 0;
DWORD win32Style, win32StyleEx; DWORD win32Style, win32StyleEx;
unsigned int x, y; unsigned int x, y;
@ -147,7 +148,8 @@ namespace Nz
m_callback = 0; m_callback = 0;
#if NAZARA_UTILITY_THREADED_WINDOW if (async)
{
Mutex mutex; Mutex mutex;
ConditionVariable condition; ConditionVariable condition;
m_threadActive = true; m_threadActive = true;
@ -157,9 +159,9 @@ namespace Nz
m_thread = Thread(WindowThread, &m_handle, win32StyleEx, title, win32Style, x, y, width, height, this, &mutex, &condition); m_thread = Thread(WindowThread, &m_handle, win32StyleEx, title, win32Style, x, y, width, height, this, &mutex, &condition);
condition.Wait(&mutex); condition.Wait(&mutex);
mutex.Unlock(); mutex.Unlock();
#else }
else
m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this); m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this);
#endif
if (!m_handle) if (!m_handle)
{ {
@ -175,9 +177,7 @@ namespace Nz
m_eventListener = true; m_eventListener = true;
m_ownsWindow = true; m_ownsWindow = true;
#if !NAZARA_UTILITY_THREADED_WINDOW
m_sizemove = false; m_sizemove = false;
#endif
m_style = style; m_style = style;
// Récupération de la position/taille de la fenêtre (Après sa création) // Récupération de la position/taille de la fenêtre (Après sa création)
@ -203,9 +203,7 @@ namespace Nz
m_eventListener = false; m_eventListener = false;
m_ownsWindow = false; m_ownsWindow = false;
#if !NAZARA_UTILITY_THREADED_WINDOW
m_sizemove = false; m_sizemove = false;
#endif
m_style = RetrieveStyle(m_handle); m_style = RetrieveStyle(m_handle);
RECT clientRect, windowRect; RECT clientRect, windowRect;
@ -222,18 +220,21 @@ namespace Nz
{ {
if (m_ownsWindow) if (m_ownsWindow)
{ {
#if NAZARA_UTILITY_THREADED_WINDOW if (m_style & WindowStyle_Threaded)
{
if (m_thread.IsJoinable()) if (m_thread.IsJoinable())
{ {
m_threadActive = false; m_threadActive = false;
PostMessageW(m_handle, WM_NULL, 0, 0); // Pour réveiller le thread PostMessageW(m_handle, WM_NULL, 0, 0); // Wake up our thread
m_thread.Join(); m_thread.Join();
} }
#else }
else
{
if (m_handle) if (m_handle)
DestroyWindow(m_handle); DestroyWindow(m_handle);
#endif }
} }
else else
SetEventListener(false); SetEventListener(false);
@ -280,7 +281,7 @@ namespace Nz
if (titleSize == 0) if (titleSize == 0)
return String(); return String();
titleSize++; // Caractère nul titleSize++; // \0
std::unique_ptr<wchar_t[]> wTitle(new wchar_t[titleSize]); std::unique_ptr<wchar_t[]> wTitle(new wchar_t[titleSize]);
GetWindowTextW(m_handle, wTitle.get(), titleSize); GetWindowTextW(m_handle, wTitle.get(), titleSize);
@ -320,7 +321,11 @@ namespace Nz
if (m_ownsWindow) if (m_ownsWindow)
{ {
if (block) if (block)
{
NazaraNotice("WaitMessage");
WaitMessage(); WaitMessage();
NazaraNotice("~WaitMessage");
}
MSG message; MSG message;
while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE)) while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE))
@ -525,7 +530,6 @@ namespace Nz
return true; // Afin que Windows ne ferme pas la fenêtre automatiquement return true; // Afin que Windows ne ferme pas la fenêtre automatiquement
} }
#if !NAZARA_UTILITY_THREADED_WINDOW
case WM_ENTERSIZEMOVE: case WM_ENTERSIZEMOVE:
{ {
m_sizemove = true; m_sizemove = true;
@ -536,6 +540,10 @@ namespace Nz
{ {
m_sizemove = false; m_sizemove = false;
// In case of threaded window, size and move events are not blocked
if (m_style & WindowStyle_Threaded)
break;
// On vérifie ce qui a changé // On vérifie ce qui a changé
RECT clientRect, windowRect; RECT clientRect, windowRect;
GetClientRect(m_handle, &clientRect); GetClientRect(m_handle, &clientRect);
@ -565,7 +573,6 @@ namespace Nz
m_parent->PushEvent(event); m_parent->PushEvent(event);
} }
} }
#endif
case WM_KEYDOWN: case WM_KEYDOWN:
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN:
@ -789,10 +796,8 @@ namespace Nz
case WM_MOVE: case WM_MOVE:
{ {
#if !NAZARA_UTILITY_THREADED_WINDOW if (m_sizemove && (m_style & WindowStyle_Threaded) == 0)
if (m_sizemove)
break; break;
#endif
RECT windowRect; RECT windowRect;
GetWindowRect(m_handle, &windowRect); GetWindowRect(m_handle, &windowRect);
@ -862,12 +867,12 @@ namespace Nz
case WM_SIZE: case WM_SIZE:
{ {
#if NAZARA_UTILITY_THREADED_WINDOW if (m_sizemove && (m_style & WindowStyle_Threaded) == 0)
if (wParam != SIZE_MINIMIZED) break;
#else
if (!m_sizemove && wParam != SIZE_MINIMIZED) if (wParam == SIZE_MINIMIZED)
#endif break;
{
RECT rect; RECT rect;
GetClientRect(m_handle, &rect); GetClientRect(m_handle, &rect);
@ -882,7 +887,6 @@ namespace Nz
event.size.width = size.x; event.size.width = size.x;
event.size.height = size.y; event.size.height = size.y;
m_parent->PushEvent(event); m_parent->PushEvent(event);
}
break; break;
} }
@ -1187,7 +1191,6 @@ namespace Nz
return style; return style;
} }
#if NAZARA_UTILITY_THREADED_WINDOW
void WindowImpl::WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition) void WindowImpl::WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
{ {
HWND& winHandle = *handle; HWND& winHandle = *handle;
@ -1195,15 +1198,16 @@ namespace Nz
mutex->Lock(); mutex->Lock();
condition->Signal(); condition->Signal();
mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici mutex->Unlock(); // mutex and condition may be destroyed after this line
if (!winHandle) if (!winHandle)
return; return;
NazaraNotice("In");
while (window->m_threadActive) while (window->m_threadActive)
window->ProcessEvents(true); window->ProcessEvents(true);
NazaraNotice("Out");
DestroyWindow(winHandle); DestroyWindow(winHandle);
} }
#endif
} }

View File

@ -22,10 +22,8 @@
namespace Nz namespace Nz
{ {
#if NAZARA_UTILITY_THREADED_WINDOW
class ConditionVariable; class ConditionVariable;
class Mutex; class Mutex;
#endif
class Window; class Window;
#undef IsMinimized // Conflit avec la méthode du même nom #undef IsMinimized // Conflit avec la méthode du même nom
@ -88,9 +86,7 @@ namespace Nz
static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags); static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags);
static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam);
static UInt32 RetrieveStyle(HWND window); static UInt32 RetrieveStyle(HWND window);
#if NAZARA_UTILITY_THREADED_WINDOW
static void WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition); static void WindowThread(HWND* handle, DWORD styleEx, const String& title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition);
#endif
HCURSOR m_cursor; HCURSOR m_cursor;
HWND m_handle; HWND m_handle;
@ -101,21 +97,15 @@ namespace Nz
Vector2i m_mousePos; Vector2i m_mousePos;
Vector2i m_position; Vector2i m_position;
Vector2ui m_size; Vector2ui m_size;
#if NAZARA_UTILITY_THREADED_WINDOW
Thread m_thread; Thread m_thread;
#endif
Window* m_parent; Window* m_parent;
bool m_eventListener; bool m_eventListener;
bool m_keyRepeat; bool m_keyRepeat;
bool m_mouseInside; bool m_mouseInside;
bool m_ownsWindow; bool m_ownsWindow;
#if !NAZARA_UTILITY_THREADED_WINDOW
bool m_sizemove; bool m_sizemove;
#endif
bool m_smoothScrolling; bool m_smoothScrolling;
#if NAZARA_UTILITY_THREADED_WINDOW
bool m_threadActive; bool m_threadActive;
#endif
short m_scrolling; short m_scrolling;
}; };
} }

View File

@ -66,6 +66,8 @@ namespace Nz
else if (style & WindowStyle_Closable || style & WindowStyle_Resizable) else if (style & WindowStyle_Closable || style & WindowStyle_Resizable)
style |= WindowStyle_Titlebar; style |= WindowStyle_Titlebar;
m_asyncWindow = (style & WindowStyle_Threaded) != 0;
std::unique_ptr<WindowImpl> impl = std::make_unique<WindowImpl>(this); std::unique_ptr<WindowImpl> impl = std::make_unique<WindowImpl>(this);
if (!impl->Create(mode, title, style)) if (!impl->Create(mode, title, style))
{ {
@ -313,11 +315,8 @@ namespace Nz
} }
#endif #endif
#if NAZARA_UTILITY_THREADED_WINDOW if (!m_asyncWindow)
LockGuard lock(m_eventMutex);
#else
m_impl->ProcessEvents(false); m_impl->ProcessEvents(false);
#endif
if (!m_events.empty()) if (!m_events.empty())
{ {
@ -337,9 +336,17 @@ namespace Nz
NazaraAssert(m_impl, "Window not created"); NazaraAssert(m_impl, "Window not created");
NazaraUnused(block); NazaraUnused(block);
#if !NAZARA_UTILITY_THREADED_WINDOW if (!m_asyncWindow)
m_impl->ProcessEvents(block); m_impl->ProcessEvents(block);
#endif else
{
LockGuard eventLock(m_eventMutex);
for (const WindowEvent& event : m_pendingEvents)
PushEvent(event);
m_pendingEvents.clear();
}
} }
void Window::SetCursor(WindowCursor cursor) void Window::SetCursor(WindowCursor cursor)
@ -384,25 +391,14 @@ namespace Nz
} }
#endif #endif
#if NAZARA_UTILITY_THREADED_WINDOW
m_impl->SetEventListener(listener); m_impl->SetEventListener(listener);
if (!listener) if (!listener)
{ {
// On vide la pile des évènements // Empty the event queue
LockGuard lock(m_eventMutex); LockGuard lock(m_eventMutex);
while (!m_events.empty()) while (!m_events.empty())
m_events.pop(); m_events.pop();
} }
#else
if (m_ownsWindow)
{
// Inutile de transmettre l'ordre dans ce cas-là
if (!listener)
NazaraError("A non-threaded window needs to listen to events");
}
else
m_impl->SetEventListener(listener);
#endif
} }
void Window::SetFocus() void Window::SetFocus()
@ -590,7 +586,20 @@ namespace Nz
} }
#endif #endif
#if NAZARA_UTILITY_THREADED_WINDOW if (!m_asyncWindow)
{
while (m_events.empty())
m_impl->ProcessEvents(true);
if (event)
*event = m_events.front();
m_events.pop();
return true;
}
else
{
LockGuard lock(m_eventMutex); LockGuard lock(m_eventMutex);
if (m_events.empty()) if (m_events.empty())
@ -615,17 +624,7 @@ namespace Nz
} }
return false; return false;
#else }
while (m_events.empty())
m_impl->ProcessEvents(true);
if (event)
*event = m_events.front();
m_events.pop();
return true;
#endif
} }
bool Window::OnWindowCreated() bool Window::OnWindowCreated()

View File

@ -203,17 +203,18 @@ namespace Nz
// Set the window's name // Set the window's name
SetTitle(title); SetTitle(title);
#if NAZARA_UTILITY_THREADED_WINDOW if (m_style & WindowStyle_Threaded)
{
Mutex mutex; Mutex mutex;
ConditionVariable condition; ConditionVariable condition;
m_threadActive = true; m_threadActive = true;
// We wait that thread is well launched // Wait until the thread is ready
mutex.Lock(); mutex.Lock();
m_thread = Thread(WindowThread, this, &mutex, &condition); m_thread = Thread(WindowThread, this, &mutex, &condition);
condition.Wait(&mutex); condition.Wait(&mutex);
mutex.Unlock(); mutex.Unlock();
#endif }
// Set fullscreen video mode and switch to fullscreen if necessary // Set fullscreen video mode and switch to fullscreen if necessary
if (fullscreen) if (fullscreen)
@ -275,13 +276,15 @@ namespace Nz
{ {
if (m_ownsWindow) if (m_ownsWindow)
{ {
#if NAZARA_UTILITY_THREADED_WINDOW if (m_style & WindowStyle_Threaded)
{
if (m_thread.IsJoinable()) if (m_thread.IsJoinable())
{ {
m_threadActive = false; m_threadActive = false;
m_thread.Join(); m_thread.Join();
} }
#else }
// Destroy the window // Destroy the window
if (m_window && m_ownsWindow) if (m_window && m_ownsWindow)
{ {
@ -293,8 +296,7 @@ namespace Nz
xcb_destroy_window( xcb_destroy_window(
connection, connection,
m_window m_window
)) )))
)
NazaraError("Failed to destroy window"); NazaraError("Failed to destroy window");
xcb_flush(connection); xcb_flush(connection);
@ -1405,7 +1407,7 @@ namespace Nz
// Catch reparent events to properly apply fullscreen on // Catch reparent events to properly apply fullscreen on
// some "strange" window managers (like Awesome) which // some "strange" window managers (like Awesome) which
// seem to make use of temporary parents during mapping // seem to make use of temporary parents during mapping
if (m_style & Nz::WindowStyle_Fullscreen) if (m_style & WindowStyle_Fullscreen)
SwitchToFullscreen(); SwitchToFullscreen();
break; break;
@ -1685,12 +1687,11 @@ namespace Nz
)); ));
} }
#if NAZARA_UTILITY_THREADED_WINDOW
void WindowImpl::WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition) void WindowImpl::WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition)
{ {
mutex->Lock(); mutex->Lock();
condition->Signal(); condition->Signal();
mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici mutex->Unlock(); // mutex and condition may be destroyed after this line
if (!window->m_window) if (!window->m_window)
return; return;
@ -1700,5 +1701,4 @@ namespace Nz
window->Destroy(); window->Destroy();
} }
#endif
} }

View File

@ -20,10 +20,8 @@
namespace Nz namespace Nz
{ {
#if NAZARA_UTILITY_THREADED_WINDOW
class ConditionVariable; class ConditionVariable;
class Mutex; class Mutex;
#endif
class Cursor; class Cursor;
class Icon; class Icon;
class VideoMode; class VideoMode;
@ -103,25 +101,19 @@ namespace Nz
bool UpdateNormalHints(); bool UpdateNormalHints();
void UpdateEventQueue(xcb_generic_event_t* event); void UpdateEventQueue(xcb_generic_event_t* event);
#if NAZARA_UTILITY_THREADED_WINDOW
static void WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition); static void WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition);
#endif
xcb_window_t m_window; xcb_window_t m_window;
xcb_screen_t* m_screen; xcb_screen_t* m_screen;
xcb_randr_get_screen_info_reply_t m_oldVideoMode; xcb_randr_get_screen_info_reply_t m_oldVideoMode;
xcb_size_hints_t m_size_hints; xcb_size_hints_t m_size_hints;
UInt32 m_style;
#if NAZARA_UTILITY_THREADED_WINDOW
Thread m_thread; Thread m_thread;
#endif UInt32 m_style;
Window* m_parent; Window* m_parent;
bool m_eventListener; bool m_eventListener;
bool m_ownsWindow; bool m_ownsWindow;
bool m_smoothScrolling; bool m_smoothScrolling;
#if NAZARA_UTILITY_THREADED_WINDOW
bool m_threadActive; bool m_threadActive;
#endif
short m_scrolling; short m_scrolling;
Vector2i m_mousePos; Vector2i m_mousePos;
bool m_keyRepeat; bool m_keyRepeat;