1 Properties

1.7 Inheritable Properties

Suppose we have a hierarchical arrangement of property-exporting objects, each exporting an identical property called stiffness whose value is a double (properties are considered identical if they have the same name and the same value type). It might then be desirable to have stiffness values propagate down to lower nodes in the hierarchy. For example, a higher level node might be a finite element model, with lower nodes corresponding to individual elements, and when we set stiffness in the model node, we would like it to propagate to all element nodes for which stiffness is not explicitly set. To implement this, each instance of stiffness is associated with a mode, which may be either explicit or inherited. When the mode is inherited, stiffness obtains its value from the first ancestor object with a stiffness property whose mode is explicit.

This is an example of property inheritance, as illustrated by Figure 1.1. Stiffness is explicitly set in the top node (A), and its value of 1 propagates down to nodes B and D whose stiffness mode is inherited. For node C, stiffness is also explicitly set, and its value of 4 propagate down to node F.

Figure 1.1: Inheritance of a property named “stiffness” within a hierarchy of property-exporting objects. Explicitly set instances of the property are surrounded by square boxes.

Another common use of property inheritance is in setting render properties: we might like some properties, such as color, to propagate down to descendant nodes for which a color has not been explicitly set.

To state things more generally: any property which can be inherited is called an inheritable property, and is associated with a mode whose value is either explicit or inherited. The basic operating principle of property inheritance is this:

Important:
An inherited property’s value should equal that of the nearest matching ancestor property which is explicitly set.

Other behaviors include:

  • Setting a property’s value (using either the set accessor in the host or the set method of the Property handle) will cause its mode to be set to explicit.

  • A property’s mode can be set directly. When set to explicit, all descendant nodes in the hierarchy are updated with the property’s value. When set to inherited, the property’s value is reset from the first explicit value in the ancestry, and then propagated to the descendants.

  • When a new node is added to the hierarchy, all inherited properties within the node are updated from the ancestry, and then propagated to the descendants.

If a property is inheritable, then the isInherited() method in its PropertyInfo structure will return true, and it’s property handle will be an instance of InheritableProperty:

interface InheritableProperty extends Property
{
   // sets the property’s mode
   public void setMode (PropertyMode mode);
   // returns the property’s mode
   public PropertyMode getMode();
}

Valid modes are PropertyMode.Explicit, PropertyMode.Inherited, and PropertyMode.Inactive. The latter is similar to Inherited, except that setting an Inactive property’s value will not cause its mode to be set to Explicit and its new value will not be propagated to hierarchy descendants.

The hierarchy structure which we have been describing is implemented by having host classes which correspond to hierarchy nodes implement the HierarchyNode interface.

interface HierarchyNode
{
   // returns an iterator over this node’s children
   Iterable<? extends HierarchyNode> getChildren();
   // returns true if this node has children
   boolean hasChildren();
   // returns the parent of this node, if any
   HierarchyNode getParent();
}

These methods should be implemented as wrappers to the underlying hierarchy implementation.