
Hi, Michael Caisse wrote:
This concept is difficult (messy) to implement with ad-hoc techniques. I personally find that the richness provided by some of the modeling language constructs produces very simple solutions for what can often be messy problems to solve. It brings an elegance to the solution space that cannot be found in just states and transitions alone. It is the richness of the modeling language that helps one solve more complex problems without complexity.
Sure, in these simple toy examples the ad-hoc switch statement looks as good if not better than a complex library. But as soon as we start making something that is industrial proof with all the error cases and whatnots ... well things start getting more complicated and I personally start looking for some additional constructs to help out.
I fully agree with Michael's point that more complicated constructs are really messy to implement with ad-hoc techniques. And the real power behind a fsm library is the abstraction from code to move on to higher abstractions. But on the construct presented by Phil I personally find a lot to criticize. First of all, it is a mess. The code is long and even while the machine is so trivial that you could almost do it without a fsm, it must be quite hard to follow if one adds all what was left out for demonstration purposes. Second, and what really bugs me is the mix of fsm structure with character processing. Such a code is not to be reused (if one doesn't count a selective copy/paste). This is made even worse by the fact that this is obviously GUI code and such processing must happen several times in different modules. I also don't like:
void process_event(const character_received_event& e) { .... void process_event(const sigwinch_event& e) { ....
Having to write overloads in a template word??? No, thanks! I think the only thing I like in it is the O(1). Phil Endecott wrote:
How would you do this with MSM? Something like this presumably:
row < normal, character_received_event, seen_escape, none, &is_escape_char >, row < normal, character_received_event, normal, &insert_at_cursor_and_advance >, row < seen_escape, character_received_event, normal, &cursor_home, &is_H >, row < seen_escape, character_received_event, normal, none >, row < any, sigwinch_event, unchanged, &resize_screen >
Apart from the fsm structure and syntax errors, which are irrelevant to the discussion, yes, I could do something like this if performance were uncritical in this part of the application and I wanted a chance to play with eUML. But more likely, I wouldn't do that. Instead, if performance was an issue I'd probably keep the second switch/case (the switch on character), pack it inside a nice generic functor which would in no case do this:
case escape: state = seen_escape; break;
Because this means mixing character processing with fsm structure. It'd be something like (as entry functor. Could be as transition functor too): struct CharTypeProcessing: euml_action<CharTypeProcessing> { template <class Event,class FSM,class STATE> void operator()(Event const&,FSM& fsm,STATE& ) { switch (c) { case escape: fsm.process_event(escape_char()); break; .... more special characters like tab, newline etc .... default: fsm.process_event(normal_char(c) ) ;break; } } }; I don't go more into details but I'm sure you get the idea. We now have a generic functor, which can be reused in any state or fsm without any knowledge of the structure. It can be documented as: name: CharTypeProcessing description: checks for special characters. Triggers event normal_char(char value) if a normal char, escape_char if escape, etc. And now, any other developer can reuse it, without having to dig into the code to get the part he needs. But what really really strikes me is that it's already Phil's second implementation of a fsm on 2 examples. And a pretty different one than the first! This means double work, double debugging. Add this to the fact that the character processing is also not reusable (mixed with fsm structure, as we saw) and I think I'll be enjoying a latte with a choco-croissant (my favorite) while other developers will still try to find why Phil's code doesn't work for them (hint: they surely made a mistake in their copy/paste. Tsss...).
You are welcome to try to convince me that it has benefits that I have not yet seen....
Sorry but I won't try because I doubt, from experience, that someone who will have spent a long time on his multiple switch/case will want to give up this work too fast. But it's really ok for me, as I said, I wrote MSM for people like me, who can't see a double switch/case without a strong uncomfortable feeling. If you feel more comfortable with it, great for you! Only, if you ever look for a copy/paste error for hours, I hope you'll picture me with my latte and choco-croissant and switch back to MSM. I'll be happy to share a latte with you ;-) Regards, Christophe