Wednesday, October 27, 2010

Future, a very handy class

In BB.Synch there is a class called TFuture<T> whose goal is to launch a process and check if the result is available, if so, then get the result. This class is used in ChessKISS twice, once for the search and the other for the Winboard protocol, let's see an easy example.

On a console application:


function GetMessage: string;
var
  msg: AnsiString;
  c: AnsiChar;

begin
  msg := '';
  c := #0;
  repeat
    Read(Input, c);
    msg := msg + c;
  until (c = #13) or (c = #10);
  Delete(msg, Length(msg), 1);  //Delete CR

  Exit(msg);
end;
We have to check if we have receive a command, but this would block the application since we are calling Read(), a solution would be to create a Thread, but doing it is something always tedious, this is where TFuture helps us. Let's create a function that uses the new class, the only thing to do is pass the function as parameter in the constructor.
var
  t: TFuture<string> = nil;

function Process: string;
begin
  result := '';

  if t = nil then
    t := TFuture<string>.Create(GetMessage, tpNormal);

  if t.Available then
  begin
    result := t.GetValue;
    FreeAndNil(t);
  end;
end;
If the variable is null it creates a new task, and then once the result is  available (somebody has send or type a command in the console window), it gets the value, frees the class and return it.

The main process might look like this:


begin
  repeat
    p := Process;
    if p <> '' then
      DoSomethingWithTheValue(p);

    Sleep(500);
  until False;

end.


 Very handy and non blocking class, tip from Primoz Gabrijelcic.

No comments:

Post a Comment