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 ruleObj) { fS ruleID = getString globalID(ruleObj); dm_q(r { lock lock; if (cachedCtx == null) ret; print("GazelleContextCache_v2: processing rule update " + ruleID); RuleEngine2 engine = cachedCtx.engine; RuleEngine2.Rule rule = engine.getRule(ruleID); if (rule == null) print("GazelleContextCache_v2: rule not found, assuming it's new"); else engine.rules.remove(rule); PairS p = dm_textAndCommentForRule(ruleID); if (p == null) ret with print("GazelleContextCache_v2: no text found for rule"); engine.addRules2(ll(t3(p.a, p.b, ruleID))); rule = cachedCtx.engine.getRule(ruleID); if (rule == null) ret with print("GazelleContextCache_v2: rule not properly added"); gazelle_addHelpers(nu(GazelleEvalContext, engine := gazelle_dummyEngineWithRule(rule))); print("GazelleContextCache_v2: rule update complete"); }) }), vmBus_onMessage('gazelleRuleDeleted, voidfunc(O rule) { S ruleID = getString globalID(rule); dm_q(r { lock lock; if (cachedCtx == null) ret; cachedCtx.engine.deleteRule(ruleID); print("GazelleContextCache_v2: rule " + ruleID + " deleted"); }) })); } }