Files
MycLib/Src/Myc.Core.Mutable.pas
2025-07-17 00:48:46 +02:00

210 lines
4.6 KiB
ObjectPascal

unit Myc.Core.Mutable;
interface
uses
System.Classes,
System.SysUtils,
System.SyncObjs,
Myc.Signals,
Myc.Mutable;
type
TMycConstMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable)
private
FValue: T;
function GetChanged: TSignal;
function GetValue: T;
public
constructor Create(AValue: 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, TWriteable<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;
TMycProtectedMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable, TWriteable<T>.IWriteable)
private
FWriteable: TWriteable<T>.IWriteable;
FLock: TLightweightMREW;
protected
function GetChanged: TSignal;
function GetValue: T;
public
constructor Create(const AWriteable: TWriteable<T>.IWriteable);
procedure SetValue(const Value: T);
end;
TMycConstLazy<T> = class(TInterfacedObject, TLazy<T>.ILazy)
private
FValue: T;
function GetChanged: TState;
function Update(var Value: T): Boolean;
public
constructor Create(AValue: T);
end;
implementation
uses
System.Generics.Defaults;
constructor TMycConstMutable<T>.Create(AValue: T);
begin
inherited Create;
FValue := AValue;
end;
{ TMycConstMutable<T> }
function TMycConstMutable<T>.GetChanged: TSignal;
begin
Result := TSignal.Null;
end;
function TMycConstMutable<T>.GetValue: T;
begin
Result := FValue;
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
if not TEqualityComparer<T>.Default.Equals(FValue, Value) then
begin
FValue := Value;
FChanged.Notify;
end;
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;
{ TMycProtectedMutable<T> }
constructor TMycProtectedMutable<T>.Create(const AWriteable: TWriteable<T>.IWriteable);
begin
inherited Create;
FWriteable := AWriteable;
end;
function TMycProtectedMutable<T>.GetChanged: TSignal;
begin
Result := FWriteable.Changed;
end;
function TMycProtectedMutable<T>.GetValue: T;
begin
FLock.BeginRead;
try
Result := FWriteable.Value;
finally
FLock.EndRead;
end;
end;
procedure TMycProtectedMutable<T>.SetValue(const Value: T);
begin
FLock.BeginWrite;
try
FWriteable.SetValue(Value);
finally
Flock.EndWrite;
end;
end;
constructor TMycConstLazy<T>.Create(AValue: T);
begin
inherited Create;
FValue := AValue;
end;
{ TMycConstLazy<T> }
function TMycConstLazy<T>.GetChanged: TState;
begin
Result := TState.Null;
end;
function TMycConstLazy<T>.Update(var Value: T): Boolean;
begin
Result := false;
end;
end.