Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Stateless - StateMachine für Delphi (https://www.delphipraxis.net/186504-stateless-statemachine-fuer-delphi.html)

Sir Rufo 7. Sep 2015 23:48

Stateless - StateMachine für Delphi
 
Unter GITHUB: A simple library for creating state machines in DELPHI code habe ich einen Delphi-Port von GITHUB: A simple library for creating state machines in C# code veröffentlicht.

Unittests und Beispiele inklusive.

Der Code sollte ab Delphi XE2+ einfach so verwendet werden können.

Hier ein kleines Beispiel
Delphi-Quellcode:
program PhoneCall;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.Diagnostics,
  System.SysUtils,
  Stateless;

{$SCOPEDENUMS ON}

type
  State     = ( OffHook, Ringing, Connected, Active, OnHold, PhoneDestroyed );
  Trigger   = ( CallDialed, HungUp, CallConnected, LeftMessage, PlacedOnHold, TakenOffHold, PhoneHurledAgainstWall );
  TPhoneCall = TStateMachine<State, Trigger>;

procedure ConfigurePhoneCall( PhoneCall: TPhoneCall );
var
  LCallTimer: TStopwatch;
begin
  PhoneCall.Configure( State.OffHook )
  {} .Permit( Trigger.CallDialed, State.Ringing );

  PhoneCall.Configure( State.Ringing )
  {} .Permit( Trigger.HungUp, State.OffHook )
  {} .Permit( Trigger.CallConnected, State.Active );

  PhoneCall.Configure( State.Connected )
  {} .Permit( Trigger.HungUp, State.OffHook )
  {} .OnEntry(
    procedure( t: TPhoneCall.TTransition )
    begin
      LCallTimer := TStopwatch.StartNew;
    end )
  {} .OnExit(
    procedure( t: TPhoneCall.TTransition )
    begin
      LCallTimer.Stop;
      WriteLn( 'Duration: ', LCallTimer.ElapsedMilliseconds, 'ms' );
    end );

  PhoneCall.Configure( State.Active )
  {} .SubstateOf( State.Connected )
  {} .Permit( Trigger.LeftMessage, State.OffHook )
  {} .Permit( Trigger.PlacedOnHold, State.OnHold );

  PhoneCall.Configure( State.OnHold )
  {} .SubstateOf( State.Connected )
  {} .Permit( Trigger.TakenOffHold, State.Active )
  {} .Permit( Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed );
end;

procedure Test;
var
  LCall: TPhoneCall;
begin
  LCall := TPhoneCall.Create( State.OffHook );
  try
    ConfigurePhoneCall( LCall );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.CallDialed );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.CallConnected );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.PlacedOnHold );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.TakenOffHold );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.PlacedOnHold );
    WriteLn( LCall.ToString );

    LCall.Fire( Trigger.HungUp );
    WriteLn( LCall.ToString );

  finally
    LCall.Free;
  end;
end;

begin
  try
    Test;
  except
    on E: Exception do
      WriteLn( E.ClassName, ': ', E.Message );
  end;
  ReadLn;

end.
Und die Ausgabe:
Code:
StateMachine { State = OffHook, PermittedTriggers = { CallDialed } }
StateMachine { State = Ringing, PermittedTriggers = { HungUp, CallConnected } }
StateMachine { State = Active, PermittedTriggers = { PlacedOnHold, LeftMessage, HungUp } }
StateMachine { State = OnHold, PermittedTriggers = { TakenOffHold, PhoneHurledAgainstWall, HungUp } }
StateMachine { State = Active, PermittedTriggers = { PlacedOnHold, LeftMessage, HungUp } }
StateMachine { State = OnHold, PermittedTriggers = { TakenOffHold, PhoneHurledAgainstWall, HungUp } }
Duration: 0ms
StateMachine { State = OffHook, PermittedTriggers = { CallDialed } }

mkinzler 8. Sep 2015 05:48

AW: Stateless - StateMachine für Delphi
 
:thumb:
Das wäre doch ein Produkt für Delphinus

DonAlfredo 8. Sep 2015 10:46

AW: Stateless - StateMachine für Delphi
 
Thank you very much !!!
I was awaiting this eagerly ... :-D

Question (at the moment, I did not look closely into the sources):
Would a port to Free Pascal be possible / difficult / useless ?

Thanks, Alfred.

mkinzler 8. Sep 2015 10:54

AW: Stateless - StateMachine für Delphi
 
I guess it's not impossible but because it uses delphi generics and rtti excessively many adaption may be made.

But I haven't had a very close look neither.

DonAlfredo 8. Sep 2015 11:11

AW: Stateless - StateMachine für Delphi
 
I just had a look at the sources!
FPC is not possible at the moment.
It uses nested generics, and current FPC cannot handle this.
E.g.: FTriggerBehaviours: TObjectDictionary<TTrigger, TObjectList<TTriggerBehaviour>>;

But few months ago, I did port the same statemachine to FPC.
I will have a look and check again against Sir Rufo's and make public if ok !

Sir Rufo 8. Sep 2015 11:34

AW: Stateless - StateMachine für Delphi
 
Zitat:

Zitat von mkinzler (Beitrag 1315049)
:thumb:
Das wäre doch ein Produkt für Delphinus

Ja, ich überlege aber noch, wie ich das am besten verpacke. Ich wollte noch das ein oder andere auf github schieben (z.B. IdleWorker, BackgroundWorker, ...) und da gibt es bei den Types, Utils schon Überschneidungen.

Wenn das mal komplett ist, dann geht das auch zu Delphinus ... :)

Sir Rufo 8. Sep 2015 11:36

AW: Stateless - StateMachine für Delphi
 
Zitat:

Zitat von DonAlfredo (Beitrag 1315099)
I just had a look at the sources!
FPC is not possible at the moment.

Yes, FPC or any backward compatibility was not in my mind :)

Stevie 8. Sep 2015 11:48

AW: Stateless - StateMachine für Delphi
 
Da bist du mir zuvor gekommen - wollte schon seit einiger Zeit eine Statemachine in Spring4D einfügen - Stateless war auch eins meiner möglichen Vorlagen.

franktron 8. Sep 2015 12:20

AW: Stateless - StateMachine für Delphi
 
Mal eine Doofe Frage, was macht man damit und was tut das.

Stevie 8. Sep 2015 12:31

AW: Stateless - StateMachine für Delphi
 
https://de.wikipedia.org/wiki/Endlicher_Automat


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:38 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz