Test Refactoring of signals
This commit is contained in:
+101
-26
@@ -8,38 +8,61 @@ uses
|
||||
Myc.Lazy;
|
||||
|
||||
type
|
||||
TMycLazy<T> = class abstract(TInterfacedObject, IMycLazy<T>)
|
||||
TMycNullLazy<T> = class(TInterfacedObject, IMycLazy<T>)
|
||||
protected
|
||||
function GetChanged: IMycState; virtual; abstract;
|
||||
function GetChanged: TState;
|
||||
public
|
||||
function Pop(out Res: T): Boolean; virtual; abstract;
|
||||
function Pop(out Res: T): Boolean;
|
||||
end;
|
||||
|
||||
TMycNullLazy<T> = class(TMycLazy<T>)
|
||||
protected
|
||||
function GetChanged: IMycState; override;
|
||||
public
|
||||
function Pop(out Res: T): Boolean; override;
|
||||
end;
|
||||
|
||||
TMycFuncLazy<T> = class(TMycLazy<T>)
|
||||
private
|
||||
FChanged: IMycDirty;
|
||||
TMycLazyBase<T> = class(TInterfacedObject, IMycLazy<T>)
|
||||
strict private
|
||||
FChanged: TFlag;
|
||||
FChangeState: TState.TSubscription;
|
||||
function GetChanged: TState;
|
||||
protected
|
||||
function GetValue: T; virtual; abstract;
|
||||
public
|
||||
constructor Create(const AChanged: TState);
|
||||
destructor Destroy; override;
|
||||
function Pop(out Res: T): Boolean;
|
||||
end;
|
||||
|
||||
TMycFuncLazy<T> = class(TMycLazyBase<T>)
|
||||
private
|
||||
FProc: TFunc<T>;
|
||||
protected
|
||||
function GetChanged: IMycState; override;
|
||||
function GetValue: T; override;
|
||||
public
|
||||
constructor Create(const AChanged: TState; const AProc: TFunc<T>);
|
||||
destructor Destroy; override;
|
||||
function Pop(out Res: T): Boolean; override;
|
||||
end;
|
||||
|
||||
TMycChainedLazy<T> = class(TMycLazyBase<T>)
|
||||
private
|
||||
FValue: IMycLazy<T>;
|
||||
protected
|
||||
function GetValue: T; override;
|
||||
public
|
||||
constructor Create(const AValue: IMycLazy<T>);
|
||||
end;
|
||||
|
||||
TMycMutable<T> = class(TInterfacedObject, IMycLazy<T>, IMycMutable<T>)
|
||||
private
|
||||
FNotifier: TEvent;
|
||||
FValue: T;
|
||||
protected
|
||||
function GetChanged: TState;
|
||||
public
|
||||
constructor Create;
|
||||
function Pop(out Res: T): Boolean;
|
||||
procedure SendValue(const Value: T);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TMycNullLazy<T> }
|
||||
|
||||
function TMycNullLazy<T>.GetChanged: IMycState;
|
||||
function TMycNullLazy<T>.GetChanged: TState;
|
||||
begin
|
||||
Result := TState.Null;
|
||||
end;
|
||||
@@ -50,36 +73,88 @@ begin
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
{ TMycFuncLazy<T> }
|
||||
{ TMycLazyBase<T> }
|
||||
|
||||
constructor TMycFuncLazy<T>.Create(const AChanged: TState; const AProc: TFunc<T>);
|
||||
constructor TMycLazyBase<T>.Create(const AChanged: TState);
|
||||
begin
|
||||
inherited Create;
|
||||
FChanged := TDirty.Construct;
|
||||
FProc := AProc;
|
||||
FChanged := TFlag.CreateFlag;
|
||||
FChangeState := AChanged.Subscribe(FChanged);
|
||||
end;
|
||||
|
||||
destructor TMycFuncLazy<T>.Destroy;
|
||||
destructor TMycLazyBase<T>.Destroy;
|
||||
begin
|
||||
FChangeState.Unsubscribe;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TMycFuncLazy<T>.GetChanged: IMycState;
|
||||
function TMycLazyBase<T>.GetChanged: TState;
|
||||
begin
|
||||
Result := FChanged.State;
|
||||
end;
|
||||
|
||||
function TMycFuncLazy<T>.Pop(out Res: T): Boolean;
|
||||
function TMycLazyBase<T>.Pop(out Res: T): Boolean;
|
||||
begin
|
||||
Result := FChanged.State.IsSet;
|
||||
if Result then
|
||||
begin
|
||||
if Assigned(FProc) then
|
||||
Res := FProc;
|
||||
Res := GetValue;
|
||||
FChanged.Reset;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TMycFuncLazy<T> }
|
||||
|
||||
constructor TMycFuncLazy<T>.Create(const AChanged: TState; const AProc: TFunc<T>);
|
||||
begin
|
||||
inherited Create( AChanged );
|
||||
FProc := AProc;
|
||||
Assert( Assigned(FProc) );
|
||||
end;
|
||||
|
||||
function TMycFuncLazy<T>.GetValue: T;
|
||||
begin
|
||||
Result := FProc();
|
||||
end;
|
||||
|
||||
{ TMycChainedLazy<T> }
|
||||
|
||||
constructor TMycChainedLazy<T>.Create(const AValue: IMycLazy<T>);
|
||||
begin
|
||||
inherited Create( AValue.Changed );
|
||||
FValue := AValue;
|
||||
end;
|
||||
|
||||
function TMycChainedLazy<T>.GetValue: T;
|
||||
begin
|
||||
if not FValue.Pop( Result ) then
|
||||
raise Exception.Create('Lazy chain already popped');
|
||||
end;
|
||||
|
||||
{ TMycMutable<T> }
|
||||
|
||||
constructor TMycMutable<T>.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
FNotifier := TEvent.CreateNotifier;
|
||||
FValue := Default(T);
|
||||
end;
|
||||
|
||||
function TMycMutable<T>.GetChanged: TState;
|
||||
begin
|
||||
Result := FNotifier.State;
|
||||
end;
|
||||
|
||||
function TMycMutable<T>.Pop(out Res: T): Boolean;
|
||||
begin
|
||||
Res := FValue;
|
||||
exit(true);
|
||||
end;
|
||||
|
||||
procedure TMycMutable<T>.SendValue(const Value: T);
|
||||
begin
|
||||
FValue := Value;
|
||||
FNotifier.Notify;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user