Jump to content

Recommended Posts

  • Moderators

A finite state machine. 

The FSM implemented below is taken from this article, which explains link between event based UX and FSM. Worthwhile reading.

Every state is an object and has one or more actions associated. The implementation here uses messaging, which makes it much simpler.

 

type
  idle = class
    procedure click(caption:string);
    Button: TW3Button;
  end;

type
  fetch = class
    procedure fetchResult;
    procedure Success;
    procedure Error;
  end;

type
  error = class
    procedure retry;
  end;

type
  TForm1 = class(TW3Form)
  private
    {$I 'Form1:intf'}
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure Resize; override;
  end;

var State : variant;
var window   external 'window':   variant;

implementation

procedure idle.click(caption:string);
begin
  writeln('click');
  Button := TW3Button.Create(Application.Forms[0]);
  Button.SetBounds(50,50,200,40);
  Button.Caption := caption;
  Button.OnClick := procedure(sender:TObject)
  begin
    State := 'fetch';
    //initiate the fetch, say xmlhttprequest
    window.postMessage([State],'*');
    Button.Destroy;
  end;
end;

procedure Fetch.fetchResult;
begin
  //get fetch return code
  var resultCode : boolean := false;   // or true.
  if resultCode
    then Success
    else Error;
end;

procedure Fetch.Success;
begin
  writeln('success');
  State := '';
  window.postMessage([State],'*');
end;

procedure Fetch.Error;
begin
  writeln('error');
  State := 'error';
  window.postMessage([State],'*');
end;

procedure error.retry;
begin
  writeln('retry');
  State := 'idle';
  window.postMessage([State,'Error : Retry'],'*');
end;

{ TForm1 }

procedure TForm1.InitializeForm;
begin
  inherited;
  // this is a good place to initialize components

  var idleState  := idle.Create;
  var fetchState := fetch.Create;
  var errorState := error.Create;

  State := 'idle';

  window.onmessage := procedure(evt:variant)
  begin
    if evt.data[0] = 'idle'  then idleState.Click(evt.data[1]);
    if evt.data[0] = 'fetch' then fetchState.fetchResult;
    if evt.data[0] = 'error' then errorState.Retry;
  end;

  window.postMessage([State,'Fetch'],'*');

end;

 

 

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...