// uses global variable conversation static void ctxProcessRule(S ruleName) { if (ruleName == null) ret; ++ctxContext().safetyCounter; WoodyRule rule = bot.getRule(ruleName); printObjectWithFields(rule, "fullName", "condition", "body", "properties"); // fake if (eqic(ruleName, "Agent#EVENT.NEWUSER")) { S theGoto = ctxFindFirstGoto(rule.body); print("NEWUSER -> Goto: " + theGoto); ctxContext().nextRule = theGoto; ret; } L actions = ctxActions(rule.body); if (nempty(actions)) { bool random = eq(rule.properties.get("ACTIONSELECTOR"), "RANDOMLOOP"); // otherwise assume TILLEND S name = rule.longName(); BitSet bs = conversation->randomLoopMap.get(name); if (bs == null) { condition->randomLoopMap.put(name, bs = new BitSet); conversation->change(); } new L candidates; for i over actions: if (!bs.get(i)) candidates.add(i); if (empty(candidates)) { bs.clear(); conversation->change(); for i over actions: candidates.add(i); } int idx = random ? random(candidates) : first(candidates); bs.set(idx); conversation->change(); S action = actions.get(idx); ctxProcessAction(action); ctxContext().nextRule = rule.properties.get("GOTO"); ret; } SS cases = ctxCaseGotos(rule.body); if (nempty(cases)) { S matched = null, nextRule = null; for (S cond, target : cases) { Bool b = ctxEvalCondition(cond); print(cond + " -> " + b); if (isTrue(b) && nextRule == null) { matched = cond; nextRule = target; } } ctxContext().nextRule = nextRule; // may be null if (matched != null) ret; } print("Unknown rule type"); }