unit Myc.Core.Mutable; interface uses System.Classes, System.SysUtils, System.SyncObjs, Myc.Signals, Myc.Mutable; type TMycNullMutable = class(TInterfacedObject, TMutable.IMutable) private FValue: T; function GetChanged: TSignal; function GetValue: T; public constructor Create(AValue: T); end; TMycMutableBase = class(TInterfacedObject, TMutable.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 = class(TMycMutableBase) private FProc: TFunc; protected function GetValue: T; override; public constructor Create(const AChanged: TSignal; const AProc: TFunc); end; TMycWriteableMutable = class(TInterfacedObject, TMutable.IMutable, TWriteable.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 = class(TInterfacedObject, TMutable.IMutable, TWriteable.IWriteable) private FWriteable: TWriteable.IWriteable; FLock: TLightweightMREW; protected function GetChanged: TSignal; function GetValue: T; public constructor Create(const AWriteable: TWriteable.IWriteable); procedure SetValue(const Value: T); end; implementation uses System.Generics.Defaults; constructor TMycNullMutable.Create(AValue: T); begin inherited Create; FValue := AValue; end; { TMycNullMutable } function TMycNullMutable.GetChanged: TSignal; begin Result := TSignal.Null; end; function TMycNullMutable.GetValue: T; begin Result := FValue; end; { TMycMutableBase } constructor TMycMutableBase.Create(const AChanged: TSignal); begin inherited Create; FChanged := TEvent.CreateEvent; FChangeState := AChanged.Subscribe(FChanged); end; destructor TMycMutableBase.Destroy; begin FChangeState.Unsubscribe; inherited; end; function TMycMutableBase.GetChanged: TSignal; begin Result := FChanged.Signal; end; { TMycWriteableMutable } constructor TMycWriteableMutable.Create(const AValue: T); begin inherited Create; FValue := AValue; FChanged := TEvent.CreateEvent; end; function TMycWriteableMutable.GetChanged: TSignal; begin Result := FChanged.Signal; end; function TMycWriteableMutable.GetValue: T; begin Result := FValue; end; procedure TMycWriteableMutable.SetValue(const Value: T); begin if not TEqualityComparer.Default.Equals(FValue, Value) then begin FValue := Value; FChanged.Notify; end; end; constructor TMycFuncMutable.Create(const AChanged: TSignal; const AProc: TFunc); begin inherited Create(AChanged); FProc := AProc; end; function TMycFuncMutable.GetValue: T; begin Result := FProc(); end; { TMycProtectedMutable } constructor TMycProtectedMutable.Create(const AWriteable: TWriteable.IWriteable); begin inherited Create; FWriteable := AWriteable; end; function TMycProtectedMutable.GetChanged: TSignal; begin Result := FWriteable.Changed; end; function TMycProtectedMutable.GetValue: T; begin FLock.BeginRead; try Result := FWriteable.Value; finally FLock.EndRead; end; end; procedure TMycProtectedMutable.SetValue(const Value: T); begin FLock.BeginWrite; try FWriteable.SetValue(Value); finally Flock.EndWrite; end; end; end.