📄 smctclgenerator.java
字号:
if (stateName.equals("Default") == true) { _source.print(_indent); _source.println(" set loopbackFlag 0;"); _source.println(); // Remember this transition's name. _source.print(_indent); _source.print(" set _transition \""); _source.print(transName); _source.println("\";"); } else { _source.println(); } // If verbose is turned on, then put the logging code in. if (Smc.isDebug() == true) { String sep; _source.print(_indent); _source.println( " if {[$context getDebugFlag] != 0} {"); _source.print(_indent); _source.print( " puts [$context getDebugStream] "); _source.print("\"TRANSITION : "); _source.print(mapName); _source.print("::"); _source.print(stateName); _source.print(" "); _source.print(transName); _source.print("("); for (pit = parameters.iterator(), sep = ""; pit.hasNext() == true; sep = ", ") { _source.print(sep); (pit.next()).accept(this); } _source.print(")"); _source.println("\";"); _source.print(_indent); _source.println(" }"); _source.println(); } for (git = guards.iterator(), _guardIndex = 0, _guardCount = guards.size(); git.hasNext() == true; ++_guardIndex) { guard = git.next(); // Track if there is a guard with no condition. if (guard.getCondition().length() == 0) { nullCondition = true; } guard.accept(this); } // What if all the guards have a condition? There will be // no "else" clause. This condition will fall through and // do nothing? Is that right? No. If that is the case, // then add the "else" clause and have it call this // transition's default. if (_guardIndex > 0 && nullCondition == false) { if (_guardCount == 1) { _source.print(_indent); _source.print(" }"); } _source.println(" else {"); _source.print(_indent); _source.print(" "); _source.print(mapName); _source.print("_Default "); _source.print(transName); _source.print(" $context"); for (SmcParameter param: parameters) { _source.print(" "); _source.print(param.getName()); } _source.println(";"); _source.print(_indent); _source.println(" }"); _source.println(); } else { _source.println(); } _source.print(_indent); _source.println(" return -code ok;"); _source.print(_indent); _source.println(" }"); return; } // end of visit(SmcTransition) public void visit(SmcGuard guard) { SmcTransition transition = guard.getTransition(); SmcState state = transition.getState(); SmcMap map = state.getMap(); String context = map.getFSM().getContext(); String mapName = map.getName(); String stateName = state.getClassName(); int transType = guard.getTransType(); boolean defaultFlag = stateName.equalsIgnoreCase("Default"); boolean loopbackFlag = false; String indent2; String indent3; String indent4; String endStateName = guard.getEndState(); String fqEndStateName = ""; String pushStateName = guard.getPushState(); String condition = guard.getCondition(); List<SmcAction> actions = guard.getActions(); // If this guard's end state is not of the form // "map::state", then prepend the map name to the // state name. // DON'T DO THIS IF THIS IS A POP TRANSITION! // The "state is actually a transition name. if (transType != Smc.TRANS_POP && endStateName.length () > 0 && endStateName.equals(NIL_STATE) == false && endStateName.indexOf("::") < 0) { endStateName = mapName + "::" + endStateName; } if (stateName.indexOf("::") < 0) { stateName = mapName + "::" + stateName; } // v. 2.0.2: If the push state is not fully-qualified, // then prepend the current map's name and make if // fully-qualified. if (pushStateName != null && pushStateName.length() > 0 && pushStateName.indexOf("::") < 0) { pushStateName = mapName + "::" + pushStateName; } loopbackFlag = isLoopback(transType, stateName, endStateName); // The guard code generation is a bit tricky. The first // question is how many guards are there? If there are // more than one, then we will need to generate the // proper "if-then-else" code. if (_guardCount > 1) { // Ok, there are multiple guard statements. Now is // this the first guard among many? if (_guardIndex == 0 && condition.length() > 0) { // Yes, this is the first. This means an "if" // should be used for this condition. _source.print(_indent); _source.print(" if {"); _source.print(condition); _source.println("} {"); } else if (condition.length() > 0) { // No, this is not the first transition but it // does have a condition. Use an "else if" for // the condition. _source.print(" elseif {"); _source.print(condition); _source.println("} {"); } else { // This is not the first transition and it has // no condition. _source.println(" else {"); } indent2 = _indent + " "; } // There is only one guard. Does this guard have a // condition. else if (condition.length() == 0) { // Actually, this is a plain, old, vaniila // transition. indent2 = _indent + " "; } else { indent2 = _indent + " "; // Yes, there is a condition. _source.print(_indent); _source.print(" if {"); _source.print(condition); _source.println("} {"); } // If this is a pop transition, do not change the // "end state" name because it is really a transition. if (transType == Smc.TRANS_POP) { // no-op. } // Now that the necessary conditions are in place, it's // time to dump out the transitions actions. First, do // the proper handling of the state change. If this // transition has no actions, then set the end state // immediately. Otherwise, unset the current state so // that if an action tries to issue a transition, it will // fail. else if (actions.size() == 0 && endStateName.length() != 0) { endStateName = "${" + _pkgScope + endStateName + "}"; } else if (actions.size() > 0) { // Save away the current state if this is a loopback // transition. Storing current state allows the // current to be cleared before any actions are // executed. Remember: actions are not allowed to // issue transitions and clearing the current state // prevents them from doing so. if (loopbackFlag == true) { endStateName = "${EndStateName}"; _source.print(indent2); _source.println( "set EndStateName [$context getState];"); } else { endStateName = "${" + _pkgScope + endStateName + "}"; } } // Decide if runtime loopback checking must be done. if (defaultFlag == true && transType == Smc.TRANS_SET && loopbackFlag == false) { _source.print(_indent); _source.print(" if {[string compare "); _source.print("[[$context getState] getName] ["); _source.print(endStateName); _source.println(" getName]] == 0} {"); _source.print(_indent); _source.println(" set loopbackFlag 1;"); _source.print(_indent); _source.println(" }"); _source.println(); } // Perform the current state's exit action. // v. 1.0, beta 3: Not any more. The exit actions are // executed only if 1) this is a standard, non-loopback // transition or a pop transition. if (transType == Smc.TRANS_POP || loopbackFlag == false) { indent4 = indent2; // If this is a non-loopback, generic transition, // do runtime loopback checking. if (transType == Smc.TRANS_SET && defaultFlag == true) { indent4 = indent2 + " "; _source.print(indent2); _source.println("if {$loopbackFlag == 0} {"); } _source.print(indent4); _source.println( "[$context getState] Exit $context;"); if (transType == Smc.TRANS_SET && defaultFlag == true) { _source.print(indent2); _source.println("}"); _source.println(); } } // Dump out this transition's actions. if (actions.size() == 0) { indent3 = indent2; if (condition.length() > 0) { _source.print(indent2); _source.println("# No actions."); } } else { // Now that we are in the transition, clear the // current state since we are no longer in a state. _source.print(indent2); _source.println("$context clearState;"); // v. 2.0.2: Place the actions inside a catch block. // If one of the actions raises an error, the catch // block will make sure the state is set before // re-raising the error. // v. 2.2.0: Check if the user has turned off this // feature first. if (Smc.isNoCatch() == false) { indent3 = indent2 + " "; _source.print(indent2); _source.println("if [catch {"); } else { indent3 = indent2; } for (SmcAction action: actions) { action.accept(this); } // v. 2.2.0: Check if the user has turned off this // feature first. if (Smc.isNoCatch() == false) { _source.print(indent2); _source.println("} result] {"); // v. 2.0.2: Generate the set state, push or pop // code for the if's then body. Note: the catch // body was generated only if there were actions. if (transType == Smc.TRANS_SET) { _source.print(indent3); _source.print("$context setState "); _source.print(endStateName); _source.println(";"); } else if (transType == Smc.TRANS_PUSH) { _source.print(indent3); _source.print("$context setState "); _source.print(endStateName); _source.println(";"); // Before doing the push, execute the end // state's entry actions (if any) if this is // not a loopback. if (loopbackFlag == false) { indent4 = indent3; if (defaultFlag == true) { indent4 = indent3 + " "; _source.println(); _source.print(indent3); _source.println( "if {$loopbackFlag == 0} {");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -