public NodeToken backtrack() { backtrackLeafArcTokens(); NodeToken resultToken = null; while (!queue.isEmpty()) { NodeToken token = queue.first(); queue.remove(token); if (token.getExecutionType().isBacktracked()) { continue; } token.getNode().backtrack(engine, token); boolean isDestination = token.equals(destinationToken); if (isDestination) { resultToken = backtrackCompletedToken(token, ExecutionType.Forward); } else { NodeToken backtrackToken = backtrackToken(token); if (backtrackToken != token) { backtrackToken.markBacktracked(); NodeTokenEvent.fireBacktrackedEvent(engine, backtrackToken); backtrackToken.markComplete(); NodeTokenEvent.fireCompletedEvent(engine, backtrackToken, null); } } } reactivateTokenSets(); return resultToken; }
private NodeToken backtrackToken(final NodeToken token) { NodeToken backtrackToken = token; if (!token.isComplete()) { token.markComplete(); NodeTokenEvent.fireCompletedEvent(engine, backtrackToken, null); token.markBacktracked(); NodeTokenEvent.fireBacktrackedEvent(engine, token); token.getProcess().removeActiveNodeToken(token); } else if (!token.getExecutionType().isBacktracked()) { if (token.getChildTokens().isEmpty()) { token.markBacktracked(); NodeTokenEvent.fireBacktrackedEvent(engine, token); } else { backtrackToken = backtrackCompletedToken(token, ExecutionType.Backtracked); backtrackToken.setGuardAction(GuardAction.SkipNode); NodeTokenEvent.fireSkippedEvent(engine, backtrackToken, null); } } for (ArcToken parent : getParents(token)) { boolean backtrackParent = visited.contains(parent.getParentToken()); token.getProcess().removeActiveArcToken(parent); parent.markBacktracked(); ArcTokenEvent.fireBacktrackedEvent(engine, parent); ArcToken backtrackArcToken = engine .getFactory() .newArcToken( token.getProcess(), parent.getArc(), backtrackParent ? ExecutionType.Backtracked : ExecutionType.UTurn, backtrackToken); ArcTokenEvent.fireCreatedEvent(engine, backtrackArcToken); backtrackToken.getChildTokens().add(backtrackArcToken); shareTokenSets(backtrackArcToken, parent); if (backtrackParent && parent.getExecutionType() != ExecutionType.Forward) { ArcToken mirror = backtrackMirror.getMirror(parent); arcTokenMap.put(mirror, backtrackArcToken); finishArcTokenBacktrack(backtrackArcToken, mirror); } else { finishArcTokenBacktrack(backtrackArcToken, parent); } } return backtrackToken; }