This commit is contained in:
Michael Schimmel
2025-06-06 01:22:25 +02:00
parent 73d656cda5
commit c4d8607d17
13 changed files with 393 additions and 173 deletions
+59 -48
View File
@@ -6,16 +6,16 @@ uses
System.SysUtils;
type
IMycSubscriber = interface
function Notify: Boolean;
end;
TSignal = record
type
ISubscriber = interface
function Notify: Boolean;
end;
TSubscriptionTag = Pointer;
ISignal = interface
function Subscribe(Subscriber: IMycSubscriber): TSubscriptionTag;
function Subscribe(Subscriber: ISubscriber): TSubscriptionTag;
procedure Unsubscribe(Tag: TSubscriptionTag);
end;
@@ -45,38 +45,11 @@ type
class operator Implicit(const A: ISignal): TSignal; overload;
class operator Implicit(const A: TSignal): ISignal; overload;
function Subscribe(Subscriber: IMycSubscriber): TSubscription; inline;
function Subscribe(Subscriber: ISubscriber): TSubscription; inline;
class property Null: ISignal read FNull;
end;
TEvent = record
type
IEvent = interface(TSignal.ISignal)
procedure Trigger;
end;
{$REGION 'private'}
strict private
class var
FNull: IEvent;
class constructor ClassCreate;
private
FEvent: IEvent;
{$ENDREGION}
public
constructor Create(const AEvent: IEvent);
class operator Initialize(out Dest: TEvent);
class operator Implicit(const A: IEvent): TEvent; overload;
class operator Implicit(const A: TEvent): IEvent; overload;
class property Null: IEvent read FNull;
function Subscribe(Subscriber: IMycSubscriber): TSignal.TSubscription; inline;
procedure Unsubscribe(Tag: Pointer); inline;
end;
TState = record
type
IState = interface(TSignal.ISignal)
@@ -108,18 +81,54 @@ type
class property Null: IState read FNull;
function Subscribe(Subscriber: IMycSubscriber): TSignal.TSubscription; inline;
procedure Unsubscribe(Tag: Pointer); inline;
function Subscribe(Subscriber: TSignal.ISubscriber): TSignal.TSubscription; inline;
property IsSet: Boolean read GetIsSet;
end;
// An event is a stateless signal that forwards all notifications to the subscribers.
TEvent = record
type
IEvent = interface(TSignal.ISubscriber)
{$REGION 'property access'}
function GetSignal: TSignal;
{$ENDREGION}
property Signal: TSignal read GetSignal;
end;
{$REGION 'private'}
strict private
class var
FNull: IEvent;
class constructor ClassCreate;
private
FEvent: IEvent;
function GetSignal: TSignal; inline;
{$ENDREGION}
public
constructor Create(const AEvent: IEvent);
class operator Initialize(out Dest: TEvent);
class operator Implicit(const A: IEvent): TEvent; overload;
class operator Implicit(const A: TEvent): IEvent; overload;
class function CreateEvent: TEvent; static;
class property Null: IEvent read FNull;
function Notify: Boolean; inline;
property Signal: TSignal read GetSignal;
end;
// A latch is a specific type of event that, once set, remains set (non-resettable).
// It becomes set when the internal countdown reaches zero.
TLatch = record
type
ILatch = interface(IMycSubscriber)
ILatch = interface(TSignal.ISubscriber)
{$REGION 'property access'}
function GetState: TState;
{$ENDREGION}
property State: TState read GetState;
end;
@@ -153,8 +162,10 @@ type
// TFlag represents a resettable flag, typically indicating if a State is "dirty" (requiring attention) or "clean".
TFlag = record
type
IFlag = interface(IMycSubscriber)
IFlag = interface(TSignal.ISubscriber)
{$REGION 'property access'}
function GetState: TState;
{$ENDREGION}
function Reset: Boolean;
property State: TState read GetState;
end;
@@ -260,16 +271,11 @@ begin
Result := FState.IsSet;
end;
function TState.Subscribe(Subscriber: IMycSubscriber): TSignal.TSubscription;
function TState.Subscribe(Subscriber: TSignal.ISubscriber): TSignal.TSubscription;
begin
Result := TSignal.TSubscription.Create(FState, FState.Subscribe(Subscriber));
end;
procedure TState.Unsubscribe(Tag: Pointer);
begin
FState.Unsubscribe(Tag);
end;
class operator TState.Implicit(const A: TState): IState;
begin
Result := A.FState;
@@ -299,14 +305,19 @@ begin
FNull := TMycNullEvent.Create();
end;
function TEvent.Subscribe(Subscriber: IMycSubscriber): TSignal.TSubscription;
class function TEvent.CreateEvent: TEvent;
begin
Result := TSignal.TSubscription.Create(FEvent, FEvent.Subscribe(Subscriber));
Result := TMycEvent.Create;
end;
procedure TEvent.Unsubscribe(Tag: Pointer);
function TEvent.GetSignal: TSignal;
begin
FEvent.Unsubscribe(Tag);
Result := FEvent.Signal;
end;
function TEvent.Notify: Boolean;
begin
Result := FEvent.Notify;
end;
class operator TEvent.Implicit(const A: TEvent): IEvent;
@@ -443,7 +454,7 @@ begin
FSignal := FNull;
end;
function TSignal.Subscribe(Subscriber: IMycSubscriber): TSubscription;
function TSignal.Subscribe(Subscriber: ISubscriber): TSubscription;
begin
Result := TSubscription.Create(FSignal, FSignal.Subscribe(Subscriber));
end;