Class CRProtoInstance

java.lang.Object
org.web3d.vrml.renderer.CRProtoInstance
All Implemented Interfaces:
VRMLExecutionSpace, VRMLNode, FrameStateListener, VRMLNodeType, VRMLProtoInstance

public class CRProtoInstance extends Object implements VRMLProtoInstance
A concrete instance of a Prototype that is common for all renderers.

This class cannot be instantiated directly. The only way to get an instance of this is to ask for one from a proto implementation - either external or normal. As a node that does not form part of the scene graph, the fields that are those of the root node's definition. If you ask for the normal implementation node, you will also get this first node.

IS Implementation

This implementation handles IS values as a sort of route with a few missing bits. When a value is set in the interface declaration, we look up all the IS related nodes and fields. For each of these we then call sendRoute() on them to update their value.

For the reverse case, when a value changes inside the proto body, we just mark the field as being changed in that node. Then, when someone checks the proto interface field, it will go through the list of related IS nodes and ask their field if it has been updated. If it has, then this value is copied to the interface declaration field and, using setValue() call on the interface field, makes sure it gets propagated to the other users.

Note: The upshot of this implementation is that is does not correctly deal with IS values where the end user has not connected a ROUTE to one of the proto declaration fields. In order to send values to items where there is an IS, we rely on having the user call hasFieldChanged() or setValue() to update all the internal users of the field. In the case where fields are not routed, this means that hasFieldChanged() is never called and hence the other users of IS are never informed.

DEF/USE Handling

Because you can DEF an instance of a Proto, we run into all sorts of interesting problems. As we have to put in Java3D shared groups and stuff we really need access to the root node before it is created. The problem there is that we don't have that access, and even when we do it is too late to deal with the DEF work. In an ideal world, when you ask for the implementation node the J3D node it returns and the node this instance returns are going to be the same thing. DEF completely stuffs with that idea.

The solution implemented here is to take the root node and apply any wrapping that may be needed to get it to work in a shared environment. In order to use a ProtoInstance within the J3D scene you first check for the type being correct by asking for the Implementation node and checking the interface corresponds to one that you are allowed to accept. If that passes then you check for the DEF with isDEF() just like any other node. Then, to add the real object to the scene graph you call either getSharedObject() or getSceneGraphObject() as appropriate. Note that they must be called on this class instance, not on the implementation node. If you call them on the implementation instance, the results are undefined and will probably lead to a lot of errors generated by the Java3D internals.

Version:
$Revision: 1.77 $
Author:
Justin Couch