Git Product home page Git Product logo

Comments (4)

inamiy avatar inamiy commented on July 19, 2024

Hi, thanks for great feedback :)

My use case is a game having many tokens (AKA sprites) each having state and a state machine. I don't mind each token owning an instance of StateMachine, but then I must configure each instance the same way (easy enough to workaround.) But possibly a StateMachine should have a Design which is configured and passed to a StateMachine instance.

Design sounds a good idea.
I was also thinking about Graphviz (DOT file) support in #4,
so using (Route)Design class will help its printing and also an easy configuration to StateMachine.

In other implementations of FSM 'context' seems to mean: the object which has state, which the state machine sets the state of, and which is passed to all actions (what you call Handlers) for them to act on. Your context is not the same thing? Maybe a solution is a delegate for the state machine?

I guess that is Event in SwiftState's terminology.

By the way, SwiftState's HandlerContext is just a Handler's tuple argument.
I used this term similar to UIViewController Transitioning API, where view transition invokes methods with passing transitionContext argument.

On another topic, I don't understand the use case for AnyState. Is one use case adding transitions from any state to a reset state, so that you don't have to specify a transition from every state to the reset state? Maybe you could explain in your document. But I should read the code, and for example study what a transition from AnyState to AnyState would mean.

Exactly right. What you mentioned is one of good ways of using AnyState.
You can also combine with condition as a blacklist to define the route, e.g. StateMachineTests.swift#L116-L129

from swiftstate.

bootchk avatar bootchk commented on July 19, 2024

More discussion about context, delegate, handlers....

In your tests, you pass an unnamed closure as a Handler. The closure is bound to variables in scope, for example to "var returnedTransition: StateTransition?". What I think I need is passing a named closure as a Handler, where the named closure is a method bound at runtime in the statemachine to some delegate object instance.

For exaple:

delegate1 = SKLabelNode()
delegate2 = SKLabelNode()

design = StateMachineDesign()
// setScale is a method of SKNode which is superclass of SKLabelNode
design.addRoute(.State0 => .State1, event: .Event0, handler: setScale(50) )

delegate1.sm = StateMachine(design: design, delegate: delegate1)
delegate2.sm = StateMachine(design: design, delegate: delegate2)

delegate1.sm <-! .Event0

Then the stateMachine changes the state of delegate1 and calls method setScale bound to delegate1. I.E. this pseudocode inside StateMachine:

self.delegate.handler()

I hope that gives the idea, but Iā€™m still thinking, I haven't tested. Possibly SwiftState already allows that.

from swiftstate.

inamiy avatar inamiy commented on July 19, 2024

Though there's no direct support of delegation in current SwiftState, I think you can do the similar thing just by wrapping with closure of Handler type (will be a bit lengthy):

// NOTE: HandlerContext is omitted using `_`
machine.addRouteEvent(.Event0, transitions: [.State0 => .State1], handler: { [weak delegate] _ in delegate?.setScale(50) })

If we are going to support for a better delegation syntax as you mentioned above, however, there will be many difficulties because Swift itself doesn't support runtime messaging (needs Foundation.framework). In your example, if setScale(50) is called without delegate. prefix, it will just prompt compile error.

So, here's one alternative solution I came up with...

  1. [User side] Create free (global) func setScale() instead of delegate-bounded instance method. It's signature must be of the curried form func setScale(scale: Float, ...)(delegate: StateMachineDelegateProtocol) or func setScale(sclae: Float, ...) -> (StateMachineDelegateProtocol -> Void).
  2. [Library side] Support above free function event handler.

But (1) seems too heavy a burden for users, so I'm currently thinking of (2) not necessary for a while.

from swiftstate.

bootchk avatar bootchk commented on July 19, 2024

Thanks. That all seems correct. Because Swift does not support runtime messaging, I think I will NOT attempt to use a design, but just implement a StateMachine factory that binds an instance of what would be a delegate to a instance of StateMachine.

from swiftstate.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.