For as long as rule-based modeling has existed, there has been the concept of an “update” cycle, where changes are made to rules, and then “something” demands a new model or image or output. Generally, this has been a graphics-oriented process, so that the user can see what they just did. In the prototype days of KBridge, it was “render3.” Hereafter (or at least soon), it will be “update.”
The general idea of an update process is to demand out what is needed to build a representation on some external process (to the rule system). We could be updating a CAD model, the UI, a DWG file, a Word document, etc. The update process works by calling the update on the root, and it calls the update on its children, and so on. When it completes, the model, graphics or file is “up to date” with the rules.
With KBridge, we now have a generic update process, not just one for three.js graphics. The implementation is a new rule (on BaseModel, so it is on every instantiable object) called “update.” The default rule for update is :
R.update(this); this.children.forEach(node => node.update);
The latter part is the recursive descent which makes sure all children get the message. But the first statement is the magic thing. R.update(this) does the following:
•Looks at this to see what rules it has with the (new) “Update” flag.
•For every such rule, it evaluates it.
That is all. Note that the rule named “update” is not an Update-flagged rule. The update rule is the recursive descent engine; the Update-flagged rules are the things that get done during an update cycle. The update rule is a normal rule and can be overridden; you might do this to block updates below, or to conditionalize whether updates are called or not.
To convert the older render3 system to use the new process, we could just add the Update flag to all render3 rules and be done. We aren’t doing just that; the existing render3 rules also do a tree-traversal, which is now going to be handled by the update cycle. Things that assume the existing render3 methodology may need to change (such as any demos that customize it). Existing generic parameters, like renderNode, will continue to work, and have the same meaning. Anything with “render3” in the name may not.
The new Custom UI Designs are already based on the new update model. The Custom UI “pipeline” is a totally distinct update from render3. None of the UI Designs contain Render3Mixin, and don’t care about it. The two updates do not have to be in sync; a Custom UI could update much less than the graphics image it is showing. The generic update call doesn’t force things to happen, whether a particular model actually changes is driven by that subsystem. It is the UI that demands the change to its controls, they are not pushed.
Like the three.js rendering, the Custom UI support uses the External Host protocol. This is beyond the scope of this topic, but it is a key component that allows us to create more “update” targets like DWG or CAD systems. Currently, external hosts are written by us and are part of the kernel build.
The new update is active in R.version 0.8.6 and later. As of 0.8.6, render3 has not been converted, and so we are temporarily supporting both updates. As major change, complete conversion to the new method will be incorporated in R. version 0.9.0.