Refactoring IState - ISignal

This commit is contained in:
Michael Schimmel
2025-06-24 09:24:37 +02:00
parent a3da63ad6a
commit 6ea0f94e36
11 changed files with 120 additions and 118 deletions
+34 -44
View File
@@ -25,7 +25,6 @@ type
FTag: TSubscriptionTag;
constructor Create(const ASignal: ISignal; ATag: TSubscriptionTag);
public
class operator Initialize(out Dest: TSubscription);
// Unsubscribes from the associated signal
procedure Unsubscribe;
end;
@@ -52,12 +51,14 @@ type
TState = record
type
IState = interface(TSignal.ISignal)
IState = interface
{$REGION 'property access'}
function GetIsSet: Boolean;
function GetSignal: TSignal;
{$ENDREGION}
// IsSet is true if the TState has been reached or the condition is met.
property IsSet: Boolean read GetIsSet;
property Signal: TSignal read GetSignal;
end;
{$REGION 'private'}
@@ -69,7 +70,7 @@ type
private
FState: IState;
function GetIsSet: Boolean; inline;
function GetAsSignal: TSignal; inline;
function GetSignal: TSignal; inline;
{$ENDREGION}
public
constructor Create(const AState: IState);
@@ -80,15 +81,12 @@ type
class function All(const States: TArray<TState>): TState; static;
class function Any(const States: TArray<TState>): TState; static;
class property Null: IState read FNull;
function Subscribe(Subscriber: TSignal.ISubscriber): TSignal.TSubscription; inline;
property IsSet: Boolean read GetIsSet;
class property Null: IState read FNull;
// Explicitly cast a state to a signal. This is dangerous, use with care!
// States only notify, when they change. This behaviour is obscured by treating it like a signal.
property AsSignal: TSignal read GetAsSignal;
property IsSet: Boolean read GetIsSet;
property Signal: TSignal read GetSignal;
end;
// An event is a stateless signal that forwards all notifications to the subscribers.
@@ -195,7 +193,7 @@ type
class operator Implicit(const A: IFlag): TFlag; overload;
class operator Implicit(const A: TFlag): IFlag; overload;
class function CreateFlag: TFlag; static;
class function CreateFlag(Init: Boolean = false): TFlag; static;
class function CreateObserver(const Signal: TSignal): TFlag; static;
class property Null: IFlag read FNull;
@@ -222,24 +220,20 @@ end;
procedure TSignal.TSubscription.Unsubscribe;
begin
FSignal.Unsubscribe(FTag);
FSignal := TSignal.Null;
if Assigned(FSignal) then
begin
FSignal.Unsubscribe(FTag);
FSignal := TSignal.Null;
end;
FTag := nil;
end;
class operator TSignal.TSubscription.Initialize(out Dest: TSubscription);
begin
Dest.FSignal := TSignal.Null;
Dest.FTag := nil;
end;
{ TState }
constructor TState.Create(const AState: IState);
begin
FState := AState;
if not Assigned(FState) then
FState := FNull;
if Assigned(AState) then
FState := AState;
end;
class constructor TState.ClassCreate;
@@ -253,8 +247,8 @@ var
Latch: TLatch.ILatch;
begin
Latch := TLatch.CreateLatch(Length(States));
for var i := 0 to High(States) do
States[i].Subscribe(Latch);
for var state in States do
state.Signal.Subscribe(Latch);
Result := Latch.State;
end;
@@ -269,15 +263,15 @@ begin
else
begin
Latch := TLatch.CreateLatch(1);
for var i := 0 to High(States) do
States[i].Subscribe(Latch);
for var state in States do
state.Signal.Subscribe(Latch);
Result := Latch.State;
end;
end;
function TState.GetAsSignal: TSignal;
function TState.GetSignal: TSignal;
begin
Result := FState;
Result := FState.Signal;
end;
function TState.GetIsSet: Boolean;
@@ -287,7 +281,7 @@ end;
function TState.Subscribe(Subscriber: TSignal.ISubscriber): TSignal.TSubscription;
begin
Result := TSignal.TSubscription.Create(FState, FState.Subscribe(Subscriber));
Result := Signal.Subscribe(Subscriber);
end;
class operator TState.Implicit(const A: TState): IState;
@@ -309,9 +303,8 @@ end;
constructor TEvent.Create(const AEvent: IEvent);
begin
FEvent := AEvent;
if not Assigned(FEvent) then
FEvent := FNull;
if Assigned(AEvent) then
FEvent := AEvent;
end;
class constructor TEvent.ClassCreate;
@@ -363,14 +356,13 @@ end;
constructor TFlag.Create(const AFlag: IFlag);
begin
FFlag := AFlag;
if not Assigned(FFlag) then
FFlag := FNull;
if Assigned(AFlag) then
FFlag := AFlag;
end;
class function TFlag.CreateFlag: TFlag;
class function TFlag.CreateFlag(Init: Boolean = false): TFlag;
begin
Result := TMycFlag.Create;
Result := TMycFlag.Create( Init );
end;
class function TFlag.CreateObserver(const Signal: TSignal): TFlag;
@@ -419,9 +411,8 @@ end;
constructor TLatch.Create(const ALatch: TLatch.ILatch);
begin
FLatch := ALatch;
if not Assigned(FLatch) then
FLatch := FNull;
if Assigned(ALatch) then
FLatch := ALatch;
end;
class function TLatch.CreateLatch(Count: Integer): ILatch;
@@ -445,7 +436,7 @@ begin
until AtomicCmpExchange(FQueueLock, 1, 0) = 0;
try
Gate.State.Subscribe(Latch);
Gate.State.Signal.Subscribe(Latch);
Gate := Latch;
Result := Latch.State;
finally
@@ -466,7 +457,7 @@ begin
until AtomicCmpExchange(FQueueLock, 1, 0) = 0;
try
FLatch.State.Subscribe(Latch);
FLatch.State.Signal.Subscribe(Latch);
FLatch := Latch;
Result := FLatch.State;
finally
@@ -508,9 +499,8 @@ end;
constructor TSignal.Create(const ASignal: ISignal);
begin
FSignal := ASignal;
if not Assigned(FSignal) then
FSignal := FNull;
if Assigned(FSignal) then
FSignal := ASignal;
end;
function TSignal.Subscribe(Subscriber: ISubscriber): TSubscription;