Package org.squirrelframework.foundation.fsm

Source Code of org.squirrelframework.foundation.fsm.CollaboratingStateMachineTest$Context

package org.squirrelframework.foundation.fsm;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.UntypedAnonymousAction;
import org.squirrelframework.foundation.fsm.UntypedStateMachine;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;

/**
* Tests two interacting FSMs.
* <p>
* A state change action running on the first FSM fires an event against the
* second FSM. The second FSM's state should change accordingly.
*
* @author Jeremy.Stone
*/
public class CollaboratingStateMachineTest {
    /*
     * Pair of FSMs. Two states each (A and B) with transitions allowed in
     * either direction.
     *
     * One FSM starts at A; the other at B.
     */
    UntypedStateMachine fsmAtoB;

    UntypedStateMachine fsmBtoA;

    static class Context {
        FSMEvent lastEvent;
    }

    final Context ctxAtoB = new Context();

    final Context ctxBtoA = new Context();

    enum FSMEvent {
        ToA, ToB
    }

    static class StateMachineSample extends AbstractUntypedStateMachine {
    }

    /** */
    @Test
    public void transitionInOneFSMHasActionThatCausesTransitionInAnother() {
        createFsmBtoA();
        createFsmAtoB();

        fsmAtoB.fire(FSMEvent.ToB, ctxAtoB);

        // Check final states as well as last events seen by each FSM...
        assertEquals(FSMEvent.ToB, ctxAtoB.lastEvent);
        assertEquals("B", fsmAtoB.getCurrentState());

        assertEquals(FSMEvent.ToA, ctxBtoA.lastEvent);
        assertEquals("A", fsmBtoA.getCurrentState());
    }

    private void createFsmAtoB() {
        UntypedStateMachineBuilder fsmAtoB_builder = StateMachineBuilderFactory.create(StateMachineSample.class);

        // In transitioning from A to B trigger other FSM (fsmBtoA) to
        // transition
        // to A...
        fsmAtoB_builder.externalTransition().from("A").to("B").on(FSMEvent.ToB)
                .perform(storeEventAndFire(fsmBtoA, ctxBtoA, FSMEvent.ToA));
        fsmAtoB_builder.externalTransition().from("B").to("A").on(FSMEvent.ToA).perform(storeState());

        fsmAtoB = fsmAtoB_builder.newStateMachine("A");
    }

    private void createFsmBtoA() {
        UntypedStateMachineBuilder fsmBtoA_builder = StateMachineBuilderFactory.create(StateMachineSample.class);
        fsmBtoA_builder.externalTransition().from("A").to("B").on(FSMEvent.ToB).perform(storeState());
        fsmBtoA_builder.externalTransition().from("B").to("A").on(FSMEvent.ToA).perform(storeState());

        fsmBtoA = fsmBtoA_builder.newStateMachine("B");
    }

    private static UntypedAnonymousAction storeEventAndFire(final UntypedStateMachine otherFsm, final Context otherCtx,
            final FSMEvent otherEvent) {
        return new UntypedAnonymousAction() {
            @Override
            public void execute(Object from, Object to, Object event, Object context, UntypedStateMachine stateMachine) {
                ((Context) context).lastEvent = (FSMEvent) event;
                otherFsm.fire(otherEvent, otherCtx);
            }
        };
    }

    private static UntypedAnonymousAction storeState() {
        return new UntypedAnonymousAction() {
            @Override
            public void execute(Object from, Object to, Object event, Object context, UntypedStateMachine stateMachine) {
                ((Context) context).lastEvent = (FSMEvent) event;
            }
        };
    }
}
TOP

Related Classes of org.squirrelframework.foundation.fsm.CollaboratingStateMachineTest$Context

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.