Web Sketchpad Code Architecture
Version 4.8.0
Web Sketchpad Architecture
Contents
Introduction
Web Sketchpad follows the fundamental design of the existing C based desktop application architecture, adapting that to native Javascript idioms. For example, where the C code uses function pointers and casts, the Javascript code will use object inheritance.
The Document
The Document is the fundamental object for an instance of Web Sketchpad. It is responsible for loading JSON documents, and is the owner of the various pages of the document (or in terms of the code, the document contains sketches).
The Sketch
Each sketch in a document contains the visible, user interactable represention of a set of geometric objects. It is responsible for handling browser events, pumping the animation loop, and re-constraining and redrawing.
GObjects
In general, Web Sketchpad follows implements the standard Sketchpad hierarchical model of GObject taxonomy for Kinds, Constraints, and Genera.
Inheritance
GObject inheritance is implemented using Javascript prototype chain. There are three hierarchies:
- Kind - basic / primary. API's correspond roughly to object as displayed: rendering / hit-testing.
- Constraint - relationship to parents.
- Genus - Interface variants transcending Kind, e.g. Path.
Platform Abstractions
Mousetouch
The Browsers follow the Javascript event model, and fire a variety of events based on user input. Touch events are newer than mouse events, and their behavior is not fully specified. In any case, touch events are not sent on mouse-only platforms.
Web Sketchpad adopts a touch centric "Mousetouch" abstraction, where higher-level code looks only for touch events, thus ensuring multi-touch compatibility. At the lower-level, the mousetouch module normalizes events to conform to the touch API - converting mouse events to touch events, in essence considering the mouse an instance of a touch. In general, mouse touch follows the Apple TouchEvent API
Graphics Engines
Browser capabilities for rendering complex graphics vary widely, both in basic support and quality of implementation. Web Sketchpad abstracts the rendering of GObjects with a drawing architecture which supports both raster and vector "Engines". Currently, we rely mostly on an HTML5 Canvas engine, which proved fastest. Where text is involved, and layout of text, we'll use an HTML/CSS engine.
Drawing Primitives
Each Graphics Engine implements a subset of possible primitives, roughly corresponding to the renderproc of a GObject kind. This enables an engine to optimize based on the relative permanence of the GObject as a graphical entity. Common code is expected to decide which engine to use for a given GObj based on the capabilities of the engines and their availability in the current browser.
- HTML - native HTML widgetry, e.g. buttons and input fields.
- Canvas - HTML5 Canvas raster rendering.
- Point
- String
- Circle
- CircleInterior
- Polygon
- Segment
- prepare - called once before first render.
- draw - called at each render (counting changing visibility as a render).
- cleanup - called before last render.
Drive Chains
Several Sketchpad objects (iterations, loci, function plots) involve sampling a (conceptually) moving "driver" gobject, and sample the geometry of some specified derived gobject. The minimal list of derived objects that lead from the driver to the sampler constitutes the "drive chain". Web Sketchpad implements a "clone" based drive chain architecture, where each element of the drive chain is not the actual in-sketch object, but rather a lightweight copy of it (via prototype inheritance). So you change the geometry of the drive chain without messing up the geometry of the actual gobjects. This is a different technique than used in the native code (there there is a save / move / restore that happens with the live objects).
DOM Embedding Stucture
A Document is embedded in HTML by attaching it to some already existing client DOM node - the baseNode. Beneath that there are some WSP-created nodes:
- wsp-base-node
- Main wsp controlled container. We can set css here without messing up the client owned DOM element.
- wsp-clip-node
- A child of the wsp-base-node, the clip node exists to clip rendered content to the client area via the css clip property. This can't be on the wsp-base-node because we must require the parent to be non have static positioning.
- Render Layers
-
Under the wsp-clip-node are the layers that render the actuall WSP content.
- canvas - canvas render engines in an HTML5 Canvas element
- wsp-text-layer - Parent node for various forms of text, including captions, buttons, and parameters
Drive Chains
Several Sketchpad objects (iterations, loci, function plots) involve sampling a (conceptually) moving "driver" gobject, and sample the geometry of some specified derived gobject. The minimal list of derived objects that lead from the driver to the sampler constitutes the "drive chain". Web Sketchpad implements a "clone" based drive chain architecture, where each element of the drive chain is not the actual in-sketch object, but rather a lightweight copy of it (via prototype inheritance). So you change the geometry of the drive chain without messing up the geometry of the actual gobjects. This is a different technique than used in the native code (there there is a save / move / restore that happens with the live objects).
Expression Parsing
Web Sketchpad understands the Mathematics Formatting System (MFS) and infix expression syntax of GSP. It parses them using a parser constructed from their respective grammars at compile time. Infix expressions are converted for evaluation to javascript functions, and, for presentation, to MFS text. MFS text, is, in turn, converted to HTML for display.
The parsing is done via PegJS.