 |
|
 |
Use the following code snippets to get the base class to maintain the state variable. My motivation for this is: (a) I'm lazy; (b) I can never remember the fine detail to make things like this work.
As the state variable is now object, no casting is required. Runtime checking can use if (value.Type() != _stateType) to check that correct types are passed to the runtime.
Type _stateType; object _stateVar;
_stateVar = _stateType.InvokeMember(_stateType.Name, BindingFlags.CreateInstance, null, null, null);
...
protected object GetCurrentState()
{
return _stateVar;
}
...
Andy
|
|
|
|
 |
|
 |
For your interest in using statemachines in real systems look at www.steed.de. You can build UI based Aplication as Services or C/S applications with it. I decreases developmentime an programming efford. And you can easy monitor your running applicaton.
|
|
|
|
 |
|
 |
I have used your framework for an automation project I am working on. It is working very well, and reduced my development time considerably. Many thanks for that.
The only problem I have run into is that some events I have are time critical (+/-20 milliseconds accuracy is needed), the FSM timer events are sometimes out of this range.
I noticed that you have SyncEvents, but I have not tried to use them. Can you explain more about what they are for and how they are used?
Is there a way to set a "priority" for certain events?
Thanks again and best regards.
|
|
|
|
 |
|
 |
Hi Tash
Thank you for your feedback.
About the timer issue I will look into that problem sasp.
About SyncEvents: In the article on chapter "Implementing an FSM, step by step", Point 4, you will find the Note: "With Wait(), it is also possible to synchronize to the processing of a posted event if it is derived from SyncEvent. Fsm and EventBase have a constructor with a synchronized parameter."
It is basically to synchronize to the treatment of the event. It is also possible to synchronize to the completion of an FSM.
I like your idea to introduce a "priority" to events. As soon as I have some time left, I will implement that. Do you think, "high" and "low" is sufficient or do we need more values?
Best regards Linus
|
|
|
|
 |
|
 |
Linus,
Thanks for your reply. I had missed point 4 you mentioned above, thanks for pointing that out. Would this be the correct way to sync to the completion of an event?
private class mySyncEvent : FsmSyncEvent
then in a code section
mySyncEvent ev = new mySyncEvent();
PushEvent(ev);
Wait();
Would this then wait until the event was processed? When does it continue? Is it at the completetion of the event handler? If the event caused a state transition, does the transition happen first?
As for the timer events, in my initial testing they seemed to always fire in a very timely manner. But the project has become more complex. There is a form which controls 2 FSMs. I added a timer control to the form object and it has an event which is firing every 100ms. This is not really a time critical process, just a time display for the user, and some logic to trigger some FSM events if certain conditions apply. Once this timer was added I noticed the FSM timer events were then taking slightly longer, I assume it is because the processor can not service them quickly enough with so many other things happening. That is why I was wondering about priorities, if there is a way to say certain events need to be a "high" priority that would be excellent. For my purposes just "high" and "low" would be fine.
Many thanks for you help and advice.
Best regards,
Tash Robinson
|
|
|
|
 |
|
 |
> Would this then wait until the event was processed?
Yes
> When does it continue? Is it at the completetion of the event handler?
Yes
> If the event caused a state transition, does the transition happen first?
Yes
|
|
|
|
 |
|
 |
Concerning the timer problem: It is important not to "block" an event or transition handler. If such a handler is executing a time consuming operation, the event queue is not checked in the meantime. That means also, that timer event may elapse undetected.
If an event handler has to execute a time consuming operation, it should
- delegate it to another FSM on another processor (=thread), or
- use an asynchronous variant of the op which sends back an event on completion
|
|
|
|
 |
|
 |
If you change the delegate signature of OnChangeForkState(int ForkHashCode,Fork.State state) to OnChangeForkState(Fork fork,Fork.State state) you will be able to directly register it with the Fork event ChangeState:
fork.ChangeState += new Fork.OnChangeStateDelegate(OnChangeForkState); Add the line of computing hash code internally. This way you get rid of declaring m_ChangeForkStateDelegate, the delegate itself and the ChangeForkState intermediate which uses the the BeginInvoke internal function.
The same applies to the Philosopher case.
I liked your article and learned a lot.
Thank You
Ilan
|
|
|
|
 |
|
 |
Thank you for your finding. You are right, your solution is more elegant. I will change that in my test program for the next version.
And I am honored that you enjoyed my aricle.
Linus
|
|
|
|
 |
|
 |
Hi Linus,
In your examples you show handling a specific event in an FSM without states or with no transition handler for that event and the current state. However, I would appreciate an example showing how to handle such a situation within the context of specific states.
For example, let's say I have StateA and I have defined 3 events that are handled by transition handlers for StateA. However, if any other event is received while in StateA, I want to transition to StateB. This would only happen if the event is not one of the 3 already handled (i.e., a default case).
This handling needs to be specific for StateA. For example, if I have an analogous situation (a default case) in StateC, I might need to transition to StateF (not StateB as I did earlier).
The obvious way to do this is to use a switch statement inside the FSM's EventHandler but this doesn't seem very satisfactory. Can you give me some suggestions and an example?
Thanks!
Mountain
|
|
|
|
 |
|
 |
Hi Mountain
You are right. My solution does not support a default transition handler for a specific state.
The actual situation (Fsm::OnEvent):
If FSM does not find a transition, it tries to find an event handler for this event.
If it does not find an event handler, it calls the virtual method "OnFsmEventDefault"
I will enhance FSM this way, that the user will be able to define a default transition handler for every state. This transition handler will handle all events received in StateA where no transition handler is defined for.
For automatic mode, the method name will be "StateA_DefaultTransition".
The attribute will be [FsmDefaultTransitionHandler("StateA")]
Satisfied?
If you are patient, give me a few days to implement it.
Otherwise, do it yourself.
Linus
|
|
|
|
 |
|
 |
Hi Linus,
I think that will be an excellent enhancement for FSM. I will wait on you to implement it. However, when you get it done, I'll try to make the time to post an example showing FSM using this new feature. I think it could be a nice example for you. It will be a calculator implemented on FSM.
Best regards,
Mountain
|
|
|
|
 |
|
 |
// Viellecht könnte man diesen override dynamisch in Fsm
// erzeugen!!!
This is in the code. It looks important. What is the english translation?
|
|
|
|
 |
|
 |
It is german and means: Probably it is possible to create this override dynamically.
I felt that it is not so nice, that the user of Fsm has always write this override "GetCurrentState". The reason is, that the Fsm class has to know the current state. But the state enumeration is user-specific. Perhaps it is possible to generate this method dynamically by reflection.
This issue is not so important, in spite of the 3 exclamation marks.
|
|
|
|
 |
|
 |
Thanks. The 3 exclamation marks made it look important to someone who doesn't read German.
|
|
|
|
 |
|
 |
Very nice Article; I must admit that I have not tried the code, I'm not in the .NET business But everybody really interested in state machines should read the book "Practical Statecharts in C/C++" from Miro Samek. It goes much more in detail (of course, it's a whole Book about the topic) and provides a framework for hierachical state machine as defined in the UML standard. And the author claims his code is production ready.
Andre
|
|
|
|
 |
|
 |
qf4net: Quantum Framework for .Net
Hierarchical State Machine and Active Objects
"Here you can always find the latest version of the C# port of Miro Samek's excellent implementation of a hierarchical state machine and his Quantum Framework for active objects."
http://www.hessmer.org/dev/qhsm/
|
|
|
|
 |
|
 |
That does look very nice indeed. I've scrapped my FSM implementation for Dr Hessmer's QF port however i'm curious about the BSD style license it employs. As its a direct port of Quantum Leap's framework which uses a dual license GPL + Commercial scheme, I'm wondering if his license is valid?
http://www.quantum-leaps.com/licensing/com.htm[^]
In any case, Quantum Leap's commercial licensing prices are very reasonable... well worth the time saving of developing a flexible, thread safe, and debugged FSM framework from scratch.
I'm going to put it through the paces in some test apps of my own and if everything checks out, I'm just going to focus my time on a gui designer\code generator for it.
-- modified at 5:00 Sunday 19th March, 2006
FYI, I got an email back from Dr Hessmer and I'm sure he wouldnt mind me relaying part of his reply. Here is the relevant answers by him, to the above:
"I explicitly checked the licensing situation with Miro Samek when I did the port. Your assumption is right: The C# port is solely covered by the BSD-esque license listed on my Web site.
Miro only started using the dual GPL and commercial license in later versions that he offers on his web site."
--
So there you have it. Its free to use for any purpose.
|
|
|
|
 |
|
 |
When I run the ConsoleTest project, the order I see is:
StateX_EntryState
StateX_ExitState
StateX_OnMyEventX
Why is the Exit before the transition?
Kathy.
|
|
|
|
 |
|
 |
This happends since the transition StateX_OnMyEventX is executed AFTER leaving StateX.
The order is like this:
1. Enter state StateX (upon starting the FSM or as a reaction to an event A)--> StateX_EntryState
2. Another event B is received
3. Since there exists a transition handler for event B, the FSM leaves StateX --> call StateX_ExitState
4. Now the transition can be executed --> StateX_OnB, here, the new state StateY is defined
5. Enter state StateY
I unterstand that it is samewhat confusing, but on my opinion, the FSM has to leave the state before it can execute the transition (which usually defines a new state to enter). But I am curious about discussion about this subject since I am not sure in this point.
The code to it you will find in fsm.cs, line 174
|
|
|
|
 |
|
 |
Are you saying that the machine is "Stateless" while the transition occurs ?
It leaves a no-mans land. The potential for encountering it depends entirely on the length of transition. Should we therefore include transition states in our list ?
For example:
Instead of two states: Idle, Running
Use: Idle, Commencing, Running, Finishing
where (threaded ?) processing is done during Commencing & Finishing
To my mind, machines ought not be able to exist "stateless".
If this is a silly question, please forgive my ignorance.
|
|
|
|
 |
|
 |
No, the FSM is never stateless, except if you have not defined a state variable.
The idea of a transition is, that it does not consume time. It is even a mistake to call a blocking operation within a transition handler, since the thread is not able to process any FSMs and events in the meantime. Time consuming operations have to be executed asynchronously.
Your solution with additional states is a good approach. Another way is to define a second (sub-)FSM, controlling the process of your "during" transition.
Or you send a timer event to your FSM, signalling the end of the operation.
There are no silly questions, just silly answers. I hope you are sadisfied by my answer.
|
|
|
|
 |
|
 |
What are the applications for such a system? I've never heard of Finite State Machines, so I'm not sure why I would want to use one. Can you give some examples of real-world uses for this?
Thanks,
Ceph
Skydive -- Testing gravity, one jump at a time.
|
|
|
|
 |
|
 |
Aside from the more well known uses of state machines, I've read about it being used to manage purchases on a retail website. (I always thought that was pretty cool.) Something similiar was demonstrated in an ASPToday article "Session and State Management in Distributed Web Applications".
|
|
|
|
 |
|
 |
Tom Fischer wrote:
Aside from the more well known uses of state machines
Hehe, well, the problem is, I don't know what the well-known uses are. :p
Skydive -- Testing gravity, one jump at a time.
|
|
|
|
 |