13#include "CoreMinimal.h"
31 template <CDefaultInitializable = T>
34 template <CMoveConstructible = T>
37 template <CCopyConstructible = T>
40 template <CMoveConstructible = T>
43 template <
typename Arg>
44 requires (!CSameAs<Arg, TChangeData> && !CSameAs<Arg, T>)
47 template <
typename... Args>
48 requires (
sizeof...(Args) > 1)
70 virtual T
const&
Get()
const = 0;
79 virtual void Set(T
const& value) = 0;
91 virtual void Modify(TUniqueFunction<
void(T&)>&& modifier,
bool alwaysNotify =
true) = 0;
94 template <CChangeListener<T> Function>
100 onChange(change.Next);
102 onChange(change.Next, change.Previous);
120 template <CChangeListener<T> Function>
136 template <
typename Object, CChangeListener<T> Function>
156 virtual bool Remove(FDelegateHandle
const& handle) = 0;
177 virtual TTuple<T const&, TUniquePtr<ReadLockVariant>>
GetOnAnyThread()
const = 0;
186 virtual TUniquePtr<ReadLockVariant>
ReadLock()
const = 0;
197 template <
typename Self>
198 operator const T& (
this Self&& self)
203 template <
typename Self>
209 template <
typename Self, CConvertibleTo<T> Other>
211 Self&
operator = (
this Self&& self, Other&& value)
213 if constexpr (CCopyable<Other>)
215 else if constexpr (CMovable<Other>)
216 self.Set(MoveTemp(value));
225 template <
typename T,
int32 DefaultPolicy>
228 template <
typename ThreadSafeType,
typename NaiveType>
242 template <CDefaultInitializable = T>
246 template <CCopyConstructible = T>
250 template <CMoveConstructible = T>
251 TState(T&& value) : Value(MoveTemp(value)) {}
254 template <CCopyConstructible = T>
258 template <CMoveConstructible = T>
262 template <
typename Arg>
263 requires (!CConvertibleTo<Arg, TState> && !CSameAs<Arg, T>)
264 TState(Arg&& arg) : Value(Forward<Arg>(arg)) {}
267 template <
typename... Args>
268 requires (
sizeof...(Args) > 1)
269 TState(Args&&... args) : Value(Forward<Args>(args)...) {}
271 virtual T
const&
Get()
const override {
return Value.Next; }
273 virtual TTuple<T const&, TUniquePtr<ReadLockVariant>>
GetOnAnyThread()
const override
278 virtual void Set(T
const& value)
override
281 ->WithMessage(TEXT(
"Attempting to set this state while this state is already being set from somewhere else."))
283 TGuardValue modifyingGuard(Modifying,
true);
285 bool broadcast =
true;
287 if constexpr (CCoreEqualityComparable<T>)
290 if constexpr (CCopyable<T>)
292 Value.Previous = Value.Next;
297 OnChangeEvent.Broadcast(Value);
300 virtual void Modify(TUniqueFunction<
void(T&)>&& modifier,
bool alwaysNotify =
true)
override
303 ->WithMessage(TEXT(
"Attempting to set this state while this state is already being set from somewhere else."))
305 TGuardValue modifyingGuard(Modifying,
true);
307 bool broadcast =
true;
309 if constexpr (CCopyable<T>)
313 Value.Previous = Value.Next;
317 modifier(Value.Next);
319 if constexpr (CCopyable<T> && CCoreEqualityComparable<T>)
320 broadcast = alwaysNotify
323 || !Value.Previous.IsSet()
324 || Value.Previous.GetValue() != Value.Next;
327 OnChangeEvent.Broadcast(Value);
333 return OnChangeEvent.Add(onChange, invokeMode);
336 virtual bool Remove(FDelegateHandle
const& handle)
override
339 return OnChangeEvent.Remove(handle);
345 return OnChangeEvent.RemoveAll(
object);
350 if constexpr (CCoreEqualityComparable<T>)
352 bool hasChanged = Value.Next != nextValue;
365 return OnChangeEvent.IsBroadcasted();
368 virtual TUniquePtr<ReadLockVariant>
ReadLock()
const override
370 return MakeUnique<ReadLockVariant>(TInPlaceType<ReadLockType>(), Mutex.
Get());
373 virtual TUniquePtr<WriteLockVariant>
WriteLock()
override
375 return MakeUnique<WriteLockVariant>(TInPlaceType<WriteLockType>(), Mutex.
Get());
383 bool Modifying =
false;
387 template <
typename LeftValue, CWeaklyEqualityComparableWith<LeftValue> RightValue>
390 return left.
Get() == right.
Get();
393 template <
typename LeftValue, CPartiallyOrderedWith<LeftValue> RightValue>
396 return left.
Get() <=> right.
Get();
#define ASSERT_QUIT(condition, returnOnFailure,...)
TInferredDelegate< Function, Captures... > From(Function func, const Captures &... captures)
bool operator==(IState< LeftValue > const &left, IState< RightValue > const &right)
bool operator<=>(IState< LeftValue > const &left, IState< RightValue > const &right)
virtual FDelegateHandle OnChange(TDelegate< void(TChangeData< T > const &)> onChange, EInvokeMode invokeMode=DefaultInvocation)=0
virtual int32 RemoveAll(const void *object)=0
virtual void Set(T const &value)=0
virtual bool HasEverChanged() const =0
virtual void Modify(TUniqueFunction< void(T &)> &&modifier, bool alwaysNotify=true)=0
TVariant< FWriteScopeLock, FVoid > WriteLockVariant
virtual bool Remove(FDelegateHandle const &handle)=0
virtual bool HasChangedFrom(const T &nextValue)=0
virtual T const & Get() const =0
FDelegateHandle OnChange(Function const &onChange, EInvokeMode invokeMode=DefaultInvocation)
const T * operator->(this Self &&self)
static auto DelegateValueArgument(Function const &onChange, EInvokeMode invokeMode=DefaultInvocation)
FDelegateHandle OnChange(Object &&object, Function const &onChange, EInvokeMode invokeMode=DefaultInvocation)
virtual TUniquePtr< ReadLockVariant > ReadLock() const =0
TVariant< FReadScopeLock, FVoid > ReadLockVariant
virtual TTuple< T const &, TUniquePtr< ReadLockVariant > > GetOnAnyThread() const =0
virtual TUniquePtr< WriteLockVariant > WriteLock()=0
virtual ~IState()=default
TChangeData(Args &&... args)
TChangeData(const TChangeData &from)
TChangeData(TChangeData &&from)
virtual TUniquePtr< WriteLockVariant > WriteLock() override
static constexpr int32 DefaultPolicyFlags
virtual int32 RemoveAll(const void *object) override
virtual void Set(T const &value) override
virtual bool Remove(FDelegateHandle const &handle) override
TState(TState const &other)
virtual void Modify(TUniqueFunction< void(T &)> &&modifier, bool alwaysNotify=true) override
virtual TUniquePtr< ReadLockVariant > ReadLock() const override
std::conditional_t< static_cast< bool >(DefaultPolicy &ThreadSafeState), ThreadSafeType, NaiveType > ThreadSafeSwitch
virtual TTuple< T const &, TUniquePtr< ReadLockVariant > > GetOnAnyThread() const override
virtual bool HasChangedFrom(const T &nextValue) override
ThreadSafeSwitch< FReadScopeLock, FVoid > ReadLockType
ThreadSafeSwitch< FWriteScopeLock, FVoid > WriteLockType
virtual FDelegateHandle OnChange(TDelegate< void(TChangeData< T > const &)> onChange, EInvokeMode invokeMode=DefaultInvocation) override
virtual T const & Get() const override
virtual bool HasEverChanged() const override