Fix crash on shutdown when one of the windows had outstanding input events
This commit is contained in:
@@ -41,7 +41,7 @@ struct AxisData
|
|||||||
uint64 FrameIndex = 0;
|
uint64 FrameIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace InputImpl
|
namespace
|
||||||
{
|
{
|
||||||
Dictionary<String, ActionData> Actions;
|
Dictionary<String, ActionData> Actions;
|
||||||
Dictionary<String, AxisData> Axes;
|
Dictionary<String, AxisData> Axes;
|
||||||
@@ -50,8 +50,6 @@ namespace InputImpl
|
|||||||
InputDevice::EventQueue InputEvents;
|
InputDevice::EventQueue InputEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace InputImpl;
|
|
||||||
|
|
||||||
class InputService : public EngineService
|
class InputService : public EngineService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -91,6 +89,17 @@ Delegate<StringView> Input::AxisValueChanged;
|
|||||||
Array<ActionConfig> Input::ActionMappings;
|
Array<ActionConfig> Input::ActionMappings;
|
||||||
Array<AxisConfig> Input::AxisMappings;
|
Array<AxisConfig> Input::AxisMappings;
|
||||||
|
|
||||||
|
void ClearWindowInputs(Window* window)
|
||||||
|
{
|
||||||
|
WindowsManager::WindowsLocker.Lock();
|
||||||
|
for (int32 i = InputEvents.Count() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (InputEvents[i].Target == window)
|
||||||
|
InputEvents.RemoveAtKeepOrder(i);
|
||||||
|
}
|
||||||
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
void InputSettings::Apply()
|
void InputSettings::Apply()
|
||||||
{
|
{
|
||||||
PROFILE_MEM(Input);
|
PROFILE_MEM(Input);
|
||||||
@@ -926,8 +935,8 @@ void InputService::Update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pick the first focused window for input events
|
// Pick the first focused window for input events
|
||||||
WindowsManager::WindowsLocker.Lock();
|
|
||||||
Window* defaultWindow = nullptr;
|
Window* defaultWindow = nullptr;
|
||||||
|
WindowsManager::WindowsLocker.Lock();
|
||||||
for (auto window : WindowsManager::Windows)
|
for (auto window : WindowsManager::Windows)
|
||||||
{
|
{
|
||||||
if (window->IsFocused() && window->GetSettings().AllowInput)
|
if (window->IsFocused() && window->GetSettings().AllowInput)
|
||||||
@@ -936,9 +945,7 @@ void InputService::Update()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if PLATFORM_SDL
|
|
||||||
WindowsManager::WindowsLocker.Unlock();
|
WindowsManager::WindowsLocker.Unlock();
|
||||||
#endif
|
|
||||||
|
|
||||||
// Send input events for the focused window
|
// Send input events for the focused window
|
||||||
for (const auto& e : InputEvents)
|
for (const auto& e : InputEvents)
|
||||||
@@ -992,9 +999,6 @@ void InputService::Update()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !PLATFORM_SDL
|
|
||||||
WindowsManager::WindowsLocker.Unlock();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Skip if game has no focus to handle the input
|
// Skip if game has no focus to handle the input
|
||||||
if (!Engine::HasGameViewportFocus())
|
if (!Engine::HasGameViewportFocus())
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
#include "Engine/Scripting/ManagedCLR/MMethod.h"
|
||||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||||
|
|
||||||
|
extern void ClearWindowInputs(Window* window);
|
||||||
|
|
||||||
#if USE_CSHARP
|
#if USE_CSHARP
|
||||||
// Helper macros for calling C# events
|
// Helper macros for calling C# events
|
||||||
#define BEGIN_INVOKE_EVENT(name, paramsCount) \
|
#define BEGIN_INVOKE_EVENT(name, paramsCount) \
|
||||||
@@ -122,6 +124,7 @@ WindowBase::WindowBase(const CreateWindowSettings& settings)
|
|||||||
|
|
||||||
WindowBase::~WindowBase()
|
WindowBase::~WindowBase()
|
||||||
{
|
{
|
||||||
|
ClearWindowInputs((Window*)this);
|
||||||
ASSERT(!RenderTask);
|
ASSERT(!RenderTask);
|
||||||
ASSERT(!_swapChain);
|
ASSERT(!_swapChain);
|
||||||
WindowsManager::Unregister((Window*)this);
|
WindowsManager::Unregister((Window*)this);
|
||||||
@@ -182,15 +185,14 @@ String WindowBase::ToString() const
|
|||||||
|
|
||||||
void WindowBase::OnDeleteObject()
|
void WindowBase::OnDeleteObject()
|
||||||
{
|
{
|
||||||
|
// Dereference window
|
||||||
|
ClearWindowInputs((Window*)this);
|
||||||
#if !USE_EDITOR
|
#if !USE_EDITOR
|
||||||
|
|
||||||
// Unlink main task (if was used)
|
|
||||||
if (RenderTask && RenderTask == MainRenderTask::Instance)
|
if (RenderTask && RenderTask == MainRenderTask::Instance)
|
||||||
{
|
{
|
||||||
MainRenderTask::Instance->SwapChain = nullptr;
|
MainRenderTask::Instance->SwapChain = nullptr;
|
||||||
RenderTask = nullptr;
|
RenderTask = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Release resources
|
// Release resources
|
||||||
|
|||||||
Reference in New Issue
Block a user