August 91 - Speedcode
Speedcode
Huan Keh, Walter Wittel, and Ted Lewis
Speedcode is of interest to MacApp programmers because it's currently being ported to
platforms other than the Macintosh, because it is part of a system that makes use of
code generation technology, and because it claims to be smaller and simpler than
MacApp. The initial release of Oregon Software Universe 3-the development system
that contains the Speedcode framework-is expected in September. A book is underway
as well.
Walter Wittel is a software engineer for Microsoft, and Huan Keh is a PhD candidate at
Oregon State University. Speedcode is part of Keh's PhD dissertation and Wittel's MS
thesis under the direction of Ted Lewis, who is a Professor of Computer Science at
Oregon State University. Their work was partially supported by Apple Computer.
This article concentrates on the framework portion, Speedcode, of OSU 3. Look for
additional articles that cover other aspects of the OSU 3 system in future issues of
FrameWorks.
In Search of the Holy Grail
Programmers are always attempting to reduce the time and effort to produce the next
great application. In GUI programming on machines like the Macintosh, there is a high
cost of learning the toolbox routines and the intricacies of event-driven programming.
The holy grail of Mac programming has become the search for automatic tools like
program generators and application development frameworks.
In 1985, we formed a team of students and faculty to study ways in which programmer
productivity on the Mac could be increased. Our first attempt was Oregon Speedcode
Universe (OSU), which looked a lot like Prototyper or AppMaker.
Funding from Dupont corporation allowed us to improve OSU, and in 1989, we
released OSU 2 to the world. Version 2 was able to connect to VideoWorks II movies,
and in general made GUI programming as simple as MacDraw. But OSU 2 had severe
limitations-one of which was that it generated Pascal, meaning that it couldn't take
advantage of design or code reuse.
Since late 1989, we've been working long hours to produce a C++-based application
framework that is somewhat portable across different GUI platforms and much more
capable than OSU 2. We're now on the verge of releasing OSU 3 to the world in the form
of a book and free source code. The expected first release date of the source code and
minimal documentation is September 1991.
The search for the holy grail is not over, but we feel that OSU 3 is a step in the right
direction. It incorporates the following tools:
• Application Framework, including extensive class library; see Figure 1.
• PetriNet Editor, used to sequence applications code; this is how
application specific functions are added to the basic framework.
• Browser-yet another class hierarchy browser.
• Code Generator, which synthesizes C++ code from the framework,
PetriNet, and programmer supplied routines.
• RezDez-yet another resource editor.
We don't have enough space in this article to describe the entire OSU 3 system, so for
the moment, we'll focus on the framework portion only. For brevity, we call the OSU
Application Framework Speedcode.
Intimations of Leverage
Before we dive into the details of Speedcode, let me emphasize that this approach is
still in its infancy, and we don't yet know what it is capable of doing to the development
process. However, we are encouraged by early results that suggest a 10-to-1
reduction in lines of code for small applications-and we are hoping for a 2 or 3-to-1
reduction in the size of code that must be manually written for large applications. The
following table is not meant to be a commercial break, but only to suggest early
results of using Speedcode to produce some of its own tools:
Application Mac toolbox & C++ Speedcode & C++ Ratio
___________________________________________________________
MVC Demo 3000 300 10:1
MiniDraw Demo 7000 300 23:1
ExampleDraw 8000 300 27:1
PetrNed Editor 6000 2500 2.4:1
Browser 4700 2000 2.4:1
____________________________________________________________
These lines-of-code estimates were obtained by comparison between the application
written in C++ using the Mac Toolbox, and the same application written in C++ using
Speedcode. The numbers are probably only representative of small applications.
Note that the Speedcode framework contains 16K lines of C++ itself. So the lines of
code quoted in the "Speedcode with C++" column are the number of lines of code that
the programmer had to add to the 16K lines of reusable code that always exists in the
framework.
A FrameWork, or a Toolkit?
Most of you may already familiar with frameworks such as MacApp, ET++, and
InterViews. But like pornography, everyone knows what a framework is, but we often
have trouble defining it. Besides, what is the difference between a framework and a
toolkit? Before going further, perhaps we can define what a framework is.
When function A calls function B, we say A is the caller and B is the callee. In a toolkit
approach such as provided by the Mac OS, application programs are callers and toolbox
routines are callees. In fact, many C++ class hierarchies have been described as
frameworks, but in reality they are only toolkits. Why?
One of the most important features of a framework is that application code written by
the programmer is composed of callee functions-the caller functions are all part of the
framework. So, the next time you see an advertisement for a C++ framework, ask
yourself, "who is the caller, and who is the callee?
A true framework should also incorporate some paradigm or pattern of design that is
used consistently throughout. A design paradigm is simply a pattern of function calls,
data structures, and general program organization that obeys some rules of behavior.
This is where MacApp and many other frameworks are weak; it's one of the reasons we
decided to build a replacement for MacApp.
Speedcode-Overview
Speedcode uses an object-oriented paradigm. This means that all applications are
constructed by repeated application of a pattern of specialization. Specifically, all
applications are special instances of the framework. In Speedcode, programmers form
special cases by instantiating an existing class from the built-in library, subclassing,
overriding methods, or extending the class library through the addition of new classes.
Second-and this is a major feature-Speedcode incorporates an advanced version of the
Model-View-Controller (MVC) paradigm put forth by the inventors of SmallTalk. For
the programmer, this means that multiple views of the same data are automatically
updated whenever any change occurs to the data. So, if spreadsheet data is viewed both
as a spreadsheet and a bar chart, and the user changes the data in the spreadsheet view,
it is automatically changed in the bar chart view. The separation of applications into
Model=Data, View=Display, and Controller=Interaction with the user, alters the
paradigm of the program. Recombining the Model, View, and Controller parts of an
application into a framework makes the framework much more useful than a simple
class library.
Speedcode implements automatic change propagation in a variant of the MVC paradigm.
This also means that Speedcode removes this detail from concern by the programmer.
Thus, the Speedcode framework must be more "intelligent," and the class hierarchy
must do most of the work of storing data in RAM and on disk. Note that the data storage
hierarchy in the class library of Speedcode is very extensive as a consequence of this
decision-but I am ahead of our story.
Now, we are ready for a formal definition of framework: An object-oriented
application framework is a mixture of abstract and concrete classes along with a model
of interaction and control flow among the classes. The framework has "hooks" to allow
an application programmer to plug in objects that represent the functionality unique
to the application. Generic features, such as handling windows, undo and redo of
commands, saving and opening files, and printing-which are always found in a GUI
application-are provided by the framework as reusable code.
SpeedCODE-Technical details
With that breathtaking introduction, we're now ready to get technical. Once again, it's
impossible to give all the details in this survey. I'll concentrate mainly on the class
hierarchy here, but remember that this is only a small part of the application
development system. Contact the authors for complete details on OSU 3, and for
information on how to obtain your own copy.
The OSU Application Framework is written in MPW C++ and built on top of the
Macintosh Toolbox. It is divided into three parts: the data structure class library, the
shape class library, and the application framework classes. Figure 2 shows the class
hierarchy of the OSU Application Framework.
The data structure class library is rooted at the Collection class, the shape class
library is rooted at the Shape class, and others are application framework classes. The
data structure class library defines general useful data structures, such as arrays,
lists, and sets. The shape library supports various kinds of shapes and defines the user
interface for creating and manipulating these shapes. The application framework
classes define much of a Macintosh application's standard user interface, generic
behavior, and operating environment. In order to show the differences between our
framework, MacApp, and ET++, the simplified class hierarchies of MacApp and ET++
are also given in Figure 3 and Figure 4, respectively. The Application class is
much smaller than MacApp's TApplication. The Application object manages a list of all
the windows used by the program, runs the main event loop, and dispatches events to
the appropriate objects to handle them. The programmer will always subclass
Application and each program will have one, and only one, instance of that subclass.
The Document class encapsulates the data structure or model of an application and
knows how to fill the model with data. Document is not a subclass of Controller as in
MacApp and ET++.
The abstract class Command not only supports Undo and Redo operations but also helps
structure complex applications. The Command objects are normally pushed onto the
Undo stack by Menu, Palette, or Window objects and pushed onto the Redo stack and
popped off the Redo and Undo stacks by Window objects only.
Each Pane object has its own coordinate system and clips the drawing of a view to a
rectangular area (the pane's frame). It also handles scrolling the view displayed inside
it. Panes can be installed within other panes. This results in an hierarchical
subpane/superpane relationship. The Window object can contain subpanes, and is
always the topmost pane in the subpane/superpane hierarchy.
The relationship among documents, views, and windows is important. In general, a
user's program follows a three-step process in creating a new domain-specific view
to display the data in the model filled by a document.
First, the menu or the application object creates and initializes the window that will
hold the view objects. Then, the window creates and initializes its document. Finally,
the document creates and initializes the view objects.
Figure 5 shows the message flow diagram in our modified MVC paradigm. The standard
interaction cycle in modified MVC can be described as follows. The Application
controller is used as the top level event handler or dispatcher. When the user takes
some input action, the Application controller either handles this event or dispatches it
to the Menu, Palette, or the Window/Pane controller depending upon the type of the
event. The Menu, Palette, or Window/Pane controller then dispatches the event to the
appropriate view.
After handling the event, the view notifies the model to change itself and the model in
turn broadcasts change messages to its dependent views. Views can then query the
model about its new state, and update their display if necessary.
Data Structure Class Library
The data structure class library is a portable collection of classes similar to those of
Smalltalk collection classes (see Figure 6). It includes generally useful abstract data
types such as OrderedCollection, Set (hash table), ObjList (linked list), and
Dictionary. We have used these data structure classes extensively for the
implementation of the OSU Application Framework itself and the set of high level tools
in OSU 3.0. The data structure class library is rooted at the Collection class shown in
Figure 2.
The Shape Class Library
It's quite an understatement to say that graphics are an important part of most GUI
applications. Unfortunately, there isn't any standard code in either the Macintosh
Toolbox or MacApp to implement structured graphics. The result is that there are
subtle differences between applications in how the user manipulate shapes.
Our solution to this problem is to implement a standard shape library that can be used
in any application that manipulates shapes (see Figure 7). The class hierarchy of the
shape library is rooted at the Shape class shown in Figure 2. Our shape library
handles various kinds of shapes, so that it is usable in a variety of applications. It also
allows the programmer to customize and extend the way shapes are manipulated