AndyGabler2 / Animation4J

1 stars 0 forks source link

Rework Interruptible Flag #2

Closed AndyGabler2 closed 9 months ago

AndyGabler2 commented 1 year ago

Well for one, it's misspelled. "Interruptible" is spelled "interruptable". Don't think anyone aside from me is using this framework so a breaking change might be okay.

The more important thing, is that on all DeterministicFiniteAutomata (AnimationController and StopMotionController) an individual State (Animation or StopMotionState) has this in interruptable flag. This does not work for some use cases since sometimes we might want to interrupt an animation depending on what is happening (based on the specific transition).

AndyGabler2 commented 1 year ago

Dumping code comment here so I have it for later after I fix it.

STATE_TYPE checkTransition(
        TRANSITION_CONTEXT contextProvider,
        TRANSITION_ROOT rootEntity
    ) {
        // TODO bug discovered. If the criteria is met for two transitions, then we got a problem
        // TODO, actually, this is a rather complex bug.
        // TODO So as soon as we find that a transition from is OK, the state we transition to becomes the "real" state
        // TODO this means the active state is no longer checked for transitions. We're transitioning off of the "real" state
        /*
         * Consider the following (~ is active, + is real)
         *
         * In first call, active and real state is A
         *
         * A(~+) ---> B ---> C
         *       ---> D
         * Suppose our end goal is State D. Well if the criteria is met for State A to transition to State B, then
         * State B becomes the "real" state but State A remains the "active" state.
         * A(~) ---> B(+) ---> C
         *      ---> D
         * If during this time, State C becomes the active state, we could very well still be having State A be the
         * "active" state while State C is the one transitioning off of. This makes things especially clunky when conditions
         * are met where we would expect the transition from State A to State D to fire.
         *
         * We could, in theory redesign this to be a non-deterministic finite automata, where the machine can be in two states
         * at once.
         *
         * Solution could be to only check transitions off of the "active" state. Maybe here return an array of acceptable
         * transitions.
         */
        final Transition transitionToNextState = transitions.stream()
            .filter(transition -> transition.transitionFunction.apply(contextProvider, rootEntity))
            .findFirst().orElse(null);

        if (transitionToNextState == null) {
            return null;
        }

        if (!interruptible && transitionToNextState.overridesInterruptibleFlag) {
            transitionInterruptible = true;
        }

        return transitionToNextState.toState;
    }

Basically, a bug where we're making the "real" state in a DFA the "real" state far too fast. Unsure if I should check transitions from the active state (and allow more than one transition to be possible)

AndyGabler2 commented 9 months ago

Done here. https://github.com/AndronikusGameTech/Animation4J/pull/4