TFuture<T>.Result --> TFuture<T>.Value

This commit is contained in:
Michael Schimmel
2025-06-06 12:50:59 +02:00
parent 98de7176c3
commit e7f381bc46
5 changed files with 40 additions and 40 deletions
+5 -5
View File
@@ -11,13 +11,13 @@ uses
type
TMycFuture<T> = class abstract(TInterfacedObject, TFuture<T>.IFuture)
protected
function GetResult: T; virtual; abstract;
function GetValue: T; virtual; abstract;
function GetDone: TState; virtual; abstract;
end;
TMycNullFuture<T> = class(TMycFuture<T>)
protected
function GetResult: T; override;
function GetValue: T; override;
function GetDone: TState; override;
end;
@@ -27,7 +27,7 @@ type
FDone: TLatch.ILatch;
FResult: T;
protected
function GetResult: T; override;
function GetValue: T; override;
function GetDone: TState; override;
public
constructor Create(const ATaskManager: IMycTaskManager; const AGate: TState.IState; AProc: TFunc<T>);
@@ -43,7 +43,7 @@ begin
Result := TState.Null;
end;
function TMycNullFuture<T>.GetResult: T;
function TMycNullFuture<T>.GetValue: T;
begin
Result := Default(T);
end;
@@ -90,7 +90,7 @@ begin
Result := FDone.State;
end;
function TMycGateFuncFuture<T>.GetResult: T;
function TMycGateFuncFuture<T>.GetValue: T;
begin
Assert(FDone.State.IsSet, 'Result is not yet available.');
Result := FResult;
+10 -10
View File
@@ -8,16 +8,16 @@ uses
Myc.TaskManager;
type
// Represents the eventual result of an asynchronous operation.
// Represents the eventual Value of an asynchronous operation.
TFuture<T> = record
type
IFuture = interface
{$REGION 'property access'}
function GetResult: T;
function GetValue: T;
function GetDone: TState;
{$ENDREGION}
// Provides access to the computed result.
property Result: T read GetResult;
// Provides access to the computed Value.
property Value: T read GetValue;
// Provides access to the completion state.
property Done: TState read GetDone;
end;
@@ -33,7 +33,7 @@ type
private
FFuture: IFuture;
function GetDone: TState; inline;
function GetResult: T; inline;
function GetValue: T; inline;
{$ENDREGION}
public
constructor Create(const AFuture: IFuture);
@@ -51,7 +51,7 @@ type
function WaitFor: T;
property Done: TState read GetDone;
property Result: T read GetResult;
property Value: T read GetValue;
end;
implementation
@@ -81,7 +81,7 @@ end;
function TFuture<T>.Chain<S>(const Proc: TFunc<T, S>): TFuture<S>;
begin
var Cap := FFuture;
Result := TFuture<S>.Construct(FFuture.Done, function: S begin Result := Proc(Cap.Result); end);
Result := TFuture<S>.Construct(FFuture.Done, function: S begin Result := Proc(Cap.Value); end);
end;
class function TFuture<T>.Construct(const Proc: TFunc<T>): TFuture<T>;
@@ -99,15 +99,15 @@ begin
Result := FFuture.Done;
end;
function TFuture<T>.GetResult: T;
function TFuture<T>.GetValue: T;
begin
Result := FFuture.Result;
Result := FFuture.Value;
end;
function TFuture<T>.WaitFor: T;
begin
TaskManager.WaitFor(FFuture.Done);
Result := FFuture.Result;
Result := FFuture.Value;
end;
class operator TFuture<T>.Implicit(const A: IFuture): TFuture<T>;
+4 -4
View File
@@ -462,19 +462,19 @@ begin // Start of LoadDataSeries
begin
var tickList := TList<TDataPoint>.Create;
try
var totalTicks := Length(liveData.Result);
var totalTicks := Length(liveData.Value);
var overallLastTabTickTime := 0.0;
for var P in loadedFiles do
Inc(totalTicks, Length(P.Result));
Inc(totalTicks, Length(P.Value));
tickList.Capacity := totalTicks;
for var P in loadedFiles do
begin
if Length(P.Result) > 0 then
if Length(P.Value) > 0 then
begin
for var iterTickData in P.Result do
for var iterTickData in P.Value do
if iterTickData.OADateTime > overallLastTabTickTime then
begin
tickList.Add(iterTickData);
+8 -8
View File
@@ -114,7 +114,7 @@ begin
Assert.IsTrue(LFuture.Done.IsSet, 'Future should be marked as done.'); // Accesses TState.IState.IsSet [cite: 57, 194, 312]
Assert.AreEqual(1, FProcExecutionCount, 'AProc should have been executed once.');
LResultValue := LFuture.GetResult; // Accesses IFuture.GetResult
LResultValue := LFuture.GetValue; // Accesses IFuture.GetResult
Assert.AreEqual(CExpectedResult, LResultValue, 'GetResult returned an unexpected value.');
end;
@@ -149,7 +149,7 @@ begin
Assert.IsTrue(LFuture.Done.IsSet, 'Future should be marked as done after init state trigger.');
Assert.AreEqual(1, FProcExecutionCount, 'AProc should have been executed once after init state.');
LResultValue := LFuture.GetResult;
LResultValue := LFuture.Value;
Assert.AreEqual(CExpectedResult, LResultValue, 'GetResult returned an unexpected value after delayed init.');
end;
@@ -191,7 +191,7 @@ begin
Assert.IsTrue(LFuture.Done.IsSet, 'Future should be done even if AProc raised an exception.');
Assert.AreEqual(1, FProcExecutionCount, 'AProc (which raised) should have been executed once.');
LResultValue := LFuture.GetResult;
LResultValue := LFuture.Value;
Assert.AreEqual(Default(Integer), LResultValue, 'GetResult should return Default(T) when AProc raises an exception.');
if not LExpectedExceptionRaisedByFactory then
@@ -237,13 +237,13 @@ begin
Assert.IsFalse(LFuture.Done.IsSet, 'Future should not be marked as done initially.');
Assert.WillRaise(procedure begin LFuture.GetResult; end);
Assert.WillRaise(procedure begin LFuture.Value; end);
LInitLatch.Notify;
FTaskFactory.WaitFor(LFuture.Done);
Assert.WillNotRaise(procedure begin LFuture.GetResult; end);
Assert.WillNotRaise(procedure begin LFuture.Value; end);
end;
procedure TTestMycGateFuncFuture.Test_FanIn_OneFutureWaitsForMultipleOthers;
@@ -326,7 +326,7 @@ begin
Assert.IsTrue(LGateLatch.State.IsSet, 'GateLatch should be set after both prerequisites.');
Assert.IsTrue(LMainFuture.Done.IsSet, 'MainFuture should be done now.');
Assert.AreEqual(12, FProcExecutionCount, 'All AProcs (PF1, PF2, Main) should have run.'); // 1+1+10
Assert.AreEqual(CMainFutureResult, LMainFuture.GetResult, 'MainFuture returned an unexpected result.');
Assert.AreEqual(CMainFutureResult, LMainFuture.Value, 'MainFuture returned an unexpected result.');
// Clean up subscriptions explicitly, though ARC + managed records handle much
Subscriptions[1].Unsubscribe; // [cite: 52, 186, 304]
@@ -387,8 +387,8 @@ begin
Assert.IsTrue(LFlagFutureARan, 'FutureA AProc should have run.');
Assert.IsTrue(LFlagFutureBRan, 'FutureB AProc should have run.');
Assert.AreEqual(2, Self.FSharedCounter, 'Both future AProcs should have incremented the counter.');
Assert.AreEqual(100, LFutureA.GetResult, 'FutureA GetResult value mismatch.');
Assert.AreEqual(200, LFutureB.GetResult, 'FutureB GetResult value mismatch.');
Assert.AreEqual(100, LFutureA.Value, 'FutureA Value value mismatch.');
Assert.AreEqual(200, LFutureB.Value, 'FutureB Value value mismatch.');
end;
initialization
+13 -13
View File
@@ -87,7 +87,7 @@ begin
fut.WaitFor(); // Wait for the future to complete its execution [cite: 148]
Assert.IsTrue(fut.Done.IsSet, 'Future.Done.IsSet should be true after completion.'); // Static string [cite: 148]
resultValue := fut.Result; // Retrieve the result of the future [cite: 148]
resultValue := fut.Value; // Retrieve the result of the future [cite: 148]
Assert.AreEqual(42, resultValue, 'The result of the future is not the expected value.'); // Static string
end;
@@ -112,7 +112,7 @@ begin
fut.WaitFor(); // [cite: 148]
Assert.IsTrue(fut.Done.IsSet, 'Future.Done.IsSet should be true for nil gate construct.'); // Static string [cite: 148]
resultValue := fut.Result; // [cite: 148]
resultValue := fut.Value; // [cite: 148]
Assert.AreEqual(43, resultValue, 'Future result is incorrect for nil gate construct.'); // Static string
end;
@@ -140,7 +140,7 @@ begin
fut.WaitFor(); // [cite: 148]
Assert.IsTrue(fut.Done.IsSet, 'Future.Done.IsSet should be true for preset gate construct.'); // Static string [cite: 148]
resultValue := fut.Result; // [cite: 148]
resultValue := fut.Value; // [cite: 148]
Assert.AreEqual(44, resultValue, 'Future result is incorrect for preset gate construct.'); // Static string
end;
@@ -176,7 +176,7 @@ begin
Assert.IsTrue(delayedGate.State.IsSet, 'The delayed gate should be set after Notify.'); // Static string [cite: 59, 55]
Assert.IsTrue(fut.Done.IsSet, 'Future.Done.IsSet should be true after the delayed gate is triggered.');
// Static string [cite: 148, 55]
resultValue := fut.Result; // [cite: 148]
resultValue := fut.Value; // [cite: 148]
Assert.AreEqual(45, resultValue, 'Future result is incorrect for delayed gate construct.'); // Static string
end;
@@ -211,7 +211,7 @@ begin
fut2.WaitFor(); // Wait for the chained future to complete [cite: 148]
Assert.IsTrue(fut2.Done.IsSet, 'Chained Future.Done.IsSet should be true after completion.'); // Static string [cite: 148, 55]
resultValue := fut2.Result; // [cite: 148]
resultValue := fut2.Value; // [cite: 148]
Assert.AreEqual('Value: 100', resultValue, 'Chained Future result is incorrect.'); // Static string
end;
@@ -254,7 +254,7 @@ begin
Assert.IsTrue(fut1.Done.IsSet, 'Initial future (gated) should be done after gate is set.'); // Static string [cite: 148, 55]
Assert.IsTrue(fut2.Done.IsSet, 'Chained future (gated) should be done after gate is set.'); // Static string [cite: 148, 55]
resultValue := fut2.Result; // [cite: 148]
resultValue := fut2.Value; // [cite: 148]
Assert.AreEqual('ChainVal: 200', resultValue, 'Chained future (gated) result is incorrect.'); // Static string
end;
@@ -303,7 +303,7 @@ begin
Assert.IsTrue(futB.Done.IsSet, 'Future B in chain should be done.'); // Static string [cite: 148, 55]
Assert.IsTrue(futC.Done.IsSet, 'Future C (multi-chained) should be done.'); // Static string [cite: 148, 55]
finalResult := futC.Result; // [cite: 148]
finalResult := futC.Value; // [cite: 148]
// Ensure FloatToStr conversion is consistent for comparison
Assert.AreEqual('Final: ' + FloatToStr(25.0), finalResult, 'Multi-chained Future result is incorrect.'); // Static string
end;
@@ -330,7 +330,7 @@ begin
fut.WaitFor(); // [cite: 148]
Assert.IsTrue(fut.Done.IsSet, 'Parametric Future.Done.IsSet should be true.'); // Static string [cite: 148, 55]
resultValue := fut.Result; // [cite: 148]
resultValue := fut.Value; // [cite: 148]
Assert.AreEqual(ParamValue, resultValue, 'Parametric Future result does not match input parameter.'); // Static string
end;
@@ -396,7 +396,7 @@ begin
// Static string [cite: 148, 55]
if Futures[i].Done.IsSet then // Additional check to safely access Result
begin
Assert.AreEqual(i, Futures[i].Result, 'A future''s result was incorrect in State.All stress test.');
Assert.AreEqual(i, Futures[i].Value, 'A future''s result was incorrect in State.All stress test.');
// Static string [cite: 148]
end;
end;
@@ -511,13 +511,13 @@ begin
outerFuture.WaitFor(); // Wait for the outer future to complete and yield the inner future [cite: 148]
Assert.IsTrue(outerFuture.Done.IsSet, 'Outer future should be done after WaitFor.'); // Static string [cite: 148, 55]
innerFuture := outerFuture.Result; // Retrieve the inner future [cite: 148]
innerFuture := outerFuture.Value; // Retrieve the inner future [cite: 148]
Assert.IsNotNull(innerFuture.Done, 'Inner future (from outer.Result) should have a non-nil Done state.'); // Static string [cite: 148]
innerFuture.WaitFor(); // Wait for the inner future to complete and yield the final result [cite: 148]
Assert.IsTrue(innerFuture.Done.IsSet, 'Inner future should be done after its WaitFor.'); // Static string [cite: 148, 55]
finalResult := innerFuture.Result; // Retrieve the final integer result [cite: 148]
finalResult := innerFuture.Value; // Retrieve the final integer result [cite: 148]
Assert.AreEqual(123, finalResult, 'Nested future final result from Construct is incorrect.'); // Static string
end;
@@ -561,14 +561,14 @@ begin
outerChainedFuture.WaitFor(); // Wait for initialFuture to complete AND the chain function to execute [cite: 148]
Assert.IsTrue(outerChainedFuture.Done.IsSet, 'Outer chained future should be done after WaitFor.'); // Static string [cite: 148, 55]
innerStringFuture := outerChainedFuture.Result; // Get the Future<string> produced by the chain function [cite: 148]
innerStringFuture := outerChainedFuture.Value; // Get the Future<string> produced by the chain function [cite: 148]
Assert.IsNotNull(innerStringFuture.Done, 'Inner string future (from chain) should have a non-nil Done state.');
// Static string [cite: 148]
innerStringFuture.WaitFor(); // Wait for the inner Future<string> to complete [cite: 148]
Assert.IsTrue(innerStringFuture.Done.IsSet, 'Inner string future should be done after its WaitFor.'); // Static string [cite: 148, 55]
finalResult := innerStringFuture.Result; // Get the final string result [cite: 148]
finalResult := innerStringFuture.Value; // Get the final string result [cite: 148]
Assert.AreEqual('Value: 77', finalResult, 'Nested future (via Chain) final result is incorrect.'); // Static string
end;