//////////////////////////////////////////////////////////// // // InputEvents.cpp // //////////////////////////////////////////////////////////// #include "InputEvents.h" #include "Common.h" bool FlxEventRequest::operator==(const FlxEventRequest &Other) const { return (Widget == Other.Widget) && (UseUIOnly == Other.UseUIOnly) && (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.UseUIOnly) { UE_LOG(LogLuprexIntegration, Error, TEXT("RequestEvents: ShowPointer requires UseUIOnly.")); return false; } if (Request.UseUIOnly && !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].UseUIOnly)) 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.UseUIOnly) { 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 Updated; // Add all high priority requests to the updated array, new request first. if (NewRequest.UseUIOnly) 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.UseUIOnly) 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].UseUIOnly)) { return InputMode::UIOnly; } else { return InputMode::GameOnly; } }