Custom behaviors are implemented by deriving concrete classes from the AcDbAssocActionBody class and overriding the necessary methods. The methods that are intended to be overridden all have the suffix of "Override". Methods without this suffix are not intended to be overridden. The only method that must always be overridden is the evaluateOverride() method. It is also a good habit to implement a createInstance() static method for every new custom action body class that serves as a "pseudo constructor". It should create an instance of the custom action body and its parent action, properly set them up, and add them to the database and to the associative network.
Every time the application code creates an action (owning a custom action body) and adds it to the database and to the associative network, it is advisable to explicitly evaluate the top level network by calling AcDbAssocManager::evaluateTopLevelNetwork(). Evaluating the top-level network will evaluate the newly added action and the action will update the contents of the objects it controls (the objects the action has write-dependencies on). This way the controlled objects will get in sync with the action. When some other actions are later added and these actions depend on the same objects, the contents of these objects will be what it is supposed to be. Without evaluating the newly added actions, the content of the controlled objects might not be what is expected, and adding new actions depending on these objects might produce unexpected results.
When client code changes values of properties of an action body, it is advisable to call AcDbAssocActionBody::setStatus(kChangedDirectlyAssocStatus), to make sure the action owning the action body is evaluated with the new property values. Most existing methods that change action body properties automatically set the action status, so this explicit call is usually not needed. However, this call is necessary for newly added custom action body methods. Otherwise, the action would not know that it needs to be evaluated.
Custom action bodies may keep their data in any form they see fit. However, the AcDbAssocParamBasedActionBody class represents the data of custom action body classes in a uniform and transparent manner. Custom action bodies derived from this class may keep their data in the form of action parameters derived from the AcDbAssocActionParam class. Action parameters take care of representing the data in various forms and provide the current values to the action body anytime the action body requests them. The custom action body does not need to take care of managing its data and handling operations like serialization or cloning because it is done automatically by the AcDbAssocParamBasedActionBody class.
The AcDbAssocParamBasedActionBody class also keeps numerical properties (called value action parameters) that may be constant or may be defined by expressions referencing variables. If the value is constant, it is kept directly in the value action parameter. If it is defined by an expression, an AcDbAssocVariable (anonymous or with explicit name) is automatically created to keep the expression.
The AcDbAssocParamBasedActionBody class takes care of managing these numerical values and expressions, including managing the automatically created AcDbAssocVariables. The custom action body code does not need to do it and can just use the value action parameters to keep its numerical properties.
The value action parameters are simply typed. If the value represents an angle, the angle is in radians. AcDbAssocVariables hold angles in degrees. When the value action parameter obtains the angle from its associated variable, it converts it from degrees to radians. If the value represents a distance, the custom action body may consider scaling it in some cases, such as when the entity the action controls is scaled.
The action parameter classes provide a general and high-level mechanism for representing custom action body data. For example, when an action body needs to keep a reference to an edge subentity of an entity (such as to a line entity, segment of a polyline, edge of a solid or surface, or generally to any subentity of an entity that provides AcGeCurve3d geometry), it creates an object from the AcDbAssocEdgeActionParam class that takes care of keeping the data. Anytime the action body code needs the current AcGeCurve3d geometry, it asks the AcDbAssocEdgeActionParam class and it provides the current geometry to the client code. The AcDbAssocEdgeActionParam class takes care of keeping the data in various ways, such as by referencing an AcDbEntity in the database, by referencing an edge subentity of an AcDbEntity, or by directly keeping a constant AcGeCurve3d. This internal representation of the data is completely transparent to the custom action body code. The custom code does not need to worry about how the data is kept or where it is obtained from.
The Associative Framework provides a set of predefined action parameters:
Applications can create compound action parameters by grouping other action parameters and make them owned by AcDbAssocCompoundActionParam objects, or derive their own action parameter classes from the base AcDbAssocActionParam class.