Trustin Lee wrote:
> On 4/10/07, Niklas Therning <[EMAIL PROTECTED]> wrote:
>> Coding Horse wrote:
>> > Hi, Community,
>> >
>> > I'm trying to model my app logic with mina-sm framework and reading
>> > StateMachineProxyFactoryTest as the start point, like what was
>> suggested by
>> > Niklas.
>> >
>> > There are lines like this:
>> >
>> > @Handler( on = "eject", in = "s4", next = "s1" )
>> > public void ejected()
>> > {
>> > messages.add( "Tape ejected" );
>> > }
>> >
>> > I'm not sure I understand the above code correctly:
>> > If current state is "s4" and event "eject" is received, the method
>> ejected()
>> > of the hander will be called and then the state will be changed to
>> "s1".
>> >
>>
>> Yes, you've understood correctly.
>>
>> > Also, I can't figure out how to model this scenario:
>> > conditioned state transition, like:
>> > if(condition met){
>> > // next state is "stateA"
>> > }else{
>> > // next state is "stateB"
>> > }
>> > It seems to me that the state transition is predefine in
>> > on = "eject", in = "s4", next = "s1"
>> >
>>
>> Yes, the annotations doesn't handle this case. You can use the
>> StateControl class to achieve what you want:
>>
>> if (condition met) {
>> StateControl.breakAndGotoNext("stateA");
>> } else {
>> StateControl.breakAndGotoNext("stateB");
>> }
>>
>> If you use StateControl it will override the @Handler annotation. It
>> will cause an exception to be thrown and a state change will occur on
>> the next event.
>>
>> You can also use breakAndGotoNow(state). This will cause a state
>> transition and then the current event will be reexecuted by the state
>> machine starting from the specified state.
>>
>> breakAndContinue() will interrupt the current @Handler method as if it
>> never matched the event in the first place. Any transitions with higher
>> weights will be searched and the first which handles the current event
>> will be executed.
>>
>> Finally, you have breakAndCallNext(state) and breakAndCallNow(state)
>> which can be used to create sub-routine like sub state machines. The
>> current state will be pushed onto a stack and the state machine will
>> transition to the specified state (either on the next event or the
>> current event). Use breakAndReturnNext() or breakAndReturnNow() to
>> return to the previously pushed state.
>>
>> I must admit that things can become quite messy if you overuse
>> StateControl. However, in small doses it works quite well ;-) . Just
>> let me know if you see any potential for improvements. I'd very much
>> appreciate to get some feedback on this piece of code.
>
> Would there any way to use this framework to implement a protocol
> decoder? :)
>
> Trustin
Yes indeed it would! The only limitation at the moment is that you can
only create a state machine proxy for a set of interfaces. Proxy
creation for classes isn't possible. Though it would be quite simple I
guess using CGLIB. Since ProtocolDecoder and ProtocolEncoder are
interfaces you could definitely create a state machine proxy which acts
as a decoder/encoder.
--
Niklas Therning
www.spamdrain.net