Skip to content

Core Engine

SimonCzy edited this page Sep 4, 2023 · 3 revisions

These are the gory details on what AiA is doing in the background to execute and display algorithms.

The application maintains a global state that is manipulated by triggering events. Events occur in response to a user action. Components render themselves based on the current state, and React triggers a re-render when the state is updated. The relevant code in found the context directory of the source tree.

Context

The core of the application is a global state context, maintained by a useState hook. This state is responsible for keeping track of various properties of the currently executing algorithm:

  • id: Internal name of algorithm executing
  • name: Human algorithm name
  • explanation: The text to be shown in the main Explanation panel
  • instructions: The initial instructions show on screen
  • extraInfo: The Extra Info panel
  • param: The Param instance (from algorithms/params) used for user input
  • pseudocode: The pseudocode, already parsed and structured
  • collapse: The state of the pseudocode refinement blocks
  • lineExplanation: Explanations for individual lines

Other components can (and should!) reference this context using React's useContext feature. This will cause them to be automatically re-rendered when the state is updated. Components must not update the state directly, and should use events instead.

Events

The state is updated by triggering events. These events are:

  • RUN_ALGORITHM: Run a new algorithm, called when the user changes their active algorithm.
  • NEXT_LINE: Execution steps to the next visible line
  • PREV_LINE: Reverse of NEXT_LINE
  • TOGGLE_PLAY: Toggle on/off the automatic playing feature
  • COLLAPSE: The collapse state is changed (a pseudocode block is closed or opened)

Chunker

A core design of AiA is that algorithms are actually executed in their entirety when the user clicks the RUN button (just after entering their data). While executing the algorithm implementation will call the chunker regularly with the next bookmark (the \B tag in the pseudocode) as well as any animation operations to be executed.

Thus we end up with a set of "chunks" that have a relevant bookmark and a sequence of animation operations. When NEXT_LINE is triggered, the pseudocode panel changes its highlight to the bookmark in the next chunk and the next chunk's animation operations are run.

PREV_LINE is a little sneaky - it actually resets the animation state and re-applies the chunks from the beginning.

The comments in chunker.js go into some more detail about how state is captured if you're interested.