Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

fb:porticula NoPaste

Info
Info / Hilfe
Liste
Übersicht / Liste
Neu
Datei hochladen
Suche
Quellcode suchen
Download
Dateidownload

FSM mit State Pattern (mit Table)

Uploader:RedakteurSt_W
Datum/Zeit:21.03.2013 00:50:50

'#Define DEBUG

#Define FALSE 0
#Define TRUE (Not FALSE)
#if Not __FB_MIN_VERSION__(0, 25, 0)
    #error fbc must be at least version 0.25.0 to compile this module
#EndIf

#Macro implState(statename)
Type State##statename extends StateObj
    Declare Function getNav(As String) As StateObj Ptr
    Declare Function getName() As String
    Dim navtab(0 To 1) As StateObj Ptr
    Dim title As String = "##statename##"
    Declare Constructor()
End Type
Dim Shared S_##statename As State##statename
Function State##statename##.getNav(a As String) As StateObj Ptr
    If (Asc(a)-Asc("a") < LBound(this.navtab)) OrElse (Asc(a)-Asc("a") > UBound(this.navtab)) Then Return @S_Empty
    Return this.navtab(Asc(a)-Asc("a"))
End Function
Function State##statename##.getName() As String
    Return this.title
End Function
#EndMacro


Type StateObjFW As StateObj

Type StateCtx extends Object
    Private:
    Dim curState As StateObjFW Ptr

    Public:
    Declare Constructor()
    Declare Function setState(As StateCtx Ptr) As StateCtx Ptr
    Declare Sub nav(As String)
    Declare Function isFinal() As Integer
End Type


Type StateObj extends Object
    Declare Sub nav(As StateCtx Ptr, As String)
    Declare abstract Function getNav(As String) As StateObj Ptr
    Declare abstract Function getName() As String
End Type


Sub StateObj.nav(ctx As StateCtx Ptr, a As String)
    ctx->setState(this.getNav(a))
End Sub


implState(Empty)
implState(A1)
implState(B1)
implState(C1)
implState(C1C2)
implState(C1C3)



Constructor StateA1()
    this.navtab(0) = @S_B1
    this.navtab(1) = @S_Empty
End Constructor
Constructor StateB1()
    this.navtab(0) = @S_Empty
    this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1()
    this.navtab(0) = @S_C1
    this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1C2()
    this.navtab(0) = @S_C1C3
    this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1C3()
    this.navtab(0) = @S_C1
    this.navtab(1) = @S_C1C2
End Constructor
Constructor StateEmpty()
    this.navtab(0) = @S_Empty
    this.navtab(1) = @S_Empty
End Constructor



Constructor StateCtx ()
    this.curState = @S_A1
End Constructor


Function StateCtx.setState(s As StateCtx Ptr) As StateCtx Ptr
    Dim tmp As StateCtx Ptr = this.curState
    this.curState = s
    Return tmp
End Function

Sub StateCtx.nav(s As String)
    #Ifdef DEBUG
        Print "  "; this.curState->getName(); " -> ";
    #EndIf
    this.curState->nav(@This, s)
    #Ifdef DEBUG
        Print this.curState->getName()
    #EndIf
End Sub

Function StateCtx.isFinal() As Integer
    If *this.curState Is StateC1C3 Then Return TRUE
    Return FALSE
End Function


'Open "test.input" For Input As #1
Open Cons For Input As #1

Dim s As String

Do
    Dim sc As StateCtx
    Line Input #1, s
    If Eof(1) Then Exit Do
    For q As Integer = 0 To Len(s)-1
        sc.nav(Chr(s[q]))
    Next
    Print """"; s; """ "; *IIf(sc.isFinal, @"ACCEPT", @"REJECT")
Loop