Signals system
27.11.2007 Anton VolkovIn almost every flash 3d-engines I know graphics is re-calculated constantly — even in nothing is changed on a scene. Taking “do not calc same things twise” optimizing principle into account, we were thinking how to calculate only changed things.
At first we managed to use flags system. For example, when setting new coords for object, we set its flag coordsChanged = true. Then, thru the different checks, visualisator decided to only move this object, without re-drawing its graphics. So this system made up its way to version 4 and thanks to it we have good performance in a demo.
Then, along with engine development, this came to a very complicated flags dependencies. We got excess check-ups somewhere, and flag cleaning task become difficult too — there are a lot of materials, points, edges, even composite (like lists) flags. So finally we got a non-transparent system with additional processor load due to constant flag checking and cleaning (30-40% without changes on a mid-complicated scene with shadows).
That lead us to review engine architecture. At the moment we created and testing new changes system — signals system.

Let’s enter a couple of new definitions — signal and operation. Signal is an analog of event. Every signal is unique and belongs to a certain object. Operation is a link to a certain method of a certain object.
Signals can create and cancel other signals, run operations. So, when creating scene, we form links between objects, their signals and operations. On a scheme we call consequences “Sequels” and canceled signals — “Cancels”.
Every on-scene objects change creates according signal. At the scheme Object2 moves and its sub-object Subobject2 rotates. This generates two signals — move and transform.
At the next scene calculating we analize signals list and add new signals to it. At the scheme Object2 “moves” and makes Subobject1 and Subobject2 to “move” too.
Then list is cleaned from cancelled signals. In our example Subobject2 transform signal cancels its move signal (transforming is more complicated and includes moving, so we don’t have to make it twice and just ignore it).
At the end we form list of operations to do, to show scene correctly. But, operations have to be made in a proper order. There is no sence to calculate objects lighting ang then to move object somewhere. So operations have run priorities too.
Another problem — sometimes it is important which of operation to perform first even if they have equal priority. At the scheme it is not correct to calculate Subobject2 transformation, because we have to calculate Object2 coords first. So some operations have “level”.
Now we sort operations list using this parameters and perform them accordingly.
First tests showed there is no additional processor load at all, and the system works 15-20% faster. At also became better in a terms of transparency, because signals are concentrated in one place and it is easy to trace them too.

28.11.2007 в 03:24
Good points. Yes flags are bad for component independence and get very complex and do not scale. Broadcasting is much better.
# COMPONENT INDEPENDENCE - scale to ease from worse to best
* independent as possible - supports reuse supports maintainability
* coupling
o content coupling: if one component modify data or instructions in another (bad reliability)
o common: communicate via shared data storage (high risk all connecting to one datastore)
o control coupling coupling: 2 components are control coupled a->b if a uses flags to control b. (flags are lazy and bad for reuse - disgustingly complicated)
o stamp coupling: 2 modules of components communicating via some sort of passed data structure that contains more info than needed. (reliability issues when more information than needed - bad for scale)
o data coupling: sending messages, events, passing parameters messages aren’t flags and only typically what is needed.
22.04.2008 в 15:07
[…] Signals system — only nesessary calculations; […]