InputModeRequests now use less-than operator to sort
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user