ProtectedMutable

This commit is contained in:
Michael Schimmel
2025-06-25 10:44:33 +02:00
parent e1159e883b
commit dce0d83e18
6 changed files with 110 additions and 100 deletions
+41 -22
View File
@@ -46,6 +46,7 @@ type
function GetChanged: TSignal;
function GetValue: T;
function GetWriter: TMutable<T>.IWriter;
function Exchange(const Value: T): T;
public
constructor Create(const AValue: T);
procedure SetValue(const Value: T);
@@ -80,19 +81,19 @@ type
constructor Create(const AChanged: TSignal.ISignal; const AProc: TFunc<T>);
end;
TMycProtectedWriteableMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable, TMutable<T>.IWriter)
TMycProtectedMutable<T> = class(TInterfacedObject, TMutable<T>.IMutable, TMutable<T>.IWriter)
private
FValue: T;
FChanged: TEvent;
FMutable: TMutable<T>.IMutable;
FLock: Integer;
protected
function Exchange(const Value: T): T;
function GetChanged: TSignal;
function GetValue: T;
function GetWriter: TMutable<T>.IWriter;
procedure Lock; inline;
procedure Release; inline;
public
constructor Create(const AValue: T);
constructor Create(const AMutable: TMutable<T>.IMutable);
procedure SetValue(const Value: T);
end;
@@ -149,6 +150,12 @@ begin
FChanged := TEvent.CreateEvent;
end;
function TMycWriteableMutable<T>.Exchange(const Value: T): T;
begin
Result := FValue;
FValue := Value;
end;
function TMycWriteableMutable<T>.GetChanged: TSignal;
begin
Result := FChanged.Signal;
@@ -239,52 +246,64 @@ begin
Result := FProc();
end;
{ TMycProtectedWriteableMutable<T> }
{ TMycProtectedMutable<T> }
constructor TMycProtectedWriteableMutable<T>.Create(const AValue: T);
constructor TMycProtectedMutable<T>.Create(const AMutable: TMutable<T>.IMutable);
begin
inherited Create;
FValue := AValue;
FChanged := TEvent.CreateEvent;
FMutable := AMutable;
end;
function TMycProtectedWriteableMutable<T>.GetChanged: TSignal;
begin
Result := FChanged.Signal;
end;
function TMycProtectedWriteableMutable<T>.GetValue: T;
function TMycProtectedMutable<T>.Exchange(const Value: T): T;
begin
Lock;
try
Result := FValue;
Assert(FMutable.Writer <> nil);
FMutable.Writer.Exchange(Value);
finally
Release;
end;
end;
function TMycProtectedWriteableMutable<T>.GetWriter: TMutable<T>.IWriter;
function TMycProtectedMutable<T>.GetChanged: TSignal;
begin
Result := Self;
Result := FMutable.Changed;
end;
procedure TMycProtectedWriteableMutable<T>.Lock;
function TMycProtectedMutable<T>.GetValue: T;
begin
Lock;
try
Result := FMutable.Value;
finally
Release;
end;
end;
function TMycProtectedMutable<T>.GetWriter: TMutable<T>.IWriter;
begin
Result := nil;
if FMutable.Writer <> nil then
Result := Self;
end;
procedure TMycProtectedMutable<T>.Lock;
begin
while AtomicExchange(FLock, 1) = 1 do
YieldProcessor;
end;
procedure TMycProtectedWriteableMutable<T>.Release;
procedure TMycProtectedMutable<T>.Release;
begin
AtomicExchange(FLock, 0);
end;
procedure TMycProtectedWriteableMutable<T>.SetValue(const Value: T);
procedure TMycProtectedMutable<T>.SetValue(const Value: T);
begin
Lock;
try
FValue := Value;
FChanged.Notify;
Assert(FMutable.Writer <> nil);
FMutable.Writer.SetValue(Value);
finally
Release;
end;