I try to keep the development version in a working state, mainly
because it runs the demos on the main site and on the code page. I
typically don't commit broken code, but being human I sometimes make a
mistake and either forget a new file, or I unintentionally check in
something that I overlooked and was broken.
To address your two points:
1) The linker will attempt to resolve all dependencies it can locate
in an object. It uses regular expressions to parse the objects and
looks for known patterns which indicate a dependency. It can resolve
most, but sometimes the patterns that one developer uses don't parse
properly and a dependency is either overlooked or it is improperly
identified as a dependency. The page at
http://code.google.com/p/renderengine/wiki/EngineCodingStyle
attempts to explain what the engine is looking for to be able to parse
the cleanest. Since Javascript has so many ways to do one thing, I
chose (what I thought was) the cleanest syntax.
When you define an object and initialize it using Engine.initObject
("CLASSNAME", "PRIMARY_DEPENDENCY", function() {...}) it will
determine which objects your object depends on. The primary
dependency should be the class from which your class extends. Other
dependencies are typically resolved through included files. You need
to include the files before you call Engine.initObject() using the
Engine.include("path/filename.ext") method calls. It is up to you,
the developer, to make sure you include the needed files. Some
objects are included just by including a different file. If you look
at the source for "engine.object2d.js", you'll see that it includes:
"engine.hostobject.js". That file then includes:
"engine.container.js", "component.base.js", and "component.host.js".
Each of those has includes as well.
So when you're constructing your objects, you have to think about what
your object primarily depends on and what files those objects are
included in. Some files include multiple objects, such as
"engine.math2d.js" (which includes Math2D, Point2D, Vector2D,
Rectangle2D, and so forth. So you only need to make sure to include
"engine.math2d.js" for all of those objects to be resolvable.
Including the same file multiple times will not have a negative
impact, as the engine keeps track of which files have already been
included.
Basically, the linker will see code like:
var x = Point2D.create(3, 10);
x.mul(Vector2D.create(5, 0));
It will see "x" is a variable and store it as "already resolved". It
then sees that you're calling the create() method of Point2D and say
that your file depends on Point2D. Next it sees that the mul() method
is called on "x". Since "x" was already resolved, the linker will
assume that the mul() method is available. Finally, the create()
method of Vector2D is found, and the Vector2D class will be added as a
dependency of the class. In the end, we have the following knowns and
unknowns:
resolved: "x"
unresolved: "Point2D, Vector2D"
When the classes which Point2D and Vector2D depend on are resolved,
then the object with the code from above will be resolved as well.
That's the linker in a nutshell. Use the API docs to determine which
Javascript files contain the objects your class is using, and make
sure to include those before your class initializes.
More information can be found here:
http://code.google.com/p/renderengine/wiki/DependencyProcessor
2) The Engine class contains a method called worldTimer() which
executes each frame. When a frame is executed, the Engine will call
the update() method of its default context (the document body). Your
rendering context(s) should have been added to the default context
before your game started running. Anything that is added to your
context(s) will then be added to the chain of objects which must be
processed. So lets assume the following scenario:
* Your context is called "gameContext"
* You have 3 objects (extending from HostObject) which need to be
updated when the frame is rendered, so you add them (A,B,C) to
"gameContext"
* Each of those objects has 3 components (extending from
BaseComponent) which were added to the object (x,y,z)
The execution flow would be:
[START FRAME]
gameContext ->
A -> Ax -> Ay -> Az
B -> Bx -> By -> Bz
C -> Cx -> Cy -> Cz
[END FRAME]
Objects have the update() method, and components have the execute()
method. Contexts and HostObjects extend from Container, whose update
() method will call update() on each object contained within the
container. As you can surmise, this proceeds until all objects which
are within a container linked back to the default context have been
updated. Then a new frame is generated. This goes on until the
engine is shut down.
This is something I should probably add to the Wiki at some point.
- Brett