Indirect References

An indirect reference from a reference maker to a reference target means that the reference maker contains a member reference member, which holds a direct reference to the target. Indirect references allow limited circular reference hierarchies. This could be useful, for example, if a script and expression controller variable points to a node, where the controller is under the node in the reference hierarchy.

An example of a plug-in that uses indirect references is Ring Array. The Ring Array plug-in master controller needs to know about the nodes in the system object at the same time that the slave controllers of each node that is part of a Ring Array system object need to reference the master controller in order to react to changes in the parameters it holds. Thus, the master controller cannot reference the nodes, since they reference the slave controllers which reference the master controller. The Ring Array master controller holds indirect references to the nodes that are part of the system.

An indirect reference is implemented as an IIndirectReferenceMaker interface on a reference maker.

The member reference member is not exposed as a direct reference by the parent reference maker, as a result notifications and reference hierarchy enumerations aren't automatically performed between the parent and the member. If needed, the member passes notifications to the parent, and the parent passes enumerations to the member, in an implementation-specific manner.

The reference from the member to the target must be a weak direct reference. Otherwise, we could end up with undeletable "islands" of references. For example, if A holds a strong reference to B, and B holds an indirect reference to A, if the indirect reference to A was strong, then A would never be deleted because there is always at least one strong reference to it, and B would not be deleted because A is never deleted. If the method IIndirectReferenceMaker::ShouldPersistIndirectRef() returns FALSE (which it does by default), saving or loading the reference maker implementing IIndirectReferenceMaker does not force the target to be saved or loaded. Thus indirect references would normally not be forced to save or load when the maker is saved or loaded. Typical cases where an implementation of this method would return TRUE is if the indirect reference is to a node (such as in NodeTransformMonitor) or post-load callbacks are used to check and process the indirect reference. If ShouldPersistIndirectRef returns FALSE, it is possible that the target will be saved or loaded due to other references. In this case, the indirect reference link between the reference maker and the reference target will be retained.