207 lines
4.5 KiB
ObjectPascal
207 lines
4.5 KiB
ObjectPascal
unit Myc.Core.Lazy;
|
|
|
|
interface
|
|
|
|
uses
|
|
System.SysUtils,
|
|
Myc.Signals,
|
|
Myc.Lazy;
|
|
|
|
type
|
|
TMycNullMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable)
|
|
protected
|
|
function GetChanged: TSignal;
|
|
function GetValue: T;
|
|
end;
|
|
|
|
TMycMutableBase<T> = class(TInterfacedObject, TMutable<T>.IMutable)
|
|
strict private
|
|
FChanged: TEvent;
|
|
FChangeState: TSignal.TSubscription;
|
|
function GetChanged: TSignal;
|
|
protected
|
|
function GetValue: T; virtual; abstract;
|
|
public
|
|
constructor Create(const AChanged: TSignal);
|
|
destructor Destroy; override;
|
|
end;
|
|
|
|
TMycFuncMutable<T> = class(TMycMutableBase<T>)
|
|
private
|
|
FProc: TFunc<T>;
|
|
protected
|
|
function GetValue: T; override;
|
|
public
|
|
constructor Create(const AChanged: TSignal; const AProc: TFunc<T>);
|
|
end;
|
|
|
|
TMycWriteableMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable, TMutable<T>.IWriteable)
|
|
private
|
|
FValue: T;
|
|
FChanged: TEvent;
|
|
protected
|
|
function GetChanged: TSignal;
|
|
function GetValue: T;
|
|
public
|
|
constructor Create(const AValue: T);
|
|
procedure SetValue(const Value: T);
|
|
end;
|
|
|
|
TMycNullLazy<T> = class(TInterfacedObject, TLazy<T>.ILazy)
|
|
protected
|
|
function GetChanged: TState;
|
|
public
|
|
function Pop(out Res: T): Boolean;
|
|
end;
|
|
|
|
TMycLazyBase<T> = class(TInterfacedObject, TLazy<T>.ILazy)
|
|
strict private
|
|
FChanged: TFlag;
|
|
FChangeState: TSignal.TSubscription;
|
|
function GetChanged: TState;
|
|
protected
|
|
function GetValue: T; virtual; abstract;
|
|
public
|
|
constructor Create(const AChanged: TSignal);
|
|
destructor Destroy; override;
|
|
function Pop(out Res: T): Boolean;
|
|
end;
|
|
|
|
TMycFuncLazy<T> = class(TMycLazyBase<T>)
|
|
private
|
|
FProc: TFunc<T>;
|
|
protected
|
|
function GetValue: T; override;
|
|
public
|
|
constructor Create(const AChanged: TSignal.ISignal; const AProc: TFunc<T>);
|
|
end;
|
|
|
|
implementation
|
|
|
|
{ TMycNullMutable<T> }
|
|
|
|
function TMycNullMutable<T>.GetChanged: TSignal;
|
|
begin
|
|
Result := TSignal.Null;
|
|
end;
|
|
|
|
function TMycNullMutable<T>.GetValue: T;
|
|
begin
|
|
Result := Default(T);
|
|
end;
|
|
|
|
{ TMycMutableBase<T> }
|
|
|
|
constructor TMycMutableBase<T>.Create(const AChanged: TSignal);
|
|
begin
|
|
inherited Create;
|
|
FChanged := TEvent.CreateEvent;
|
|
FChangeState := AChanged.Subscribe(FChanged);
|
|
end;
|
|
|
|
destructor TMycMutableBase<T>.Destroy;
|
|
begin
|
|
FChangeState.Unsubscribe;
|
|
inherited;
|
|
end;
|
|
|
|
function TMycMutableBase<T>.GetChanged: TSignal;
|
|
begin
|
|
Result := FChanged.Signal;
|
|
end;
|
|
|
|
{ TMycWriteableMutable<T> }
|
|
|
|
constructor TMycWriteableMutable<T>.Create(const AValue: T);
|
|
begin
|
|
inherited Create;
|
|
FValue := AValue;
|
|
FChanged := TEvent.CreateEvent;
|
|
end;
|
|
|
|
function TMycWriteableMutable<T>.GetChanged: TSignal;
|
|
begin
|
|
Result := FChanged.Signal;
|
|
end;
|
|
|
|
function TMycWriteableMutable<T>.GetValue: T;
|
|
begin
|
|
Result := FValue;
|
|
end;
|
|
|
|
procedure TMycWriteableMutable<T>.SetValue(const Value: T);
|
|
begin
|
|
FValue := Value;
|
|
FChanged.Notify;
|
|
end;
|
|
|
|
{ TMycNullLazy<T> }
|
|
|
|
function TMycNullLazy<T>.GetChanged: TState;
|
|
begin
|
|
Result := TState.Null;
|
|
end;
|
|
|
|
function TMycNullLazy<T>.Pop(out Res: T): Boolean;
|
|
begin
|
|
Res := Default(T);
|
|
Result := true;
|
|
end;
|
|
|
|
{ TMycLazyBase<T> }
|
|
|
|
constructor TMycLazyBase<T>.Create(const AChanged: TSignal);
|
|
begin
|
|
inherited Create;
|
|
FChanged := TFlag.CreateFlag;
|
|
FChangeState := AChanged.Subscribe(FChanged);
|
|
end;
|
|
|
|
destructor TMycLazyBase<T>.Destroy;
|
|
begin
|
|
FChangeState.Unsubscribe;
|
|
inherited;
|
|
end;
|
|
|
|
function TMycLazyBase<T>.GetChanged: TState;
|
|
begin
|
|
Result := FChanged.State;
|
|
end;
|
|
|
|
function TMycLazyBase<T>.Pop(out Res: T): Boolean;
|
|
begin
|
|
Result := FChanged.State.IsSet;
|
|
if Result then
|
|
begin
|
|
Res := GetValue;
|
|
FChanged.Reset;
|
|
end;
|
|
end;
|
|
|
|
{ TMycFuncLazy<T> }
|
|
|
|
constructor TMycFuncLazy<T>.Create(const AChanged: TSignal.ISignal; const AProc: TFunc<T>);
|
|
begin
|
|
inherited Create(AChanged);
|
|
FProc := AProc;
|
|
Assert(Assigned(FProc));
|
|
end;
|
|
|
|
function TMycFuncLazy<T>.GetValue: T;
|
|
begin
|
|
Result := FProc();
|
|
end;
|
|
|
|
constructor TMycFuncMutable<T>.Create(const AChanged: TSignal; const AProc: TFunc<T>);
|
|
begin
|
|
inherited Create(AChanged);
|
|
FProc := AProc;
|
|
end;
|
|
|
|
function TMycFuncMutable<T>.GetValue: T;
|
|
begin
|
|
Result := FProc();
|
|
end;
|
|
|
|
end.
|