InputModeRequests now use less-than operator to sort

This commit is contained in:
2026-04-21 04:24:35 -04:00
parent 9787522ef6
commit ec983951fe
2 changed files with 67 additions and 48 deletions

View File

@@ -7,6 +7,15 @@
#include "InputModeRequest.h" #include "InputModeRequest.h"
#include "Common.h" #include "Common.h"
bool FlxInputModeRequest::operator<(const FlxInputModeRequest &Other) const
{
// The highest priority request goes to the front of the array.
// Therefore, in this context, 'less than' means 'higher priority'.
// It's a little confusing.
if (ShowPointer != Other.ShowPointer) return ShowPointer > Other.ShowPointer;
return SequenceNumber > Other.SequenceNumber;
}
bool FlxInputModeRequest::operator==(const FlxInputModeRequest &Other) const bool FlxInputModeRequest::operator==(const FlxInputModeRequest &Other) const
{ {
return (Widget == Other.Widget) && return (Widget == Other.Widget) &&
@@ -26,57 +35,68 @@ bool FlxInputModeRequests::SanityCheck(const FlxInputModeRequest &Request)
return true; return true;
} }
void FlxInputModeRequests::SplitHighLow(View &High, View &Low)
int32 FlxInputModeRequests::FindWidget(UUserWidget *Widget)
{ {
int32 NumHigh = 0; for (const FlxInputModeRequest &Req : Requests)
while ((NumHigh < Requests.Num()) && (Requests[NumHigh].IsHighPrio())) NumHigh++; {
int32 NumLow = Requests.Num() - NumHigh; if (Req.Widget == Widget) return &Req - Requests.GetData();
High = View(Requests.GetData(), NumHigh); }
Low = View(Requests.GetData() + NumHigh, NumLow); return Requests.Num();
} }
void FlxInputModeRequests::Request(const FlxInputModeRequest &NewRequest) void FlxInputModeRequests::BubbleItem(int32 Index)
{ {
bool IsHigh = NewRequest.IsHighPrio(); while ((Index > 0) && (Requests[Index] < Requests[Index - 1]))
{
Swap(Requests[Index], Requests[Index - 1]);
--Index;
}
while ((Index < Requests.Num() - 1) && (Requests[Index + 1] < Requests[Index]))
{
Swap(Requests[Index], Requests[Index + 1]);
++Index;
}
}
// Divide the array into a high-priority slice and a low-priority slice. void FlxInputModeRequests::Request(const FlxInputModeRequest &NewRequest, bool UpdateSequence)
View High, Low; {
SplitHighLow(High, Low); int32 Index = FindWidget(NewRequest.Widget);
// Stamp this request with a fresh sequence number. if (Index == Requests.Num())
FlxInputModeRequest Stamped = NewRequest; {
Stamped.SequenceNumber = ++NextSequenceNumber; Requests.Emplace(NewRequest);
Requests[Index].SequenceNumber = ++NextSequenceNumber;
}
else
{
int32 SequenceNumber = Requests[Index].SequenceNumber;
if (UpdateSequence) SequenceNumber = ++NextSequenceNumber;
Requests[Index] = NewRequest;
Requests[Index].SequenceNumber = SequenceNumber;
}
// We're going to build a new version of the requests array. BubbleItem(Index);
TArray<FlxInputModeRequest> Updated;
// Add all high priority requests to the updated array, new request first.
if (IsHigh) Updated.Add(Stamped);
for (const FlxInputModeRequest &Req : High)
if (Req.Widget != NewRequest.Widget) Updated.Add(Req);
// Add all low priority requests to the updated array, new request first.
if (!IsHigh) Updated.Add(Stamped);
for (const FlxInputModeRequest &Req : Low)
if (Req.Widget != NewRequest.Widget) Updated.Add(Req);
Swap(Requests, Updated);
} }
void FlxInputModeRequests::SetEnableInputComponent(UUserWidget *Widget, bool EnableInputComponent) void FlxInputModeRequests::SetEnableInputComponent(UUserWidget *Widget, bool EnableInputComponent)
{ {
for (FlxInputModeRequest &Req : Requests) int32 Index = FindWidget(Widget);
if (Index == Requests.Num())
{ {
if (Req.Widget == Widget)
{
Req.EnableInputComponent = EnableInputComponent;
return;
}
}
FlxInputModeRequest NewReq; FlxInputModeRequest NewReq;
NewReq.Widget = Widget; NewReq.Widget = Widget;
NewReq.EnableInputComponent = EnableInputComponent; NewReq.EnableInputComponent = EnableInputComponent;
Request(NewReq); NewReq.SequenceNumber = ++NextSequenceNumber;
Requests.Emplace(NewReq);
}
else
{
Requests[Index].EnableInputComponent = EnableInputComponent;
}
BubbleItem(Index);
} }
void FlxInputModeRequests::Remove(UUserWidget *Widget) void FlxInputModeRequests::Remove(UUserWidget *Widget)

View File

@@ -34,10 +34,7 @@ struct FlxInputModeRequest
FlxInputModeRequest() = default; FlxInputModeRequest() = default;
bool operator == (const FlxInputModeRequest &Other) const; bool operator == (const FlxInputModeRequest &Other) const;
bool operator < (const FlxInputModeRequest &Other) const;
// True if this request wants any high-priority resource:
// keyboard focus, the mouse pointer, or input blocking.
bool IsHighPrio() const { return Focus != nullptr || ShowPointer || BlockInput; }
UPROPERTY(BlueprintReadWrite) UPROPERTY(BlueprintReadWrite)
UUserWidget* Widget = nullptr; UUserWidget* Widget = nullptr;
@@ -73,19 +70,14 @@ private:
int32 NextSequenceNumber = 0; int32 NextSequenceNumber = 0;
public: public:
using View = TArrayView<FlxInputModeRequest>;
// Get the requests array. // Get the requests array.
const TArray<FlxInputModeRequest> &GetRequests() const { return Requests; } const TArray<FlxInputModeRequest> &GetRequests() const { return Requests; }
// Sanity check a request to see if it is reasonable. // Sanity check a request to see if it is reasonable.
static bool SanityCheck(const FlxInputModeRequest &Request); static bool SanityCheck(const FlxInputModeRequest &Request);
// Divide Requests into a high-priority slice and a low-priority slice.
void SplitHighLow(View &High, View &Low);
// Apply a request. Replaces any previous request by the same widget. // Apply a request. Replaces any previous request by the same widget.
void Request(const FlxInputModeRequest &NewRequest); void Request(const FlxInputModeRequest &NewRequest, bool UpdateSequence = true);
// Find the specified widget, and modify the 'EnableInputComponent' // Find the specified widget, and modify the 'EnableInputComponent'
// flag. Adds the widget if it's not already present. // flag. Adds the widget if it's not already present.
@@ -96,4 +88,11 @@ public:
// Remove any requests by dead widgets or widgets with no parents. // Remove any requests by dead widgets or widgets with no parents.
void GarbageCollect(); void GarbageCollect();
private:
// Find specified widget. If not present, returns Requests.Num()
int32 FindWidget(UUserWidget *Widget);
// Move item at Index to its proper place in the array by priority.
void BubbleItem(int32 Index);
}; };