113 lines
3.0 KiB
C++
113 lines
3.0 KiB
C++
|
|
////////////////////////////////////////////////////////////
|
||
|
|
//
|
||
|
|
// InputEvents.cpp
|
||
|
|
//
|
||
|
|
////////////////////////////////////////////////////////////
|
||
|
|
|
||
|
|
#include "InputEvents.h"
|
||
|
|
#include "Common.h"
|
||
|
|
|
||
|
|
bool FlxEventRequest::operator==(const FlxEventRequest &Other) const
|
||
|
|
{
|
||
|
|
return (Widget == Other.Widget) &&
|
||
|
|
(TakeControl == Other.TakeControl) &&
|
||
|
|
(ShowPointer == Other.ShowPointer) &&
|
||
|
|
(Hotkeys == Other.Hotkeys);
|
||
|
|
}
|
||
|
|
|
||
|
|
bool FlxEventRequests::SanityCheck(const FlxEventRequest &Request)
|
||
|
|
{
|
||
|
|
if (Request.Widget == nullptr)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("RequestEvents called with null widget."));
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (Request.ShowPointer && !Request.TakeControl)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("RequestEvents: ShowPointer requires TakeControl."));
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (Request.TakeControl && !Request.Hotkeys.IsEmpty())
|
||
|
|
{
|
||
|
|
UE_LOG(LogLuprexIntegration, Error, TEXT("RequestEvents: Widget asked for all events, and also, specific events"));
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void FlxEventRequests::SplitHighLow(View &High, View &Low)
|
||
|
|
{
|
||
|
|
int32 NumHigh = 0;
|
||
|
|
while ((NumHigh < Requests.Num()) && (Requests[NumHigh].TakeControl)) NumHigh++;
|
||
|
|
int32 NumLow = Requests.Num() - NumHigh;
|
||
|
|
High = View(Requests.GetData(), NumHigh);
|
||
|
|
Low = View(Requests.GetData() + NumHigh, NumLow);
|
||
|
|
}
|
||
|
|
|
||
|
|
void FlxEventRequests::Request(const FlxEventRequest &NewRequest)
|
||
|
|
{
|
||
|
|
// Divide the array into a high-priority slice and a low-priority slice.
|
||
|
|
View High, Low;
|
||
|
|
SplitHighLow(High, Low);
|
||
|
|
|
||
|
|
// This is a simple test to see if anything is going to change.
|
||
|
|
// If not, we return early and avoid setting the dirty bit.
|
||
|
|
if (NewRequest.TakeControl)
|
||
|
|
{
|
||
|
|
if ((High.Num() > 0) && (High[0] == NewRequest)) return;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
if ((Low.Num() > 0) && (Low[0] == NewRequest)) return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// We're going to build a new version of the requests array.
|
||
|
|
TArray<FlxEventRequest> Updated;
|
||
|
|
|
||
|
|
// Add all high priority requests to the updated array, new request first.
|
||
|
|
if (NewRequest.TakeControl) Updated.Add(NewRequest);
|
||
|
|
for (const FlxEventRequest &Req : High)
|
||
|
|
if (Req.Widget != NewRequest.Widget) Updated.Add(Req);
|
||
|
|
|
||
|
|
// Add all low priority requests to the updated array, new request first.
|
||
|
|
if (!NewRequest.TakeControl) Updated.Add(NewRequest);
|
||
|
|
for (const FlxEventRequest &Req : Low)
|
||
|
|
if (Req.Widget != NewRequest.Widget) Updated.Add(Req);
|
||
|
|
|
||
|
|
Swap(Requests, Updated);
|
||
|
|
Dirty = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void FlxEventRequests::Remove(UUserWidget *Widget)
|
||
|
|
{
|
||
|
|
int32 N = Requests.Num();
|
||
|
|
Requests.RemoveAll([Widget](const FlxEventRequest &Entry)
|
||
|
|
{
|
||
|
|
return Entry.Widget == Widget;
|
||
|
|
});
|
||
|
|
if (Requests.Num() < N) Dirty = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void FlxEventRequests::GarbageCollect()
|
||
|
|
{
|
||
|
|
int32 N = Requests.Num();
|
||
|
|
Requests.RemoveAll([](const FlxEventRequest &Entry)
|
||
|
|
{
|
||
|
|
UUserWidget *W = Entry.Widget;
|
||
|
|
return W == nullptr || !IsValid(W) || W->GetParent() == nullptr;
|
||
|
|
});
|
||
|
|
if (Requests.Num() < N) Dirty = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
FlxEventRequests::InputMode FlxEventRequests::GetRequestedMode() const
|
||
|
|
{
|
||
|
|
if ((Requests.Num() > 0) && (Requests[0].TakeControl))
|
||
|
|
{
|
||
|
|
return InputMode::UIOnly;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return InputMode::GameOnly;
|
||
|
|
}
|
||
|
|
}
|