Representing Associations

Objects derived from AcDbAssocDependency class are used to represent the connectivity information. Each dependency represents information that an action depends on a property of an object. Dependencies are owned by actions and are attached to the dependent-on objects as persistent reactors.

Actions can filter out irrelevant changes in the property of the dependency, and notify only about the relevent changes. For example, if an action is interested in the position of the start point of a curve entity, and the curve entity changes so that the end point of the curve changes but the start point stays the same, the dependency can ignore the notification from the curve entity.

The dependency uses the AcDbAssocDependency::isRelevantChange() predicate to decide if the object change is to be considered relevant or not. By default the dependency delegates this predicate to the AcDbAssocAction::isRelevantDependencyChange() so that the action owning the dependency can decide which object changes the action wants to consider relevant and which it wants to ignFor exampleore.

The dependency can be read only, write only or read write, based on whether the action owning the dependency uses the property of the object but does not modify it, changes the property of the object but does not use it, or both.

An example of a read only dependency is when an arithmetic expression in an AcDbAssocVariable references other variables and therefore depends on values of other variables. The variable uses the values of the referenced variables but does not modify them.

An example of a write only dependency is when a solid extrusion action that sets the contents of an AcDb3dSolid entity from the extrusion profile and extrusion vector. This action does not use the previous contents of the AcDb3dSolid entity, it only sets its new contents.

An example of a read write dependency is when the AcDbAssoc2dConstraintGroup action that depends on the constrained curve entities. It uses both the initial coordinates of these curve entities and then updates them to satisfy the constraints.

An order is established between all dependencies on the same object. This order is very significant and specifies the order of the actions that depend on the same object. For example, there are actions A1 and A2; A1 has a write only or a read write dependency D1 on an object, and A2 has a dependency D2 on the same object; also, in the established order D1 comes before D2. In such a case, A1 must be evaluated first, modifying the properties of the object; A2 be evaluated only after that action can.

The AcDbAssocDependency::setOrder() method should be used to specify the order of dependencies on an object. The lower the order value being, the higher the dependency is in the order. When a dependency is attached to an object, by calling the attachToObject() method, it is ordered according to the set order value. If there is more than one dependency with the same order value, the Dependenies are additionally ordered according to the sequence in which they are attached to the object.

An AcDbAssocDependency may also depend on an object inside another object along a nested path. For example, it may depend on a curve entity inside an AcDbBlockTableRecord that is referenced by an AcDbBlockReference. Such a dependency is put into the order of dependencies of the top level object, in this case the AcDbBlockReference, but it is also attached as a persistent reactor to all the entities along the path, in this case to the curve entity. An object of type AcDbCompoundObjectId is used to identify entities accessed via a path.

Applications can also derive their own specialized dependency classes by deriving from the AcDbAssocDependencyBody base class; AcDbAssocDependency becomes a hard owner. Thus, situations when the custom application cannot be loaded are better handled. In this case, the AcDbAssocDependency objects are still present and functional and the connectivity information about which actions depend on which objects is still available, and although the AcDbAssocDependencyBody objects do become proxies, only the custom functionality is unavailable. This is analogous to the relation between AcDbAssocAction and AcDbAssocActionBody objects.

Specialized Dependency Classes

The base AcDbAssocDependency class can be used directly. However, there are derived dependency classes that allow establishing dependencies on particular properties of objects and that filter object changes irrelevant to the dependency.

a) AcDbAssocValueDependency establishs dependencies on objects that provide simple named values such as doubles, integers, points, or strings. The objects reveal their named properties by exposing the AcDbAssocValueProviderPE protocol extension. The obvious client of AcDbAssocValueDependency is the AcDbAssocVariable action that may contain expressions referencing other variables, or generally, any objects that expose the AcDbAssocValueProviderPE protocol extension. The AcDbAssocVariable then owns AcDbAssocValueDependencies on these objects.

b) AcDbAssocGeomDependency establishs dependencies on topological subentities (faces, edges, vertices) of geometric entities. The entities reveal their subentities by exposing the AcDbAssocPersSubentIdPE protocol extension. The obvious client of AcDbAssocGeomDependency is the AcDbAssoc2dConstraintGroup action that constraints subentities of AutoCAD entities such as lines, arcs, circles and polylines, or generally any objects that expose AcDbAssocPersSubentIdPE protocol extension.