Back

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:

Each instance of a GObject is then created with reference to a prototype "Platonic" GObject appropriate for its kind, constraint, and genus. In general member functions exist only in the prototype object, but data members will exist directly in the instance (required unless they are read-only; also an accessor speed optimization).

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.

Supported rendering implementations:
  • HTML - native HTML widgetry, e.g. buttons and input fields.
  • Canvas - HTML5 Canvas raster rendering.
Primitives include:
  • Point
  • String
  • Circle
  • CircleInterior
  • Polygon
  • Segment
Each primitive has three entry points:
  • 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.