sclass GazelleContextCache_v2 { transient Lock lock = lock(); transient GazelleEvalContext cachedCtx; DynModule module; bool debug = true; *(DynModule *module) {} void fill { lock lock; cachedCtx = dm_gazelle_stdEvalContext(dm_gazelle_allRulesWithComment("discord")); gazelle_addHelpers(cachedCtx); } GazelleEvalContext get() { lock lock; ret gazelle_cloneCtx(_cachedCtx); } AutoCloseable listenToMessages() { ret combineAutoCloseables( vmBus_onMessage('gazelleRuleChanged, voidfunc(O rule) { temp module.enter(); lock lock; if (cachedCtx == null) ret; S ruleID = getString globalID(rule); print("GazelleContextCache_v2: processing rule update " + ruleID); RuleEngine2 engine = cachedCtx.engine; RuleEngine2.Rule rule = engine.getRule(ruleID); if (rule == null) ret; engine.rules.remove(rule); PairS p = dm_textAndCommentForRule(ruleID); if (p == null) ret; engine.addRules2(ll(t3(p.a, p.b, ruleID))); rule = cachedCtx.engine.getRule(ruleID); if (rule == null) ret; gazelle_addHelpers(gazelle_dummyEngineWithRule(rule)); print("GazelleContextCache_v2: rule update complete"); }), vmBus_onMessage('gazelleRuleDeleted, voidfunc(O rule) { temp module.enter(); lock lock; if (cachedCtx == null) ret; S ruleID = getString globalID(rule); cachedCtx.engine.deleteRule(ruleID); print("GazelleContextCache_v2: rule " + ruleID + " deleted"); })); } }