{"version":3,"sources":["https://lively-kernel.org/lively4/lively4-constraints/demos/engery-sim/engine.js"],"names":["_","MAX_VELOCITY","MIN_VELOCITY","MILLISECONDS_PER_SECOND","Engine","constructor","velocity","collectCells","stopOnError","time","timeDeltaPerStepInMilliseconds","toggleStartStop","isRunning","wasRunning","stop","start","updateSimulationLoop","step","limitExecution","cells","sortedCells","sortBy","prevState","collectState","injectTime","executionCells","executeAllCells","nextState","updateCellStates","state","dt","increaseVelocity","setVelocity","min","decreaseVelocity","max","setTime","setTimeDeltaPerStepInMilliseconds","forEach","cell","setState","getNormalizedName","reduce","partialState","getState","statePromise","then","execute","resolve"],"mappings":"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","file":"engine.js","sourcesContent":["\"enable aexpr\";\n\nimport _ from 'src/external/lodash/lodash.js';\n\nconst MAX_VELOCITY = 60;\nconst MIN_VELOCITY = 1;\nconst MILLISECONDS_PER_SECOND = 1000;\n\nclass Engine {\n  \n  constructor(velocity = MIN_VELOCITY, collectCells = () => [], stopOnError = false, time = 0, timeDeltaPerStepInMilliseconds = 1 * MILLISECONDS_PER_SECOND) {\n    this.collectCells = collectCells;\n    this.velocity = velocity;\n    this.stopOnError = stopOnError;\n    this.time = time;\n    this.timeDeltaPerStepInMilliseconds = timeDeltaPerStepInMilliseconds;\n    this.step = this.step.bind(this);\n  }\n  \n  toggleStartStop() {\n    const { isRunning: wasRunning } = this;\n    if (wasRunning) this.stop();\n    else this.start();\n  }\n  \n  start() {\n    const { isRunning } = this;\n    if (isRunning) return;\n    this.isRunning = true;\n    this.simulationLoop = setInterval(this.step, (MILLISECONDS_PER_SECOND / this.velocity));\n  }\n  \n  stop() {\n    const { isRunning } = this;\n    if (!isRunning) return;\n    this.isRunning = false;\n    clearInterval(this.simulationLoop);\n  }\n  \n  updateSimulationLoop() {\n    const { isRunning } = this;\n    if (!isRunning) return;\n    this.stop();\n    this.start();\n  }\n  \n  step(limitExecution) {\n    const cells = this.collectCells();\n    const sortedCells = _.sortBy(cells, ['offsetTop', 'offsetLeft']);\n    const prevState = this.collectState(sortedCells);\n    const time = this.injectTime(prevState);\n    const executionCells = limitExecution || sortedCells;\n    return this.executeAllCells(executionCells, prevState, time)\n      .then(nextState => this.updateCellStates(sortedCells, nextState))\n      .then(() => this.stepCounter++);\n  }\n  \n  injectTime(state) {\n    const { time, timeDeltaPerStepInMilliseconds } = this;\n    this.time = time + timeDeltaPerStepInMilliseconds;\n    state['simulation'] = { time: this.time, dt: timeDeltaPerStepInMilliseconds };\n    return this.time;\n  }\n  \n  increaseVelocity() {\n    const { velocity } = this;\n    this.setVelocity(Math.min(MAX_VELOCITY, velocity + 1));\n  }\n  \n  decreaseVelocity() {\n    const { velocity } = this;\n    this.setVelocity(Math.max(MIN_VELOCITY, velocity - 1));\n  }\n  \n  setVelocity(velocity) {\n    this.velocity = velocity;\n    this.updateSimulationLoop();\n  }\n  \n  setTime(time) {\n    this.time = time;\n  }\n  \n  setTimeDeltaPerStepInMilliseconds(dt) {\n    this.timeDeltaPerStepInMilliseconds = dt;\n  }\n  \n  updateCellStates(cells, state) {\n    _.forEach(cells, cell =>\n      cell.setState(state[cell.getNormalizedName()]));\n  }\n\n  collectState(cells) {\n    return _.reduce(\n      cells, \n      (partialState, cell) => { \n        partialState[cell.getNormalizedName()] = cell.getState();\n        return partialState;\n      },\n      {}\n    );\n  }\n  \n  executeAllCells(cells, state, time) {\n    const { stopOnError } = this;\n    return _.reduce(\n      cells, \n      (statePromise, cell) => \n      statePromise\n        .then(state => cell.execute(time, state))\n        .catch(({ state }) => (!stopOnError || !this.stop()) && state),\n      Promise.resolve(state)\n    );\n  }\n}\n\nexport default Engine;"]}