Refactoring

This commit is contained in:
Michael Schimmel
2025-06-05 22:59:39 +02:00
parent e06a023742
commit 7ba42b0c7c
13 changed files with 860 additions and 306 deletions
+51 -50
View File
@@ -8,38 +8,46 @@ uses
Myc.Signals;
type
// TMycNullState implements a "null object" pattern for IMycState.
// TMycNullSignal implements a "null object" pattern for IMycState.
// This state is always considered "set".
TMycNullState = class(TInterfacedObject, IMycState)
protected
// IMycState
function GetIsSet: Boolean;
TMycNullSignal = class(TInterfacedObject, IMycSignal)
public
constructor Create;
function Subscribe(Subscriber: IMycSubscriber): Pointer;
procedure Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
end;
// A state that acts as an event. It's state ist always set and it will always notify it's subscribers, if it gets notified by itself.
TMycNotifyEvent = class(TInterfacedObject, IMycState, IMycEvent)
// TMycNullState implements a "null object" pattern for IMycState.
// This state is always considered "set".
TMycNullState = class(TMycNullSignal, IMycState)
protected
// IMycState
function GetIsSet: Boolean;
end;
// A state that acts as an event. It's state ist always set and it will always Trigger it's subscribers, if it gets notified by itself.
TMycEvent = class(TInterfacedObject, IMycSignal, IMycEvent)
strict private
FSubscribers: TMycNotifyList<IMycSubscriber>;
protected
function GetIsSet: Boolean;
function GetState: TState;
public
constructor Create;
destructor Destroy; override;
function Subscribe(Subscriber: IMycSubscriber): Pointer;
procedure Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
function Notify: Boolean;
procedure Trigger;
end;
TMycNullEvent = class(TMycNullSignal, IMycEvent)
private
procedure Trigger;
end;
// TMycLatch implements a countdown latch.
// It is initialized with a count. Calls to its Notify method (as an IMycSubscriber)
// decrement this count. When the count reaches zero, the latch transitions to the "set"
// state (IsSet becomes true), notifies its current subscribers once, and then remains set.
TMycLatch = class(TInterfacedObject, IMycState, IMycEvent)
TMycLatch = class(TInterfacedObject, IMycState, IMycLatch)
strict private
FSubscribers: TMycNotifyList<IMycSubscriber>; // List of subscribers waiting for this latch to be set.
private
@@ -64,7 +72,7 @@ type
function Notify: Boolean;
end;
TMycNullEvent = class(TInterfacedObject, IMycEvent)
TMycNullLatch = class(TInterfacedObject, IMycLatch)
private
function GetState: TState;
function Notify: Boolean;
@@ -113,59 +121,31 @@ implementation
uses
System.SyncObjs; // For TInterlocked
{ TMycNullState }
constructor TMycNullState.Create;
begin
inherited Create;
end;
function TMycNullState.GetIsSet: Boolean;
begin
Result := true; // Null state is always set.
end;
function TMycNullState.Subscribe(Subscriber: IMycSubscriber): Pointer;
begin
// Since the state is always set, notify the subscriber immediately.
if Assigned(Subscriber) then
begin
Subscriber.Notify;
end;
// No ongoing subscription is necessary or meaningful for a null state.
Result := nil;
end;
{ TMycEvent }
procedure TMycNullState.Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
begin
// Unsubscribing from a null state has no effect.
end;
{ TMycNotifyEvent }
constructor TMycNotifyEvent.Create;
constructor TMycEvent.Create;
begin
inherited Create;
FSubscribers.Create;
end;
destructor TMycNotifyEvent.Destroy;
destructor TMycEvent.Destroy;
begin
FSubscribers.Destroy;
inherited;
end;
function TMycNotifyEvent.GetIsSet: Boolean;
function TMycEvent.GetIsSet: Boolean;
begin
Result := true;
end;
function TMycNotifyEvent.GetState: TState;
begin
Result := Self;
end;
function TMycNotifyEvent.Notify: Boolean;
procedure TMycEvent.Trigger;
begin
FSubscribers.Lock;
try
@@ -175,7 +155,7 @@ begin
end;
end;
function TMycNotifyEvent.Subscribe(Subscriber: IMycSubscriber): Pointer;
function TMycEvent.Subscribe(Subscriber: IMycSubscriber): Pointer;
begin
Result := nil;
if not Assigned(Subscriber) then
@@ -190,7 +170,7 @@ begin
end;
end;
procedure TMycNotifyEvent.Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
procedure TMycEvent.Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
begin
if Tag = nil then
exit;
@@ -203,14 +183,14 @@ begin
end;
end;
{ TMycNullEvent }
{ TMycNullLatch }
function TMycNullEvent.GetState: TState;
function TMycNullLatch.GetState: TState;
begin
Result := TState.Null;
end;
function TMycNullEvent.Notify: Boolean;
function TMycNullLatch.Notify: Boolean;
begin
Result := false;
end;
@@ -427,4 +407,25 @@ begin
end;
end;
procedure TMycNullEvent.Trigger;
begin
// nop
end;
function TMycNullSignal.Subscribe(Subscriber: IMycSubscriber): Pointer;
begin
// Since the state is always set, notify the subscriber immediately.
if Assigned(Subscriber) then
begin
Subscriber.Notify;
end;
// No ongoing subscription is necessary or meaningful for a null state.
Result := nil;
end;
procedure TMycNullSignal.Unsubscribe(Tag: TMycNotifyList<IMycSubscriber>.TTag);
begin
// Unsubscribing from a null state has no effect.
end;
end.