I will present a series of usages for a hypothetical high-level
framework that exists only in my mind. The purpose would be to
illustrate how I imagine my framework might work in such situations,
so that others may understand and comment on my proposal.
== Requirements
* Component-based: The framework must allow a range of disparate and
different components to interact with each other without assuming too
much about the content of such communications. The framework must
allow components to negotiate their own interactions, and facilitate
them wherever possible.
* Multi-core ready: The framework cannot preclude numerous popular and
well known means of sharing workload over multiple CPU cores. Such
methods may be multi-threading, multi-processing, and Software
Transactional Memory. The framework must minimize coupling and data
dependencies across boundaries that may possibly be run concurrently
one day.
* Easy to understand: The framework must have consistent and simple
semantics, and decompose naturally into smaller parts, so it is
possible for a normal person to comprehend it and reason about its
functioning one component at a time; and thus allow the programmer to
the chance to avoid making hard to debug mistakes.
* Easy to use: The framework must make the programmer's life easier,
otherwise it has no purpose.
== Smoke Demo as a basis:
http://software.intel.com/en-us/articles/designing-the-framework-of-a-parallel-game-engine/
The smoke demo is only special in so far as it provides a concrete
example of working code that has some similarity to what I think is
important for a framework. I do not intend to use it verbatim, though
I do feel that if we started out by modifying and evolving from that,
it wouldn't be a mistake.
== A Day in the Life of The Framework
=== Waking Up
# The Launcher loads the Framework and reads in a configuration file
for the application.
# The configuration defines which components to load.
## For each component, bring the binary into memory an run its initializer.
# The first component is the "reX Logic" component, which holds all
logic and state for a reX/OpenSim/SL-based world.
## The reX Logic component creates its World Model within the
Framework's Shared Data system as publisher. As of yet, no one is
subscribed to the model.
## The reX Logic component depends on the "reX Protocol" component,
which does all packet handling and event generation for
reX/OpenSim/SL-based servers. It is loaded by the Framework.
### The reX Protocol component notifies the Framework that it is ready
to accept requests.
## When the reX Logic component hears that reX Protocol is ready to
accept requests, it subscribes to all events published by reX
Protocol.
## The reX Logic component depends on the "reX Security" component,
which is responsible for acquiring security tokens. It is loaded by
the Framework.
### The reX Security component reads stored configuration, including
authorization passwords, and readies its internal state for relaying
any authorization requests (using a protocol which may be different
from one defined by reX Protocol).
### The reX Security component registers an Authorization Interface
with the Framework for authorizing credentials.
### The reX Security component notifies the Framework that it is ready
to accept requests.
## The reX Logic component depends on the "reX Avatar" component,
which is responsible for storing all information related to a reX
Avatar, including appearance, grid location, and authorization
credentials, etc. It is loaded by the Framework.
### The reX Avatar component loads Credentials and Authority from file.
### The reX Avatar component notifies the Framework that it is ready
to accept requests.
## The reX Logic component notifies the Framework that it is ready to
accept requests.
# The next component is the "Foo GUI" component.
## The Foo GUI reads its skin and other configuration from file.
## The Foo GUI component creates its Drawing Context in the Shared
Data system as publisher. The specific format of the DC is specific to
Foo GUI.
## The Foo GUI creates a root window and any child windows or decorations.
## The Foo GUI subscribes to the Avatar data in the Framework's Shared
Data system.
## The Foo GUI sets its internal state to "Startup"
## The Foo GUI component notifies the Framework that it is ready to
accept requests.
# The next component is the "Ogre3D" component.
## The Ogre3D reads its configuration from file.
## The Ogre3D component creates its Drawing Context in the Shared Data
system as publisher. The specific format of the DC is specific to
Ogre3D.
### The Foo GUI component is notified of Ogre3D's Drawing Context, and
replaces its own with Ogre3D's.
## The Ogre3D subscribes to the World Model in the Framework's Shared
Data system.
## The Ogre3D component notifies the Framework that it is ready to
accept requests.
=== Connecting
# When reX Logic hears that reX Protocol, Avatar, and GUI are ready to
accept requests, it requests a reference to IRexProtocol,
IAvatarStorage
and IGUI from the Framework, which connects to it to the reX Protocol,
Avatar and Foo GUI components respectively.
# reX Logic calls IAvatarStorage.LoadAll
## reX Avatar requests a reference to IAuthorize from the Framework,
which connects to it to the reX Security component.
## reX Avatar gets Security Token returned by
IAuthorize.GetToken(Authority, Credentials), and places it in the
Framework's Shared Data system.
## reX Avatar retrieves the Avatar data using Security Token.
## reX Avatar creates the Avatar data in the Framework's Shared Data,
as the publisher.
# Foo GUI is notified of the addition of Avatar data, but because it's
state is "Startup", needs to be hinted what to do next by reX Logic.
# reX Logic subscribes to SelectedAvatar, and calls IGUI.SelectLoginAvatar
# Foo GUI draws the Avatar Chooser dialogue using the Avatar data from
Shared Data.
# Foo GUI writes the selected identity to SelectedAvatar when the user
chooses the an avatar through the GUI.
# Foo GUI sets its internal state to "LogingIn".
# reX Logic is notified when SelectedAvatar is written to, and calls
IRexProtocol.Login(Avatar[SelectedAvatar], SecurityToken).
## reX Protocol generates the correct series of packets, and places
them on the network.
## reX Protocol writes a valid Session Token to Shared Data upon
completion of the handshake.
# reX Logic receives a LoginSuccessful Event from reX Protocol upon success.
# reX Logic calls IRexProtocol.EnterRegion(SessionToken, Region)
## reX Protocol generates the correct series of packets, and places
them on the network.
## reX Protocol begins streaming World data.
# reX Logic handles World data events by filling the World Model in Shared Data.
# Ogre3D is notified that there is new data in the World Model.
# Ogre3D inspects the World Model, and uses the information to
construct a Rendering Model.
# Ogre3D draws the Rendering Model to the Framebuffer, and places a
pointer to the Framebuffer Object in Shared Data.
# Foo GUI is notified of the new data in the Framebuffer Object, and
draws the object as a texture underneath its own GUI.
Cheers,