diff --git a/mon-entreprise/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts b/mon-entreprise/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
index df1e9e963..5039f2f38 100644
--- a/mon-entreprise/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
+++ b/mon-entreprise/source/sites/mon-entreprise.fr/middlewares/trackSimulatorActions.ts
@@ -7,14 +7,13 @@ export default (tracker: Tracker) => {
next(action)
const newState = getState()
if (action.type == 'STEP_ACTION' && action.name == 'fold') {
- tracker.debouncedPush([
- 'trackEvent',
- 'Simulator::answer',
- action.source,
- action.step,
- situationSelector(newState)[action.step as DottedName],
- ])
-
+ // tracker.debouncedPush([
+ // 'trackEvent',
+ // 'Simulator::answer',
+ // action.source,
+ // action.step,
+ // situationSelector(newState)[action.step as DottedName],
+ // ])
// TODO : add tracking in UI instead ?
// if (!currentQuestionSelector(newState)) {
// tracker.push([
diff --git a/publicodes/source/components/Explanation.tsx b/publicodes/source/components/Explanation.tsx
index c1a6ab729..283e3eec9 100644
--- a/publicodes/source/components/Explanation.tsx
+++ b/publicodes/source/components/Explanation.tsx
@@ -28,6 +28,9 @@ import UneDeCesConditions from './mecanisms/UneDeCesConditions'
import UnePossibilité from './mecanisms/UnePossibilité'
import Unité from './mecanisms/Unité'
import Variations from './mecanisms/Variations'
+import { useContext } from 'react'
+import { EngineContext } from './contexts'
+import { InternalError } from '../error'
const UIComponents = {
constant: ConstantNode,
@@ -66,9 +69,19 @@ const UIComponents = {
export default function Explanation({ node }) {
const visualisationKind = node.visualisationKind || node.nodeKind
+ const engine = useContext(EngineContext)
+ if (!engine) {
+ throw new InternalError(node)
+ }
+
+ // On ne veut pas (pour l'instant) déclencher une évaluation juste pour
+ // l'affichage.
+ // A voir si cela doit évoluer...
+ const displayedNode = node.evaluationId ? engine.evaluateNode(node) : node
+
const Component = UIComponents[visualisationKind]
if (!Component) {
throw new Error(`Unknown visualisation: ${visualisationKind}`)
}
- return
+ return
}
diff --git a/publicodes/source/components/mecanisms/common.tsx b/publicodes/source/components/mecanisms/common.tsx
index 3ccb15fd1..b36f36381 100644
--- a/publicodes/source/components/mecanisms/common.tsx
+++ b/publicodes/source/components/mecanisms/common.tsx
@@ -289,19 +289,7 @@ export function Leaf(
!node.name.includes(' . ') &&
rule.virtualRule
) {
- return (
-
- )
+ return
}
return (
({
_meta: { contextRule: [] },
+ nodes: new Map(),
})
type Cache = {
@@ -31,6 +32,7 @@ type Cache = {
inRecalcul?: boolean
filter?: string
}
+ nodes: Map
}
export type EvaluationOptions = Partial<{
@@ -60,16 +62,10 @@ export default class Engine {
parsedRules: ParsedRules
parsedSituation: Record = {}
replacements: Record> = {}
- cache: Cache
-
- // A number that is incremented every time the situation changes, and is used
- // for inline cache invalidation.
- situationVersion = 0
+ cache: Cache = emptyCache()
private warnings: Array = []
constructor(rules: string | Record | ParsedRules) {
- this.cache = emptyCache()
- this.resetCache()
if (typeof rules === 'string') {
this.parsedRules = parsePublicodes(rules) as ParsedRules
}
@@ -88,7 +84,7 @@ export default class Engine {
this.replacements = getReplacements(this.parsedRules)
}
- private resetCache() {
+ resetCache() {
this.cache = emptyCache()
}
@@ -96,7 +92,6 @@ export default class Engine {
situation: Partial> = {}
) {
this.resetCache()
- this.situationVersion++
this.parsedSituation = mapObjIndexed((value, key) => {
if (value && typeof value === 'object' && 'nodeKind' in value) {
return value as ASTNode
@@ -153,20 +148,19 @@ export default class Engine {
}
evaluateNode(
- node: N & { lastEvaluation?: number; res?: EvaluatedNode }
+ node: N & { evaluationId?: string }
): N & EvaluatedNode {
if (!node.nodeKind) {
throw Error('The provided node must have a "nodeKind" attribute')
} else if (!evaluationFunctions[node.nodeKind]) {
throw Error(`Unknown "nodeKind": ${node.nodeKind}`)
}
-
- if (!node.res || node.lastEvaluation !== this.situationVersion) {
- node.res = evaluationFunctions[node.nodeKind].call(this, node)
- node.lastEvaluation = this.situationVersion
+ let result = this.cache.nodes.get(node)
+ if (result === undefined) {
+ result = evaluationFunctions[node.nodeKind].call(this, node)
}
-
- return node.res!
+ this.cache.nodes.set(node, result!)
+ return result as N & EvaluatedNode
}
}
diff --git a/publicodes/source/mecanisms/inversion.ts b/publicodes/source/mecanisms/inversion.ts
index 092968b7c..9c200211f 100644
--- a/publicodes/source/mecanisms/inversion.ts
+++ b/publicodes/source/mecanisms/inversion.ts
@@ -55,16 +55,15 @@ export const evaluateInversion: EvaluationFunction<'inversion'> = function (
const evaluatedInversionGoal = this.evaluateNode(inversionGoal)
const unit = 'unit' in node ? node.unit : evaluatedInversionGoal.unit
- const originalCache = { ...this.cache }
+ const originalCache = this.cache
const originalSituation = { ...this.parsedSituation }
let inversionNumberOfIterations = 0
delete this.parsedSituation[inversionGoal.dottedName as string]
const evaluateWithValue = (n: number) => {
inversionNumberOfIterations++
- this.cache = {
- _meta: { ...originalCache._meta },
- }
- this.situationVersion++
+ this.resetCache()
+ this.cache._meta = { ...originalCache._meta }
+
this.parsedSituation[node.explanation.ruleToInverse] = {
unit: unit,
nodeKind: 'unité',
@@ -141,7 +140,6 @@ export const evaluateInversion: EvaluationFunction<'inversion'> = function (
// // Uncomment to display the two attempts and their result
// console.table([{ x: x1, y: y1 }, { x: x2, y: y2 }])
// console.log('iteration:', inversionNumberOfIterations)
- this.situationVersion++
this.cache = originalCache
this.parsedSituation = originalSituation
return {
diff --git a/publicodes/source/mecanisms/recalcul.ts b/publicodes/source/mecanisms/recalcul.ts
index 74ff0ddcc..cafa9bcf4 100644
--- a/publicodes/source/mecanisms/recalcul.ts
+++ b/publicodes/source/mecanisms/recalcul.ts
@@ -32,13 +32,13 @@ const evaluateRecalcul: EvaluationFunction<'recalcul'> = function (node) {
serializeUnit(originRule.unit) !== serializeUnit(replacement.unit)
) as Array<[ReferenceNode & EvaluatedNode, EvaluatedNode]>
- const originalCache = { ...this.cache }
+ const originalCache = this.cache
const originalSituation = { ...this.parsedSituation }
// Optimisation : no need for recalcul if situation is the same
const invalidateCache = Object.keys(amendedSituation).length > 0
if (invalidateCache) {
- this.cache = { _meta: { ...this.cache._meta, inRecalcul: true } }
- this.situationVersion++
+ this.resetCache()
+ this.cache._meta = { ...this.cache._meta, inRecalcul: true }
}
this.parsedSituation = {
@@ -59,7 +59,6 @@ const evaluateRecalcul: EvaluationFunction<'recalcul'> = function (node) {
this.parsedSituation = originalSituation
if (invalidateCache) {
this.cache = originalCache
- this.situationVersion++
}
return {
...node,