New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trigger is not reentrant #3
Comments
Let's see if I understand. It sounds like you have more than two states |
I have a small LED matrix display that I use to show time and some messages contained in a circular buffer.
I know I could put the code contained in the Regards, |
Thanks, now I understand your state machine, but sadly not your problem. What is working as you'd like it to? |
trigger is not reentrant. I mean that when I push the NEXT button and the buffer is empty, a second recursive call to trigger is made inside the STATE_MESSAGE_enter() function. |
for example in this kind of state machine, the states are "chained". The machine moves from one state to another without external event. |
Thanks, that's a better explanation. This is (maybe) a bug. The problem is that the state in the machine is set after the callbacks are called. If we want to allow state changes to be triggered in the callbacks, the state machine state must be set before they're triggered; however, I'm not sure what state the machine should be in when callbacks are called.
So in answer to your question, this can be fixed in the library but the questions above need answering first. You can, however, workaround the issue by moving the logic in
What do you think? |
During a transition, the machine has no state...or a IN_FLIGHT/NULL state.
? Anything....
Yes. That could be a workaround for very simple case. But it becomes really complex when the number of states increases. And in my application, if I'm in the TIME state, I need to trigger EVENT_NEXT even if the buffer is not empty. So That's why we need a getName() function in state.
|
we have:
We are in STATE_A We are in STATE_A A trigger in STATE_A_STATE_B_transition() in error does nothing (returns error) The other question is: What happen if we call 2 trigger() in a callback. |
I was thinking the same. That's a good point about triggering a state change
I'm certain that
This is a nice example.
We can't stop people from doing this, and I don't think it's semantically a There is also the risk that people end up putting their code in an infinite |
Yes That's a simplified version of what I'm currently developing.
And a getId() ? I mean, how do I know in which state my machine is from outside ?
Just add a counter each time a trigger() is called. If counter > 2 then "return ERROR;"
Like any other while() loop.... |
That's an interesting project. I'd love to read a blog post about it when you're finished. 😄
True. The idea is we fix the problem so you don't need the workaround 😄
By stopping people, I mean a compile time error. At runtime it's a bit late. Since it's not semantically a problem, I don't see a reason to do this. As far as I can tell we'd need to move We'll also need a good bunch of test cases for it, including an insane one just to see what happens. I can work on this as soon as my motherboard is returned from the repair shop, which should have been two weeks ago :sad: |
i'll try to make a post on https://hackaday.io About the state name or ID, I really don't know how to do without it. I understand It encourages some bad programming behavior, but the work around it is to have a current_state global variable and update it in all the STATE_enter() callback. Not really cool too.
At compile time it's not an problem, but at runtime, it is an unrecoverable exception.
My next project for your lib is the "IoT-isation of a table soccer where all the actions are states of a FSM. That may include quite a lot of test cases as I will relie a lot on these auto triggers. Redge |
no news ? |
Motherboard is back. This coming weekend is quite busy. If I don't manage it, I'll do it the weekend after. Sorry it can't be sooner. |
In my opinion, Trigger should not be called in transition actions, what i miss in this library api is the posibilitiy of adding a function to a state so it would be called every time the engine checks the machine and while in this state, something like this:;
A FSM could then be autosuficient, checking events into that state functions (and only the interesting ones for that state) and tiggering transitions acordingly. @redge76 could then do all the automatic transition job in that Hope my explanation was clear enough. |
I also miss the onState() function. |
@redge76 regarding your first sample: STATE_MESSAGE_enter() {
if (circ_buffer not empty){
write (circ_buffer[start_pointer]) to LED
} else {
fsm.trigger(EVENT_HOME)
}
} You could put your code in the new I'm going to fork proyect to test some of this improvements. |
@Thelmos Are you proposing that |
Yes, sorry, just for the current state. This way the state can monitor events and trigger transitions by itself. |
Explained in new issue #10 |
@redge76 Why do you want to avoid calling things in |
Hello @jonblack, thanks for a great library. LIke @redge76, I would also like to avoid calling things in In my application, I am looping through I would prefer having some way of setting the state to transition to inside the FSM, i.e. writing a self-sufficient FSM containing states and transition logic. With the What is the status on this and on #10? How can we help getting this implemented, I think this is a much needed improvement. |
Sorry for dropping the ball on this. It's been hectic here. I don't have the overview I once had. If someone can make a pull-request out of that branch and make sure it works (e.g. all examples), I'll merge it and make a new release. (I wish I had more time to do this myself). I just merged in @Thelmos 2.2.0 pull-request and made a release, too, so there's already one update out there. |
Thank you all, i will give it a try next week.
…On Oct 25, 2017 3:09 PM, "Jon Black" ***@***.***> wrote:
Sorry for dropping the ball on this. It's been hectic here.
I don't have the overview I once had. If someone can make a pull-request
out of that branch and make sure it works (e.g. all examples), I'll merge
it and make a new release.
I just merged in @Thelmos <https://github.com/thelmos> 2.2.0 pull-request
and made a release, too, so there's already one update out there.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#3 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAA6QzNF7K52gNss2LhsMjMrdqKgPOLmks5svzL8gaJpZM4HflT_>
.
|
I've been hoping for a light weight state machine like this, and there it is! I've used a stateless state machine in c# in some other project, and transitions/triggers are implemented a bit differently (it's stateless). I'm stepping in this conversation just to suggest yet another possible approach to the reentry problem: it might be possible to add an asynchronous trigger that decouples setting the new state from the trigger event itself. State transition could then be executed outside these methods in a loop "process" method, etc. I'm going to give the branch a try... State machines generally make the code much easier to implement and maintain and I really need something like that right now. So thanks a bunch to @jonblack ! Edit: looks like someone implemented something similar in a fork |
Hi,
I would like to be able to call trigger from within a "enter" or "transition" function.
Do you see a easy modification of your lib to be able to write something like this:( modify your light_switch.ino and change just de bellow functions)
My goal is to write some "routing state" that would automatically branch to another state depending on the value of some sensor. Something like:
Regards,
Redge
The text was updated successfully, but these errors were encountered: