OpenGLContext Event Model

This document describes the mechanisms within OpenGLContext which allow for providing interactivity, both at the context and the scenegraph levels.  This includes keyboard and mouse events, as well as timers and routes.

Features of the Event Model

There are a number of user-level features which are implemented by the "event model" within OpenGLContext:

each of these features will be discussed below.


The PyDispatcher package is the primary mechanism used for event propagation within OpenGLContext 2.0.  This module allows you to register functions to be notified when "senders" send particular signals.  Each field of each node can generate signals when setting and/or deleting field values for the node.  Similarly, each event manager registers functions with the dispatcher which are to be called when a particular event is received, then sends those events when the event is actually received.

Field Watching

Fields generate signals by default on set or delete.
Nothing generated during parser-mediated instantiation save for prototyped nodes
Normally not something you want to use directly, but it is what much of the rest of the interaction is built upon.

Cache Invalidation

Built upon field watching, nodes register dependencies on node, field pairs.  If the node sends an update signal for that field, then the cache object is invalidated, and the node regenerates its cache data during the next rendering pass.

Routing Tables

Two major variants:

The ROUTE is a simple unidirectional channel through which updates to a particular field of a particular node are propagated along the arc of the route to the destination node, field pair.  This allows you to create routing tables which tie together elements within a scenegraph so that code does not need to explicitly chase down dependent fields, it can simply allow route propagation to update the dependent fields.

The PROTO's IS mapping, which maps from a prototype node's fields to fields on nodes within the prototype's internal scenegraph.  This is a bidirectional linkage, where changing the prototype's fields updates the internal nodes, and updating the internal node updates the prototype's corresponding field.

Event Handlers

Most contexts derive from the EventHandlerMixIn class, which provides a method addEventHandler, which allows for registering event handlers for given event types (specified as strings).  Individual EventHandler objects are responsible for each event type, and are responsible for processing events of their own type.  Most (currently all) EventHandler objects use the PyDispatcher module to maintain the internal structures required to provide the registration tables for the handler callbacks.

self.addEventHandler( "mousein", function = self.OnMouseIn )
self.addEventHandler( "mouseout", function = self.OnMouseOut )
self.addEventHandler( 'keyboard', name='<up>', state=1, modifiers=(0,0,0), function=self.forward )
self.addEventHandler( 'keypress', name='-', modifiers=(0,0,0), function=self.straighten)
self.addEventHandler( 'mousebutton', button=1, state = 1, modifiers=(0,0,0), function=self.startExamineMode)
self.addEventHandler( 'mousemove', buttons=(), modifiers=(0,0,0), function=self.RefreshTooltip)

 Timer objects are also based on the same mechanism (with some significant extra machinery).