sclass GazelleContextCache_v2 extends F0 { transient Lock lock = lock(); transient GazelleEvalContext cachedCtx; DynModule module; bool debug = true; F0>> grabRules = func -> L> { //dm_gazelle_allRulesWithComment(gazelle_requiredComment()) gazelle_allRuleTriples() }; S mechListPrefix; bool alwaysFullRefresh; // safer // TODO: add or remove if condition changes on rule *() {} *(DynModule *module) {} GazelleContextCache_v2 fill() { loadRules(callF(grabRules)); this; } void loadRules(L rules) { lock lock; cachedCtx = dm_gazelle_stdEvalContext(rules); cachedCtx.mechListPrefix = unnull(mechListPrefix); gazelle_addHelpers(cachedCtx); } GazelleEvalContext get() { lock lock; ret gazelle_cloneCtx(cachedCtx); } void ruleChanged(S ruleID) { if (ruleID == null) ret; dm_q(module, r { lock lock; if (alwaysFullRefresh) ret with fill(); 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))); gazelle_updateStatsForRule(cachedCtx, ruleID); print("GazelleContextCache_v2: rule update complete"); }); } // works only when module != null AutoCloseable listenToMessages() { ret combineAutoCloseables( vmBus_onMessage('gazellePleaseClearRuleCaches, r { dm_q(module, r fill) }), vmBus_onMessage('gazelleRuleFeedbackChanged, vf ruleChanged), vmBus_onMessage('gazelleRuleChanged, voidfunc(O ruleObj) { ruleChanged(getString globalID(ruleObj)) }), vmBus_onMessage('gazelleRuleDeleted, voidfunc(O rule) { S ruleID = getString globalID(rule); dm_q(module, r { lock lock; if (cachedCtx == null) ret; cachedCtx.engine.deleteRule(ruleID); print("GazelleContextCache_v2: rule " + ruleID + " deleted"); }) })); } void alwaysFullRefresh() { set alwaysFullRefresh; fill(); } }