AcDbAssocAction.h 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272
  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2015 Autodesk, Inc. All rights reserved.
  4. //
  5. // Use of this software is subject to the terms of the Autodesk license
  6. // agreement provided at the time of installation or download, or which
  7. // otherwise accompanies this software in either electronic or hard copy form.
  8. //
  9. //////////////////////////////////////////////////////////////////////////////
  10. //
  11. // CREATED BY: Jiri Kripac March 2007
  12. //
  13. // DESCRIPTION:
  14. //
  15. // AcDbAssocAction base class.
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #pragma once
  19. #include "AcDbAssocGlobal.h"
  20. #include "dbEval.h"
  21. #include "AcValue.h"
  22. #pragma pack (push, 8)
  23. /// <summary> <para>
  24. /// Any object that wants to exhibit associative behavior, i.e. be automatically
  25. /// evaluated by the associative mechanism when objects it depends on change,
  26. /// needs to be derived from an AcDbAssocActionBody class (see comments at the
  27. /// AcDbAssocActionBody class) and owned by a parent AcDbAssocAction object. The
  28. /// action body is fully owned by its parent action, such as when the parent
  29. /// action is erased, it also erases the owned action body.
  30. /// </para> <para>
  31. /// The AcDbAssocAction class itself does not have virtual methods that could be
  32. /// overridden, therefore it is not possible for external developers to derive
  33. /// directly from the AcDbAssocAction class and override its methods. Internal
  34. /// AutoCAD developers can derive from the AcDbImpAssocAction class and override
  35. /// its virtual methods, but it should only be done when there is no possibility
  36. /// that objects of the derived action classes could become proxies.
  37. /// </para> <para>
  38. /// Each action is owned by an AcDbAssocNetwork that itself is an action,
  39. /// therefore hirearchical associative structures can be represented.
  40. /// </para> <para>
  41. /// The main protocol of the AcDbAssocAction class is the evaluate() method that
  42. /// calls the evaluateOverride() method of the owned AcDbAssocActionBody object.
  43. /// </para> <para>
  44. /// Actions own AcDbAssocDependency objects that allow the actions to depend on
  45. /// arbitrary AcDbObjects. This is how the connectivity in the network is
  46. /// represented. When objects the dependencies depend on change, the dependencies
  47. /// are notified, actions owning the dependencies are notified and also the
  48. /// hierarchy of the networks owning the actions is notified. This notification
  49. /// just changes AcDbAssocStatus of the dependencies and of the actions/networks
  50. /// to "dirty", it does not trigger any action evaluation.
  51. /// </para> <para>
  52. /// The actual action evaluation happens when the client code calls the evalaute()
  53. /// method on the top-level network. This automatically evaluates all the actions
  54. /// the network owns that need to be evaluated because they depend, either
  55. /// directly or transitively, on objects that changed. If an action modifies an
  56. /// object (has a write-dependency on it) and there is another action that uses
  57. /// the modified object (has read-dependency on it), then, if the first action
  58. /// is evaluated, the second action also needs to be transitively evaluated.
  59. /// </para> <para>
  60. /// The flow of information is as follows:
  61. /// </para> <para>
  62. ///
  63. /// Object1 --ReadDep--> Action1 --WriteDep1--> Object2 --ReadDep--> Action2 ...
  64. ///
  65. /// <para> </para>
  66. /// Notice that an action may depend on multiple objects and may modify multiple
  67. /// other objects. The network forms a directed acyclic graph. The evalution
  68. /// algoritm makes sure that all actions that need to be evaluated are evaluated
  69. /// and that the evaluation happens in the correct order so that every action
  70. /// is evaluated only after all other actions that modify objects this action
  71. /// depends on have already been evaluated (the situation is actually litle
  72. /// bit more complex, there are other aspects controlling the evaluation order).
  73. /// </para> <para>
  74. /// The AcDbAssocManager::evaluateTopLevelNetwork() static method should be used
  75. /// to evaluate the top-level network of the database. It will collect and
  76. /// evaluate all the actions that need to be evaluated. Explicit evaluation of
  77. /// the individual sub-networks is not recommended.
  78. ///
  79. /// </para> <para>
  80. /// Actions may own action parameters that allow custom action body classes keep
  81. /// and access their data in a uniform an high-level manner. Instead of each concrete
  82. /// custom action body devising its own way how to keep its data, they the data
  83. /// is uniformly stored in the form of AcDbAssocActionParam(eters), and for simple
  84. /// numerical values, in the form of value action parameters. The action parameters
  85. /// take care of keeping the data in various ways and provide the current values
  86. /// to the action body anytime the action body requests them. The custom action
  87. /// body does not even need to implement code to serialize and clone its data,
  88. /// because the data is owned and managed by the parent AcDbAssocAction.
  89. /// See the AcDbAssocActionParam class and derived classes for more details.
  90. /// </para><para>
  91. /// Another advantage of keeping the action body data in action parameters is that
  92. /// it is possible to write code that traverses and inspects the action body data
  93. /// in a generic way, without knowing anything about the action body itself.
  94. /// </para><para>
  95. /// AcDbAssocAction owns an array of AcDbAssocActionParams and an array of value
  96. /// action parameters. The AcDbAssocActionParams and the value action parameters
  97. /// are completely independent of each other.
  98. /// </para><para>
  99. /// The value action parameter represents a named array of numerical values, such
  100. /// as a doubles, ints, strings or vectors. Usually the array will contain only
  101. /// a single element, but generally it con contain any number of elements.
  102. /// The value parameter name is a case-sensitive string.
  103. /// </para><para>
  104. /// Each individual value may either be a constant, or defined by an expression.
  105. /// When it is defined by an expression, the value parameter keeps AcDbObjectId
  106. /// of a read-only AcDbAssocValueDependency (the dependency is owned by the
  107. /// parent AcDbAssocAction) on an anonymous AcDbAssocVariable that keeps the
  108. /// expression and provides the input value for the value parameter. This anonymous
  109. /// variable is exclusively managed by the value parameter who is responsible for
  110. /// its creation, deletion, copy, etc.
  111. /// </para><para>
  112. /// If the user enters the expression in the form of "name=expression", the
  113. /// automatically created AcDbAssocVariable is assigned the given "name" instead
  114. /// of being anonymous, i.e. with empty name. If the variable has explicit name,
  115. /// it apperars in the parameters manager and can be referenced by other expressions
  116. /// as any other variable. However, it is still completely managed by the value
  117. /// parameter who takes care of the variable deletion, copy, etc.
  118. /// </para></summary>
  119. ///
  120. class ACDB_PORT AcDbAssocAction : public AcDbObject
  121. {
  122. public:
  123. ACRX_DECLARE_MEMBERS(AcDbAssocAction);
  124. /// <summary> Default constructor. </summary>
  125. /// <param name="createImpObject"> See AcDbAssocCreateImpObject. </param>
  126. ///
  127. explicit AcDbAssocAction(AcDbAssocCreateImpObject createImpObject = kAcDbAssocCreateImpObject);
  128. /// <summary>
  129. /// Returns AcDbObjectId of an object of a class derived from
  130. /// AcDbAssocActionBody, or a null id if no action body object has been set.
  131. /// The AcDbAssocActionBody object is owned by this AcDbAssocAction object
  132. /// and implements the body of the custom action. See the comments at
  133. /// the AcDbAssocActionBody class for more information.
  134. /// </summary>
  135. /// <returns>
  136. /// AcDbObjectId of an object of a class derived from AcDbAssocActionBody
  137. /// or null id.
  138. /// </returns>
  139. ///
  140. AcDbObjectId actionBody() const;
  141. /// <summary>
  142. /// Takes an AcDbObjectId of an AcDbAssocAction and returns AcDbObjectId of
  143. /// an object of a class derived from AcDbAssocActionBody, or a null id if
  144. /// the action does not have any action body. This is just a shortcut allowing
  145. /// to deal with AcDbObjectId of an action without having to open it first.
  146. /// </summary>
  147. /// <param name="actionId">
  148. /// AcDbObjectId of an object of a class derived from AcDbAssocAction.
  149. /// </param>
  150. /// <returns>
  151. /// AcDbObjectId of an object of a class derived from AcDbAssocActionBody
  152. /// or null id.
  153. /// </returns>
  154. ///
  155. static AcDbObjectId actionBody(const AcDbObjectId& actionId);
  156. /// <summary>
  157. /// Sets AcDbObjectId of an object of a class derived from AcDbAssocActionBody.
  158. /// The AcDbAssocActionBody object becomes owned by this AcDbAssocAction
  159. /// object and implements the body of the custom action. See the comments
  160. /// at the AcDbAssocActionBody class for more information.
  161. /// </summary>
  162. /// <param name="actionBodyId">
  163. /// AcDbObjectId of an object of a class derived from AcDbAssocActionBody
  164. /// or null id.
  165. /// </param>
  166. /// <returns> Acad::ErrorStatus. </returns>
  167. ///
  168. Acad::ErrorStatus setActionBody(const AcDbObjectId& actionBodyId);
  169. /// <summary>
  170. /// If the action body is a proxy, the action is not evaluatable.
  171. /// </summary>
  172. /// <returns> True if the action is not evaluatable, false otherwise. </returns>
  173. ///
  174. bool isActionBodyAProxy() const;
  175. /// <summary> Gets the current AcDbAssocStatus of this action. </summary>
  176. /// <returns> The AcDbAssocStatus of this action. </returns>
  177. ///
  178. AcDbAssocStatus status() const;
  179. /// <summary> <para>
  180. /// Sets the AcDbAssocStatus of the action. If the status is one of the codes
  181. /// that indicate that the action will need to be evaluated (the
  182. /// isEvaluationRequest() predicate returns true for such a status), but the
  183. /// current status of the action is not that it would need to be evaluated,
  184. /// it propagates this status up to the AcDbAssocNetwork owning the action,
  185. /// and higher in the network hierarchy to the network owning this network,
  186. /// etc, so that all owning networks know that they contain an action that
  187. /// needs to be evaluated.
  188. /// </para> <para>
  189. /// If the new status isEvaluationRequest() and evaluationRequestSeverityLevel()
  190. /// of the new status is lower than the current evaluation request status of
  191. /// the action, the current higher status of the action is kept and not
  192. /// overwritten by the new lower status. Also, if the current status of the
  193. /// action isTobeSkipped(), it is not overwritten by any new status that
  194. /// isEvaluationRequest(). To change the action status in such a case, the
  195. /// action status needs to be first changed to kIsUpToDateAssocStatus, and
  196. /// after that it can be changed to an isEvaluationRequest() status.
  197. /// </para> </summary>
  198. /// <param name="newStatus"> The new AcDbAssocStatus of the action. </param>
  199. /// <param name="notifyOwningNetwork">
  200. /// If true, and the passed-in status indicates that the action needs to be
  201. /// evaluated, the status of the AcDbAssocNetwork owning this dependency is
  202. /// set to the same status (unless the network evaluation status is already
  203. /// more severe than the new one).
  204. /// </param>
  205. /// <param name="setInOwnedActions">
  206. /// If true, and this action owns some other actions (such as AcDbAssocNetwork
  207. /// owns actions), the status is also set in all owned actions (both directly
  208. /// owned and recursively owned).
  209. /// </param>
  210. /// <returns> Acad::ErrorStatus. </returns>
  211. ///
  212. Acad::ErrorStatus setStatus(AcDbAssocStatus newStatus,
  213. bool notifyOwningNetwork = true,
  214. bool setInOwnedActions = false);
  215. /// <summary> <para>
  216. /// Every action except for the topmost AcDbAssocNetwork is "logically" owned
  217. /// by a single AcDbAssocNetwork.
  218. /// </para> <para>
  219. /// This network may also be the "physical" database owner of the action
  220. /// (the network has hard-ownership id of the action), but the "physical"
  221. /// owner may also be some other object. For example, for networks attached
  222. /// to AcDbBlockTableRecords, the "logical" owner is the top-level network of
  223. /// the whole database but the "physical" database owner is the subdictionary
  224. /// of the extension dictionary of the AcBdBlockTableRecord.
  225. /// </para> </summary>
  226. /// <returns> The logically owning AScDbAssocNetwork or AcDbObjectId::kNull
  227. /// if it is the topmost AcDbAssocNetwork.
  228. /// </returns>
  229. ///
  230. AcDbObjectId owningNetwork() const;
  231. /// <summary> <para>
  232. /// Every action except for the topmost AcDbAssocNetwork is logically owned
  233. /// by a single AcDbAssocNetwork.
  234. /// </para> <para>
  235. /// This network may also be the "physical" database owner of the action
  236. /// (the network has hard-ownership id of the action), but the "physical"
  237. /// owner may also be some other object. For example, for networks attached
  238. /// to AcDbBlockTableRecords, the "logical" owner is the top-level network of
  239. /// the whole database but the "physical" database owner is the subdictionary
  240. /// of the extension dictionary of the AcBdBlockTableRecord.
  241. /// </para> <para>
  242. /// This method should not be called directly, AcDbAssocNetwork::add/removeAction()
  243. /// should be used, which in turn calls setOwningNetwork(), but it does more.
  244. /// </para> </summary>
  245. /// <param name="networkId"> The AcDbAssocNetwork logically owning this action. </param>
  246. /// <param name="alsoSetAsDatabaseOwner"> Make the network the database owner of this action. </param>
  247. /// <returns> Acad::ErrorStatus. </returns>
  248. ///
  249. Acad::ErrorStatus setOwningNetwork(const AcDbObjectId& networkId, bool alsoSetAsDatabaseOwner);
  250. /// <summary> <para>
  251. /// Gets AcDbAssocDependencies of this action. The default implementation
  252. /// obtains all dependencies owned by the base action class and selects the
  253. /// ones based on the required read/write type.
  254. /// </para> <para>
  255. /// If the action owns an AcDbAssocActionBody object that overrides the
  256. /// getDependenciesOverride() method, this method is called and it
  257. /// supersedes the default implementation. It allows the custom action body
  258. /// classes to control which dependencies to return and which not to mention.
  259. /// </para> </summary>
  260. /// <param name="readDependenciesWanted"> Read-type dependencies wanted. </param>
  261. /// <param name="writeDependenciesWanted"> Write-type dependencies wanted. </param>
  262. /// <param name="dependencyIds"> Returned AcDbObjectIds of AcDbAssocDependencies. </param>
  263. /// <returns> Acad::ErrorStatus. </returns>
  264. ///
  265. Acad::ErrorStatus getDependencies(bool readDependenciesWanted,
  266. bool writeDependenciesWanted,
  267. AcDbObjectIdArray& dependencyIds) const;
  268. /// <summary>
  269. /// Adds the given AcDbAssocDependency to this action. The dependency may
  270. /// either become owned by this action (if setThisActionAsOwningAction is true)
  271. /// which is the most common case, or just referenced by this action.
  272. /// </summary>
  273. /// <param name="dependencyId">
  274. /// AcDbObjectId of the AcDbAssocDependency being added to this action.
  275. /// </param>
  276. /// <param name="setThisActionAsOwningAction">
  277. /// If true, sets this action to be the database owner of the dependency.
  278. /// In this case the dependency must not be already owned by any other action.
  279. /// </param>
  280. /// <returns> Acad::ErrorStatus. </returns>
  281. ///
  282. Acad::ErrorStatus addDependency(const AcDbObjectId& dependencyId,
  283. bool setThisActionAsOwningAction = true);
  284. /// <summary>
  285. /// Utility method that creates a new AcDbAssocDependency of the given pDependencyClass,
  286. /// possibly owning an AcDbAssocDependencyBody of the given pDependencyBodyClass,
  287. /// adds it to the database and to this action.
  288. /// </summary>
  289. /// <param name="pDependencyClass"> Type of the dependency to create, NULL means the base AcDbAssocDependency. </param>
  290. /// <param name="pDependencyBodyClass"> Type of the dependency body to create, NULL means no dependency body. </param>
  291. /// <param name="isReadDep"> The created dependency is a read dependency. </param>
  292. /// <param name="isReadDep"> The created dependency is a write dependency. </param>
  293. /// <param name="order"> The dependency order. </param>
  294. /// <param name="dependencyId"> AcDbObjectId of the newly created dependency. </param>
  295. /// <returns> Acad::ErrorStatus. </returns>
  296. ///
  297. Acad::ErrorStatus addDependency(AcRxClass* pDependencyClass,
  298. AcRxClass* pDependencyBodyClass,
  299. bool isReadDep,
  300. bool isWriteDep,
  301. int order,
  302. AcDbObjectId& dependencyId);
  303. /// <summary>
  304. /// Removes the given AcDbAssocDependency from this action.
  305. /// </summary>
  306. /// <param name="dependencyId">
  307. /// AcDbObjectId of the AcDbAssocDependency being removed from this action.
  308. /// </param>
  309. /// <param name="alsoEraseIt"> Erases the dependency after removing it. </param>
  310. /// <returns> Acad::ErrorStatus. </returns>
  311. ///
  312. Acad::ErrorStatus removeDependency(const AcDbObjectId& dependencyId,
  313. bool alsoEraseIt);
  314. /// <summary> <para>
  315. /// Removes all AcDbAssocDependencies kept in the vector of dependencies
  316. /// of this action and optionally also erases them.
  317. /// </para> <para>
  318. /// If the action owns an AcDbAssocActionBody object that overrides
  319. /// the removeAllDependenciesOverride() method, this method is called
  320. /// to notify about the dependencies being removed. This happens after
  321. /// all the dependencies have already been removed.
  322. /// </para> </summary>
  323. /// <param name="alsoEraseThem"> Erase the AcDbAssocDependencies after removing them. </param>
  324. /// <returns> Acad::ErrorStatus. </returns>
  325. ///
  326. Acad::ErrorStatus removeAllDependencies(bool alsoEraseThem);
  327. /// <summary> <para>
  328. /// Get AcDbObjects that this action depends on or modifies. The default
  329. /// implementation collects all object on which the action has
  330. /// AcDbAssocDependencies.
  331. /// </para> <para>
  332. /// If the action owns an AcDbAssocActionBody object that overrides the
  333. /// getDependentObjectsOverride() method, this method is called and it
  334. /// supersedes the default implementation. It allows the custom action body
  335. /// classes to control which objects to return and which not to mention,
  336. /// but usually there is no need to override this method, the default
  337. /// implementation that traverses all the dependencies of the action should
  338. /// suffice.
  339. /// </para> </summary>
  340. /// <param name="readDependenciesWanted"> Dependent-on objects wanted. </param>
  341. /// <param name="writeDependenciesWanted"> Modified objects wanted. </param>
  342. /// <param name="objectIds"> Returned AcDbObjectIds of the AcDbObjects. </param>
  343. /// <returns> Acad::ErrorStatus. </returns>
  344. ///
  345. Acad::ErrorStatus getDependentObjects(bool readDependenciesWanted,
  346. bool writeDependenciesWanted,
  347. AcDbObjectIdArray& objectIds) const;
  348. /// <summary> <para>
  349. /// Checks whether the given AcDbAssocDependency is owned by this action,
  350. /// either directly, or if this action is a network, is owned by an action
  351. /// owned by the network.
  352. /// </para> <para>
  353. /// The default implementation first makes a quick check whether the
  354. /// ownerId() of the dependency is the objectId() of this action. If not
  355. /// and it is a network, it calls getDependencies() and checks if the
  356. /// dependency is one of the returned ones. The second check is generic
  357. /// and applicable to any action, but it has not been used as the default
  358. /// implementation for any action because it is more expensive.
  359. /// </para> <para>
  360. /// If the action owns an AcDbAssocActionBody object that overrides
  361. /// the isOwnedDependencyOverride() predicate, this predicate is called
  362. /// and it supersedes the default implementation.
  363. /// </para> </summary>
  364. /// <param name="pDependency">
  365. /// The dependency that is checked whether it is owned by this action.
  366. /// Needs to be open at least for read.
  367. /// </param>
  368. /// <returns> True iff the given dependency is owned by this action. </returns>
  369. ///
  370. bool isOwnedDependency(const AcDbAssocDependency* pDependency) const;
  371. /// <summary> <para>
  372. /// Checks whether the given AcDbAssocDependency, owned by this action,
  373. /// is external to this action, i.e. it depends on an AcDbObject that is
  374. /// not this action and is not owned by this action (when the action is
  375. /// a network). Also, when the dependency does not depend on any object,
  376. /// it is considered external.
  377. /// </para> <para>
  378. /// If the action owns an AcDbAssocActionBody object that overrides
  379. /// the isExternalDependencyOverride() predicate, this predicate is called
  380. /// and it supersedes the default implementation.
  381. /// </para> </summary>
  382. /// <param name="pDependency">
  383. /// The dependency that is checked whether it is external. Needs to be open
  384. /// at least for read.
  385. /// </param>
  386. /// <returns> True iff the given dependency is external to this action. </returns>
  387. ///
  388. bool isExternalDependency(const AcDbAssocDependency* pDependency) const;
  389. /// <summary> <para>
  390. /// Delegated from the owned dependency's AcDbAssocDependency::isRelevantChange()
  391. /// predicate. It allows the owning action, instead of the dependency itself,
  392. /// to decide whether the object change is relevant to that particular
  393. /// dependency. The default implementation just returns true.
  394. /// </para> <para>
  395. /// This way the data (usually the cached value) that is needed to decide
  396. /// whether an object change is relevant to a particular dependency type
  397. /// or not, can be stored either in the dependency itself or in the action
  398. /// that owns it, based on what is more convenient for each particular
  399. /// action or dependency type.
  400. /// </para> <para>
  401. /// If the action owns an AcDbAssocActionBody object that overrides
  402. /// the isRelevantDependencyChangeOverride() predicate, this predicate is
  403. /// called instead of just returning true.
  404. /// </para> </summary>
  405. /// <param name="pDependency">
  406. /// The dependency that is checked whether the change in the object it
  407. /// depends on is relevant or not. It needs to be open at least for read.
  408. /// </param>
  409. /// <returns>
  410. /// Returns iff the dependency change is relevant. The default
  411. /// implementation returns true.
  412. /// </returns>
  413. ///
  414. bool isRelevantDependencyChange(const AcDbAssocDependency* pDependency) const;
  415. /// <summary> <para>
  416. /// Delegated from the owned dependency's AcDbAssocDependency::hasCachedValue()
  417. /// predicate. It allows the owning action, instead of the dependency itself,
  418. /// to decide whether the dependency has a cached value. The default
  419. /// implementation just returns false.
  420. /// </para> <para>
  421. /// This way the the cached value can be stored either in the dependency
  422. /// itself or in the action that owns it, based on what is more convenient
  423. /// for each particular action or dependency type.
  424. /// </para> <para>
  425. /// If the action owns an AcDbAssocActionBody object that overrides
  426. /// the hasDependencyCachedValueOverride() predicate, this predicate is
  427. /// called instead of just returning false.
  428. /// </para> </summary>
  429. /// <param name="pDependency">
  430. /// The dependency that is checked whether it has cached value. It needs to
  431. /// be open at least for read.
  432. /// </param>
  433. /// <returns>
  434. /// Returns true if the dependency has a cached value, false otherwise. The default
  435. /// implementation returns false.
  436. /// </returns>
  437. ///
  438. bool hasDependencyCachedValue(const AcDbAssocDependency* pDependency) const;
  439. /// <summary> <para>
  440. /// Delegated from the owned dependency's AcDbAssocDependency::isDependentOnTheSameThingAs()
  441. /// predicate. It allows the owning action, instead of the dependency itself,
  442. /// to decide whether the two depedencies depend on the same thing. The default
  443. /// implementation just returns true.
  444. /// </para> <para>
  445. /// If the action owns an AcDbAssocActionBody object that overrides
  446. /// the isDependentOnTheSameThingOveride() predicate, this predicate is
  447. /// called instead of just returning true.
  448. /// </para> </summary>
  449. /// <param name="pDependency1">
  450. /// The dependency owned by this action. It needs to be open at least for read.
  451. /// </param>
  452. /// <param name="pDependency2">
  453. /// Another dependency. It needs to be open at least for read.
  454. /// </param>
  455. /// <returns>
  456. /// Returns true if the two dependencies depend on the same "thing", false otherwise.
  457. /// The default implementation returns false.
  458. /// </returns>
  459. ///
  460. bool areDependenciesOnTheSameThing(const AcDbAssocDependency* pDependency1,
  461. const AcDbAssocDependency* pDependency2) const;
  462. /// <summary> <para>
  463. /// Delegated from he owned dependency's AcDbAssocDependency::isEqualTo()
  464. /// predicate. It allows the owning action, instead of the dependency itself,
  465. /// to decide whether the two dependencies are equal. The default
  466. /// implementation just returns false.
  467. /// </para> <para>
  468. /// If the action owns an AcDbAssocActionBody object that overrides
  469. /// the areDependenciesEqualOveride() predicate, this predicate is called
  470. /// instead of just returning false.
  471. /// </para> </summary>
  472. /// <param name="pDependency1">
  473. /// The dependency owned by this action. It needs to be open at least for read.
  474. /// </param>
  475. /// <param name="pDependency2">
  476. /// Another dependency. It needs to be open at least for read.
  477. /// </param>
  478. /// <returns>
  479. /// Returns true if the two dependencies are "equal", false otherwise. The
  480. /// default implementation returns false.
  481. /// </returns>
  482. ///
  483. bool areDependenciesEqual(const AcDbAssocDependency* pDependency1,
  484. const AcDbAssocDependency* pDependency2) const;
  485. /// <summary>
  486. /// General mechanism by which an action can be notified about events.
  487. /// </summary>
  488. ///
  489. Acad::ErrorStatus notification(AcDbAssocNotificationData* pNotifData);
  490. /// <summary> <para>
  491. /// Called from the owned dependency's AcDbAssocDependency::copied()
  492. /// persistent reactor callback. It notifies the owning action about the fact
  493. /// that an object the action has a dependency on has been cloned. The cloning
  494. /// may be just shallow clone, not necessarily deep or wblock clone.
  495. /// </para> <para>
  496. /// If the action owns an AcDbAssocActionBody object that overrides
  497. /// the dependentObjectClonedOverride() callback, this callback is called.
  498. /// </para> </summary>
  499. /// <param name="pDependency">
  500. /// The AcDbAssocDependency on the AcDbObject that has been cloned.
  501. /// </param>
  502. /// <param name="pDbObj"> The original object. </param>
  503. /// <param name="pNewObj"> The newly created clone. </param>
  504. ///
  505. void dependentObjectCloned(const AcDbAssocDependency* pDependency,
  506. const AcDbObject* pDbObj,
  507. const AcDbObject* pNewObj);
  508. /// <summary> <para>
  509. /// Called just before the end of the main deep-cloning loop (before
  510. /// AcRxEventReactor::beginDeepCloneXlation() reactor notification), when
  511. /// the objects have already been cloned but their ids haven't been translated
  512. /// yet.
  513. /// </para> <para>
  514. /// It asks the actions who have AcDbAssocDependencies on some objects
  515. /// that have been cloned, whether the actions want to add some more objects
  516. /// to deep clone. The actions can then report more objects to be deep cloned
  517. /// and the main cloning loop then continues with deep cloning these additional
  518. /// objects. If it caused more objects to be cloned, the actions that have
  519. /// dependencies on these newly cloned objects are asked and may add yet more
  520. /// objects to clone. This process continues until no more objects are cloned.
  521. /// </para> <para>
  522. /// If the action owns an AcDbAssocActionBody object that overrides
  523. /// the addMoreObjectsToDeepCloneOverride() callback, this callback is called.
  524. /// </para> </summary>
  525. /// <param name="idMap"> The AcDbIdMapping of the current deep cloning session. </param>
  526. /// <param name="additionalObjectsToClone">
  527. /// Additional objects that the action also wants to deep clone. It is legal
  528. /// to add objects that have already been cloned; they will be ignored
  529. /// and not cloned again.
  530. /// </param>
  531. /// <returns> Acad::ErrorStatus. </returns>
  532. ///
  533. Acad::ErrorStatus addMoreObjectsToDeepClone(AcDbIdMapping& idMap,
  534. AcDbObjectIdArray& additionalObjectsToClone) const;
  535. /// <summary> <para>
  536. /// Called from AcRxEventReactor::endDeepClone() reactor notification method
  537. /// (ids of the clones have already been translated) to inform the source
  538. /// actions that they have been cloned, so that they can update the clones
  539. /// or do some other work that it needed. Notice that the source action can
  540. /// obtain its clone by consulting the provided AcDbIdMapping.
  541. /// </para> <para>
  542. /// If the action owns an AcDbAssocActionBody object that overrides
  543. /// the postProcessAfterDeepCloneOverride() callback, this callback is called.
  544. /// </para> </summary>
  545. /// <param name="idMap"> The AcDbIdMapping of the current deep cloning session. </param>
  546. /// <returns> Acad::ErrorStatus. </returns>
  547. ///
  548. Acad::ErrorStatus postProcessAfterDeepClone(AcDbIdMapping& idMap);
  549. /// <summary> <para>
  550. /// Called from AcRxEventReactor::cancelDeepClone() reactor notification
  551. /// method. Notice that the source action can obtain its clone by consulting
  552. /// the provided AcDbIdMapping.
  553. /// </para> <para>
  554. /// If the action owns an AcDbAssocActionBody object that overrides
  555. /// the postProcessAfterDeepCloneCancelOverride() callback, this callback is
  556. /// called, but it may usually be safer not to override this callback and
  557. /// just do nothing.
  558. /// </para> </summary>
  559. /// <param name="idMap"> The AcDbIdMapping of the current deep cloning session. </param>
  560. /// <returns> Acad::ErrorStatus. </returns>
  561. ///
  562. Acad::ErrorStatus postProcessAfterDeepCloneCancel(AcDbIdMapping& idMap);
  563. /// <summary> <para>
  564. /// Predicate that returns true iff the system is currently evaluating an
  565. /// action or a network of actions.
  566. /// </para> <para>
  567. /// Notice that when action evaluation is in progress, dependency notifications
  568. /// are disabled. When an object that has dependencies attached to itself is
  569. /// changed, the dependencies ignore this notification and consequently also
  570. /// do not notify the actions owning the dependencies. This is necessary because
  571. /// otherwise if one action evaluation modified some objects, the dependencies
  572. /// on these objects would be notified and the status of other actions owning
  573. /// these dependencies would be changed, requesting the actions to be evaluated
  574. /// again. This would lead to infinite loops.
  575. /// </para> </summary>
  576. /// <returns> True iff action evaluation is in progress. </returns>
  577. ///
  578. bool isActionEvaluationInProgress() const;
  579. /// <summary>
  580. /// Returns the current AcDbAssocEvaluationCallback set by the
  581. /// AcDbAssocAction::evaluate() call, or NULL if no action evaluation
  582. /// is in progress. Notice that when action evaluation is in progress, there
  583. /// always is a non-NULL AcDbAssocEvaluationCallback.
  584. /// </summary>
  585. /// <returns> The current AcDbAssocEvaluationCallback or NULL. </returns>
  586. ///
  587. AcDbAssocEvaluationCallback* currentEvaluationCallback() const;
  588. /// <summary>
  589. /// This method needs to be called from the client code evaluateOverride()
  590. /// method, usually after the client code inspected the dependencies, found
  591. /// which changed, which were on erased objects, etc. It gets all dependencies
  592. /// of the action and evaluates the ones that need to be evaluated, i.e.
  593. /// dependencies for which isEvaluationRequest(pDep->status()) == true.
  594. /// </summary>
  595. /// <returns> Acad::ErrorStatus. </returns>
  596. ///
  597. Acad::ErrorStatus evaluateDependencies();
  598. /// <summary> <para>
  599. /// Delegated from the owned dependency's AcDbAssocDependency::evaluateOverride()
  600. /// method. It allows the owning action, instead of the dependency itself,
  601. /// to do the work. The default implementation just sets the dependency status
  602. /// to kIsUpToDateAssocStatus.
  603. /// </para> <para>
  604. /// If the action owns an AcDbAssocActionBody object that overrides
  605. /// the evaluateDependencyOverride() method, this method is called to do the
  606. /// work.
  607. /// </para> </summary>
  608. /// <param name="pDependency">
  609. /// The dependency that is to be evaluated. It needs to be open at least
  610. /// for read.
  611. /// </param>
  612. ///
  613. void evaluateDependency(AcDbAssocDependency* pDependency);
  614. /// <summary> <para>
  615. /// This callback is called from AcDbAssocDependency::setStatus(..., true)
  616. /// and notifies the action owning the dependency that the status of the
  617. /// dependency has just been changed. The dependency is still open for
  618. /// write and already has the new status.
  619. /// </para> <para>
  620. /// If the action owns an AcDbAssocActionBody object that overrides
  621. /// the ownedDependencyStatusChangedOverride() method, it is called after
  622. /// the default implementation in the AcDbAssocAction class has been performed.
  623. /// However, there should usually be no need to override this method.
  624. /// </para> </summary>
  625. /// <param name="pOwnedDependency"> The dependency whose status has just been changed. </param>
  626. /// <param name="previousStatus"> Previous status of the dependency. </param>
  627. /// <returns> Acad::ErrorStatus. </returns>
  628. ///
  629. Acad::ErrorStatus ownedDependencyStatusChanged(AcDbAssocDependency* pOwnedDependency,
  630. AcDbAssocStatus previousStatus);
  631. /// <summary>
  632. /// Notifes the action that the owner of the action was transformed, such as
  633. /// that all entities in the AcDbBlockTableRecord owning the network that owns
  634. /// the action were transformed.
  635. /// </summary>
  636. /// <param name="transform"> The provided transformation matrix. </param>
  637. /// <returns> Acad::ErrorStatus. </returns>
  638. ///
  639. Acad::ErrorStatus transformActionBy(const AcGeMatrix3d& transform);
  640. /// <summary> <para>
  641. /// Compares this action with the given action and returns true if and only
  642. /// if they are equal (whatever it means). Both actions need to be open at
  643. /// least for read.
  644. /// </para> <para>
  645. /// If the action owns an AcDbAssocActionBody object that overrides
  646. /// the isEqualToOverride() predicate, this predicate is called.
  647. /// </para> </summary>
  648. /// <param name="pOtherAction"> The other action needs to be open for read. </param>
  649. /// <returns> True iff the two actions are equal. </returns>
  650. ///
  651. bool isEqualTo(const AcDbAssocAction* pOtherAction) const;
  652. /// <summary> <para>
  653. /// This method provides default implementation suitable for most
  654. /// circumstances, but actions may override it to define their special
  655. /// behavior.
  656. /// </para> <para>
  657. /// It is called when an AcDbAssocNetwork is evaluated during which it
  658. /// sequentially evaluates all the actions in the network that need to be
  659. /// evaluated. The evaluation algorithm first collects all actions that
  660. /// need to be evaluated and then evaluates them based on their evaluation
  661. /// priority by querying the actions.
  662. /// </para> <para>
  663. /// The action should return a positive priority number if it can be
  664. /// evaluated and a negative number if it cannot. Higher positive priority
  665. /// numbers mean that the action should be evaluated sooner, ahead of actions
  666. /// with lower positive priority. The negative numbers mean how much the
  667. /// action cannot be evaluated. The smaller the number, the less the action
  668. /// can be evaluated (such as when no action can be evaluated, the actions
  669. /// with least negative priorities are evaluated to break the loop and maybe
  670. /// enable other actions to be evaluated). Priority 0 means that the priority
  671. /// cannot be determined at this time.
  672. /// </para> <para>
  673. /// The default implementation returns kCanBeEvaluatedAssocEvaluationPriority
  674. /// + evaluationRequestSeverityLevel(status()) if the action can be evaluated
  675. /// because it only depends on objects that are results of actions that have
  676. /// already been evaluated (actually the rules are little bit more complex),
  677. /// and kCannotBeEvaluatedAssocEvaluationPriority if the action cannot be
  678. /// evaluated because it depends on some objects that are result of some
  679. /// not-yet evaluated actions.
  680. /// </para> <para>
  681. /// If the action owns an AcDbAssocActionBody object that overrides
  682. /// the evaluationPriorityOverride() method, this method is called and it
  683. /// supersedes the default implementation.
  684. /// </para> </summary>
  685. /// <returns>
  686. /// Priority greater than 0 means action can be evaluated, priority less
  687. /// than 0 means action cannot be evaluated. Priority 0 mens that it cannot
  688. /// be determined at this time.
  689. /// </returns>
  690. ///
  691. AcDbAssocEvaluationPriority evaluationPriority() const;
  692. /// <summary> <para>
  693. /// Lets the action report all other actions that need to be evaluated because
  694. /// this action is evaluated. It is repeatedly used to transitively collect
  695. /// all actions that need to be evaluated, before an associative network is
  696. /// evaluated. This action needs to be open at least for read and it needs
  697. /// to require to be evaluated: isEvaluationRequest(pAction->status()) == true.
  698. /// </para> <para>
  699. /// The default implementation checks dependencies of this action and then
  700. /// dependencies of other actions on the objects this action depends on,
  701. /// and reports all dependencies of other actions that need to be evaluated.
  702. /// This default implementation will suffice in most cases. The derived
  703. /// action classes can add their own logic, but they should also always call
  704. /// the base class implementation.
  705. /// </para> <para>
  706. /// If the action owns an AcDbAssocActionBody object that overrides the
  707. /// getDependentActionsToEvaluateOverride() method, this method is called
  708. /// and it supersedes the default implementation.
  709. /// </para> </summary>
  710. /// <param name="pActionsToEvaluateCallback">
  711. /// The method uses this callback to report other AcDbAssocActions,
  712. /// AcDbAssocDependencies and arbitrary AcDbObjects that should also be
  713. /// scheduled to evaluate when this action is evaluated.
  714. /// </param>
  715. ///
  716. void getDependentActionsToEvaluate(AcDbActionsToEvaluateCallback* pActionsToEvaluateCallback) const;
  717. /// <summary> <para>
  718. /// This method is called by the client code to evaluate an action or an
  719. /// associative network. It is the crux of the whole associative mechanism.
  720. /// </para> <para>
  721. /// It evaluates the action based on the current values of the objects the
  722. /// action depends on (the action has read-dependencies on these objects),
  723. /// changes the objects that depend on this action (the action has write-
  724. /// dependencies on these objects) and sets the status of the action to
  725. /// kIsUpToDateAssocStatus or to kFailedToEvaluateAssocStatus.
  726. /// </para> <para>
  727. /// If the action owns an AcDbAssocActionBody object, its evaluateOverride()
  728. /// method is called to do the real work. For internal classes it is also
  729. /// possible to directly override the AcDbImpAssocAction::evaluateOverride()
  730. /// method.
  731. /// </para> <para>
  732. /// AcDbAssocAction::evaluateDependencies() should be called from inside of
  733. /// the overridden evaluateOverride() method of a class derived from
  734. /// AcDbAssocActionBody or AcDbImpAssocAction to evaluate the dependencies
  735. /// that need to be evaluated. See the description at the evaluateDependencies()
  736. /// method.
  737. /// </para> <para>
  738. /// While the action is being evaluated, it calls methods of the
  739. /// currentEvaluationCallback() to inform the client code about the
  740. /// evaluation. See the definition of AcDbAssocEvaluationCallback for
  741. /// more details.
  742. ///
  743. /// </para> <para>
  744. /// The sequence of events is as follows:
  745. /// </para> <para>
  746. /// - Calls AcDbAssocEvaluationCallback::beginActionEvaluation().
  747. /// </para> <para>
  748. /// - Marks that action evaluation is in progress and sets the passed-in
  749. /// AcDbAssocEvaluationCallback as the current evaluation callback. It
  750. /// can then be obtained by other methods that are being invoked during
  751. /// the evaluation by calling currentEvaluationCallback().
  752. /// </para> <para>
  753. /// - Checks whether the action needs to be evaluated. Does not evaluate if not.
  754. /// </para> <para>
  755. /// - Calls AcDbImpAssocAction::evaluateOverride() to do the work. This calls
  756. /// the AcDbAssocActionBody::evaluateOverride() method if the action owns
  757. /// an action body object. The AcDbImpAssocAction::evaluateOverride() can
  758. /// also be directly overridden in the internal classes.
  759. /// </para> <para>
  760. /// - Calls AcDbAssocEvaluationCallback::endActionEvaluation().
  761. /// </para> </summary>
  762. ///
  763. /// <param name="pEvaluationCallback">
  764. /// While the action is being evaluated, it calls methods of the callback
  765. /// object to inform the client code about the evaluation. The callback pointer
  766. /// must not be NULL. See the definition of AcDbAssocEvaluationCallback
  767. /// for more details.
  768. /// </param>
  769. ///
  770. void evaluate(AcDbAssocEvaluationCallback* pEvaluationCallback);
  771. /// <summary> <para>
  772. /// Starting from this AcDbAssocAction, checks this AcDbAssocAction and its
  773. /// owners (in "physical" AutoCAD database object owhership sense) until an
  774. /// AcDbAssocNetwork is encountered whose "database" owner is not another
  775. /// AcDbAssocNetwork. Then finds an inverse of AcDbAssocNetwork::getInstanceFromObject(),
  776. /// i.e. finds the AcDbObject for which getInstanceFromObject() method returns
  777. /// the AcDbAssocNetwork.
  778. /// </para> </summary>
  779. /// <returns>
  780. /// AcDbObjectId of the AcDbObject owning an AcDbAssocNetwork that
  781. /// owns this AcDbAssocAction.
  782. /// </returns>
  783. ///
  784. AcDbObjectId objectThatOwnsNetworkInstance() const;
  785. /// <summary>
  786. /// This function is called to notify the action when a there is a drag
  787. /// operation in progress and some objects the action depends on, either
  788. /// directly or indirectly, are being dragged.
  789. /// </summary>
  790. /// <param name="status"> See the AcDb::DragStat enum. </param>
  791. ///
  792. void dragStatus(const AcDb::DragStat status);
  793. /// <summary>
  794. /// A static method to get all actions depending on the given AcDbObject
  795. /// (these actions have AcDbAssocDependencies on this object).
  796. /// </summary>
  797. /// <param name="pObject">
  798. /// The AcDbObject whose actions are requested. The object needs to be open
  799. /// at least for read.
  800. /// </param>
  801. /// <param name="readDependenciesWanted"> Actions that depend-on the object wanted. </param>
  802. /// <param name="writeDependenciesWanted"> Actions that modify the object wanted. </param>
  803. /// <param name="actionIds"> Returned AcDbObjectIds of the AcDbAssocActions. </param>
  804. /// <returns> Acad::ErrorStatus. </returns>
  805. ///
  806. static Acad::ErrorStatus getActionsDependentOnObject(const AcDbObject* pObject,
  807. bool readDependenciesWanted,
  808. bool writeDependenciesWanted,
  809. AcDbObjectIdArray& actionIds);
  810. /// <summary><para>
  811. /// Detaches the write-dependencies on the object from the object and marks
  812. /// the dependencies with kErasedAssocStatus. It does it in the reverse order,
  813. /// starting from the last write dependency on the object and ending with the
  814. /// first. It calls removeActionsControllingObjectOverride() on the individual
  815. /// action bodies of the object, so that they can do their own work, instead
  816. /// of the default handling that just detaches the write-dependencies from
  817. /// the object and sets their status to kErasedAssocStatus.
  818. /// </para><para>
  819. /// The evaluation algorithm will later evaluate the actions owning these
  820. /// dependencies with kErasedAssocStatus, and the evaluateOverride() method
  821. /// of these actions may either change or erase these actions.
  822. /// </para><para>
  823. /// This call may create a new object, copy some contents from objectToRemoveActionsFrom
  824. /// to this newly created object, do swapIdWith() with objectToRemoveActionsFrom
  825. /// and then erase objectToRemoveActionsFrom. This is currently happening
  826. /// for the AcDbExtrudedRevolved/SweptLoftedSurface entities that may be this
  827. /// way 'converted' to a base AcDbSurface entities.
  828. /// </para></summary>
  829. /// <param name="readOnlyDependencyHandling">
  830. /// <para>
  831. /// 0 ... Keep all read-only dependencies, let them still depend on the object,
  832. /// or redirect them to another object, if provided. Dependencies on
  833. /// intermediate (not last) object state will then depend on the last
  834. /// (and only) object state of the object, which may produce incorrect
  835. /// results in some cases.
  836. /// </para><para>
  837. /// 1 ... Keep read-only dependencies only if they depend on the last object
  838. /// state of the object, or redirect them to another object, if provided.
  839. /// Dependencies that depend on intermediate object states of the object
  840. /// are detached.
  841. /// </para><para>
  842. /// 2 ... Detach all dependencies on the object.
  843. /// </para></param>
  844. /// <returns> Acad::ErrorStatus. </returns>
  845. ///
  846. static Acad::ErrorStatus removeActionsControllingObject(
  847. const AcDbObjectId& objectToRemoveActionsFrom,
  848. int readOnlyDependencyHandling = 0,
  849. const AcDbObjectId& objectToRedirectReadOnlyDependenciesTo = AcDbObjectId::kNull);
  850. /// <summary> <para>
  851. /// Finds actions that need to be evaluated when the given action is evaluated,
  852. /// and changes their status to a evaluation request status, so that they will
  853. /// be evaluated. Does not do a transitive closure of all such actions, only
  854. /// the actions that directly relate to the given action are visited.
  855. /// </para><para>
  856. /// This method needs to be called, for example, before an action is going
  857. /// to be erased. If it were not called and the action was just erased, the
  858. /// other actions that should be evaluated would not be marked to evaluate
  859. /// and would not be evaluated.
  860. /// </para><para>
  861. /// This method should not be called when action evaluation is already in progress,
  862. /// because it is too late, all actions that need to be evaluated have already
  863. /// been marked to evaluate.
  864. /// </para></summary>
  865. ///
  866. static Acad::ErrorStatus markDependentActionsToEvaluate(const AcDbObjectId& actionId);
  867. /// <summary>
  868. /// Returns true if and only if there is an action with a write-dependency
  869. /// on the given AcDbObject and the action status is not isToBeSkipped().
  870. /// </summary>
  871. /// <remarks> This method is for internal use only. </remarks>
  872. /// <param name="pObject"> AcDbObject whose actions are checked. </param>
  873. /// <returns> True if and only if there is an active action on the object. </returns>
  874. ///
  875. static bool doesObjectHaveActiveActions(const AcDbObject* pObject);
  876. /// <summary>
  877. /// Removes all owned AcDbAssocActionParams, optionally also erasing them.
  878. /// </summary>
  879. /// <param name="alsoEraseThem">
  880. /// If true, the owned AcDbAssocActionParams are also erased. Otherwise they
  881. /// are just detached so that this action body is not their database owner.
  882. /// </param>
  883. /// <returns> Acad::ErrorStatus. </returns>
  884. ///
  885. Acad::ErrorStatus removeAllParams(bool alsoEraseThem);
  886. /// <summary> Returns then number of the owned AcDbAssocActionParams. </summary>
  887. /// <returns> Number of the owned AcDbAssocActionParameters. </returns>
  888. ///
  889. int paramCount() const;
  890. /// <summary>
  891. /// Returns an array of the owned AcDbAssocActionParams.
  892. /// </summary>
  893. /// <returns>
  894. /// Array of the owned AcDbAssocActionParams. Notice that it returns a
  895. /// const reference to an internal array. The client code must not hold on
  896. /// to this array and should make a copy of the array if it is doing anything
  897. /// more than just momentarily accessing its elements.
  898. /// </returns>
  899. ///
  900. const AcDbObjectIdArray& ownedParams() const;
  901. /// <summary>
  902. /// Adds a new AcDbAssocActionParam. This AcDbAssocAction becomes the database
  903. /// owner of this action parameter.
  904. /// </summary>
  905. /// <param name="paramId">
  906. /// AcDbObjectId of the action parameter being added. If the action parameter
  907. /// is already owned by this AcDbAssocAction, it it just returns its existing
  908. /// index in the array and does not add it again.
  909. ///</param>
  910. /// <param name="paramIndex">
  911. /// Returned index of the newly added action parameter. If the parameter is
  912. /// already owned by this AcDbAssocAction, its existing index is returned.
  913. /// </param>
  914. /// <returns> Acad::ErrorStatus. </returns>
  915. ///
  916. Acad::ErrorStatus addParam(const AcDbObjectId& paramId, int& paramIndex);
  917. /// <summary>
  918. /// Utility methods that creates a new AcDbAssocActionParam of the given
  919. /// pParamClass and with the given paramName and adds it to the database and
  920. /// to this AcDbAssocAction.
  921. /// </summary>
  922. /// <param name="paramName"> Name of the action parameter to create. </param>
  923. /// <param name="pParamClass"> Type of the action parameter to create. </param>
  924. /// <param name="paramId"> AcDbObjectId of the newly created action parameter. </param>
  925. /// <param name="paramIndex"> Index of the newly created action parameter. </param>
  926. /// <returns> Acad::ErrorStatus. </returns>
  927. ///
  928. Acad::ErrorStatus addParam(const AcString& paramName, AcRxClass* pParamClass, AcDbObjectId& paramId, int& paramIndex);
  929. /// <summary>
  930. /// Removes the AcDbAssocActionParam, optionally also erasing it.
  931. /// </summary>
  932. /// <param name="paramId"> AcDbObjectId of the action parameter to remove. </param>
  933. /// <param name="alsoEraseIt">
  934. /// If true, the owned action parameter is also erased. Otherwise it is just
  935. /// detached so that this AcDbAssocAction is not its database owner.
  936. /// </param>
  937. /// <returns> Acad::ErrorStatus. </returns>
  938. ///
  939. Acad::ErrorStatus removeParam(const AcDbObjectId& paramId, bool alsoEraseIt);
  940. /// <summary>
  941. /// Returns all owned AcDbAssocActionParams with the given name. Notice that
  942. /// more than one action parameter may have the same name. The parameters are
  943. /// always returned in the same order which is the order the parameters were
  944. /// added to the action. Thus, an array of action parameters can easily
  945. /// be represented by multiple action parameters with the same name.
  946. /// </summary>
  947. /// <param name="paramName"> The name of the action parameter. </param>
  948. /// <returns> All owned action parameters with the given name. </returns>
  949. ///
  950. const AcDbObjectIdArray& paramsAtName(const AcString& paramName) const;
  951. /// <summary>
  952. /// Returns an owned AcDbAssocActionParam specified by its name and optional
  953. /// index among all parameters with the same name. The default index 0 means
  954. /// the first parameter with the given name is returned.
  955. /// </summary>
  956. /// <param name="paramName"> The name of the action parameter. </param>
  957. /// <param name="index"> Index among all parameters with the same name. </param>
  958. /// <returns> The owned action parameter or a null AcDbObjectId if not found. </returns>
  959. ///
  960. AcDbObjectId paramAtName(const AcString& paramName, int index = 0) const;
  961. /// <summary>
  962. /// Returns an owned AcDbAssocActionParam in the array of all action parameters
  963. /// owned by this AcDbAssocAction.
  964. /// </summary>
  965. /// <param name="paramIndex"> Index in the array of all action parameters. </param>
  966. /// <returns> The owned action parameter or a null AcDbObjectId if not found. </returns>
  967. ///
  968. AcDbObjectId paramAtIndex(int paramIndex) const;
  969. /// <summary>
  970. /// Returns names of all owned value action parameters. The names of the value
  971. /// action parameters are arbitrary case-sensitive strings but must be unique.
  972. /// </summary>
  973. /// <param name="paramNames"> Names of all owned value action parameters. </param>
  974. ///
  975. void ownedValueParamNames(AcArray<AcString>& paramNames) const;
  976. /// <summary>
  977. /// Obtains arrays of values, expressions and evaluatorIds for a given value
  978. /// action parameter. The arrays can be of any length, but in most cases they
  979. /// will be of length 1, meaning that the value action parameter keeps a single
  980. /// value, not an array of values. All three returned arrays are of the same
  981. /// length. If there is no expression for a particular array element, the
  982. /// expression string and the evaluatorId are empty strings.
  983. /// </summary>
  984. /// <param name="paramName"> The name of the value action parameter. </param>
  985. /// <param name="values"> The returned array of values. </param>
  986. /// <param name="expressions"> The returned array ox expressions. </param>
  987. /// <param name="evaluatorIds"> The returned array of evaluatorIds. </param>
  988. /// <returns>
  989. /// If a value action parameter with the given name is not found, returns Acad::eNullPtr.
  990. /// </returns>
  991. ///
  992. Acad::ErrorStatus getValueParamArray(const AcString& paramName,
  993. AcArray<AcDbEvalVariant>& values,
  994. AcArray<AcString>& expressions,
  995. AcArray<AcString>& evaluatorIds) const;
  996. /// <summary>
  997. /// The same as getValueParamArray() but returns just the valueIndex's element
  998. /// of the returned array.
  999. /// </summary>
  1000. /// <param name="paramName"> The name of the value action parameter. </param>
  1001. /// <param name="values"> The returned values. </param>
  1002. /// <param name="expressions"> The returned expression. </param>
  1003. /// <param name="evaluatorIds"> The returned evaluatorId. </param>
  1004. /// <param name="valueIndex"> Index of the array element. </param>
  1005. /// <returns>
  1006. /// If a value action parameter with the given name is not found, returns
  1007. /// Acad::eNullPtr. If the valueIndex is out of range, returns Acad::eInvalidIndex.
  1008. /// </returns>
  1009. ///
  1010. Acad::ErrorStatus getValueParam(const AcString& paramName,
  1011. AcDbEvalVariant& value,
  1012. AcString& expression,
  1013. AcString& evaluatorId,
  1014. int valueIndex = 0) const;
  1015. /// <summary><para>
  1016. /// Sets arrays of values, expressions and evaluatorIds for a given value
  1017. /// action parameter. The arrays can be of any length, but in most cases they
  1018. /// will be of length 1, meaning that the value action parameter keeps a single
  1019. /// value, not an array of values. All three arrays must be of the same length.
  1020. /// If there is no expression for a particular array element, the expression
  1021. /// string and the evaluatorId must be empty strings.
  1022. /// </para><para>
  1023. /// If the user enters the expression in the form of "name=expression", the
  1024. /// automatically created AcDbAssocVariable is assigned the given "name",
  1025. /// apperars in the parameters manager and can be referenced by other
  1026. /// expressions as any other variable. If the expression is in the form
  1027. /// "expression", an anonymous variable is created that cannot be referenced
  1028. /// and is not visible in the parameters manager.
  1029. /// </para><para>
  1030. /// If a value parameter of the given name does not exist, it is created.
  1031. /// Otherwise the existing value parameter is used.
  1032. /// </para></summary>
  1033. /// <param name="paramName"> The name of the value action parameter. </param>
  1034. /// <param name="values"> The array of values to set. </param>
  1035. /// <param name="expressions"> The array of expressions to set. </param>
  1036. /// <param name="evaluatorIds"> The array of evaluatorIds to set. </param>
  1037. /// <param name="errorMessages"> The returned array of error messages for the individual expressions. </param>
  1038. /// <param name="silentMode"> Do not print error message if the expression string is invalid. </param>
  1039. /// <returns> Acad::ErrorStatus. </returns>
  1040. ///
  1041. Acad::ErrorStatus setValueParamArray(const AcString& paramName,
  1042. const AcArray<AcDbEvalVariant>& values,
  1043. const AcArray<AcString>& expressions,
  1044. const AcArray<AcString>& evaluatorIds,
  1045. AcArray<AcString>& errorMessages,
  1046. bool silentMode);
  1047. /// <summary><para>
  1048. /// The same as setValueParamArray() but sets just the valueIndex's element.
  1049. /// If the existing array is shorter that ther given valueIndex, the array
  1050. /// is extended to cover the valueIndex's element.
  1051. /// </para><para>
  1052. /// If a value parameter of the given name does not exist, it is created.
  1053. /// Otherwise the existing value parameter is used.
  1054. /// </para><para>
  1055. /// </para></summary>
  1056. /// <param name="paramName"> The name of the value action parameter. </param>
  1057. /// <param name="values"> The value to set. </param>
  1058. /// <param name="expressions"> The expression to set. </param>
  1059. /// <param name="evaluatorIds"> The evaluatorId to set. </param>
  1060. /// <param name="errorMessages"> The returned message for the expressions. </param>
  1061. /// <param name="silentMode"> Do not print error message if the expression string is invalid. </param>
  1062. /// <param name="valueIndex"> Index of the array element to set. </param>
  1063. /// <returns> Acad::ErrorStatus. </returns>
  1064. ///
  1065. Acad::ErrorStatus setValueParam(const AcString& paramName,
  1066. const AcDbEvalVariant& value,
  1067. const AcString& expression,
  1068. const AcString& evaluatorId,
  1069. AcString& errorMessage,
  1070. bool silentMode,
  1071. int valueIndex = 0);
  1072. /// <summary> Returns AcValue::UnitType of the value parameter. </summary>
  1073. /// <param name="paramName"> The name of the value action parameter. </param>
  1074. /// <returns> The AcValue::UnitType of the value parameter. </returns>
  1075. ///
  1076. AcValue::UnitType valueParamUnitType(const AcString& paramName) const;
  1077. /// <summary> Sets the AcValue::UnitType of the value parameter. </summary>
  1078. /// <param name="paramName"> The name of the value action parameter. </param>
  1079. /// <param name="unitType"> AcValue::UnitType. </param>
  1080. /// <returns> Acad::ErrorStatus. </returns>
  1081. ///
  1082. Acad::ErrorStatus setValueParamUnitType(const AcString& paramName, AcValue::UnitType unitType);
  1083. /// <summary>
  1084. /// Removes the value parameter and also erases the corresponding AcDbAssocVariables,
  1085. /// if there are any.
  1086. /// </summary>
  1087. /// <param name="paramName"> The name of the value action parameter to remove. </param>
  1088. /// <returns> Acad::ErrorStatus. </returns>
  1089. ///
  1090. Acad::ErrorStatus removeValueParam(const AcString& paramName);
  1091. /// <summary><para>
  1092. /// Each individual value of a value action parameter may either be a constant,
  1093. /// or defined by an expression. When it is defined by an expression, the value
  1094. /// action parameter keeps AcDbObjectId of a read-only AcDbAssocValueDependency
  1095. /// (the dependency is owned by the parent AcDbAssocAction) on an AcDbAssocVariable
  1096. /// that keeps the expression and provides the input value for the value
  1097. /// action parameter. This variable is exclusively managed by the value parameter
  1098. /// who is responsible for its creation, deletion, copy, etc.
  1099. /// </para><para>
  1100. /// If the user enters the expression in the form of "name=expression", this
  1101. /// automatically created AcDbAssocVariable is assigned the given "name",
  1102. /// apperars in the parameters manager and can be referenced by other
  1103. /// expressions as any other variable. If the expression is in the form
  1104. /// "expression", an anonymous variable is created that cannot be referenced
  1105. /// and is not visible in the parameters manager.
  1106. /// </para></summary>
  1107. /// <param name="paramName"> The name of the value action parameter. </param>
  1108. /// <param name="variableIds">
  1109. /// Returned array of AcDbAssocVariables for all the values of the value action
  1110. /// parameter with the given name. If a value is a constant and does not have
  1111. /// a corresponding AcDbAssocVariable, AcDbObjectId::kNull is returned for
  1112. /// that array element.
  1113. /// </param>
  1114. /// <returns> Acad::ErrorStatus. </returns>
  1115. ///
  1116. Acad::ErrorStatus valueParamInputVariables(const AcString& paramName, AcDbObjectIdArray& variableIds) const;
  1117. /// <summary><para>
  1118. /// The value parameter can keep AcDbObjectId of an "output" dependency (of
  1119. /// any kind) on a controlled object. The value parameter (expected to have
  1120. /// just a single value) then becomes "linked" with the named "property" of
  1121. /// the controlled object.
  1122. /// </para><para>
  1123. /// The property name is the name of the value parameter. The "property"
  1124. /// of the controlled object is accessed via the AcDbAssocValueProviderPE
  1125. /// protocol extension that the controlled object must expose. The setValue()
  1126. /// method of the protocol extension is then called to set the "property" of
  1127. /// the controlled object to be the same as the current value of the value
  1128. /// parameter. The getValue() method of the protocol extension is then called
  1129. /// to obtain the current value of the "property" of the controlled object and
  1130. /// set it to the value parameter.
  1131. /// </para></summary>
  1132. /// <param name="paramName"> The name of the value action parameter. </param>
  1133. /// <param name="controlledObjectDepId">
  1134. /// An existing AcDbAssocDependency (or a derived class) on the AcDbObject
  1135. /// controlled by this value parameter. The dependency is owned by the action
  1136. /// that owns this AcDbAssocAction.
  1137. /// </param>
  1138. /// <returns> Acad::ErrorStatus. </returns>
  1139. ///
  1140. Acad::ErrorStatus setValueParamControlledObjectDep(const AcString& paramName, const AcDbObjectId& controlledObjectDepId);
  1141. /// <summary><para>
  1142. /// Updates the "propery" of the controlled object from the current value of
  1143. /// a value action parameter.
  1144. /// </para><para>
  1145. /// See setValueParamControlledObjectDep() for information about how to
  1146. /// link value action parameters with named properties of controlled objects.
  1147. /// </para></summary>
  1148. /// <param name="paramName"> The name of the value action parameter. </param>
  1149. /// <returns> Acad::ErrorStatus. </returns>
  1150. ///
  1151. Acad::ErrorStatus updateValueParamControlledObject(const AcString& paramName) const;
  1152. /// <summary><para>
  1153. /// Updates the value of the value action parameter from the current value of
  1154. /// a named "property" of the controlled object.
  1155. /// </para><para>
  1156. /// See setValueParamControlledObjectDep() for information about how to
  1157. /// link value action parameters with named properties of controlled objects.
  1158. /// </para></summary>
  1159. /// <param name="paramName"> The name of the value action parameter. </param>
  1160. /// <returns> Acad::ErrorStatus. </returns>
  1161. ///
  1162. Acad::ErrorStatus updateValueParamFromControlledObject(const AcString& paramName);
  1163. /// <summary><para>
  1164. /// Updates named properties of all objects that are linked with value action
  1165. /// paramerters.
  1166. /// </para><para>
  1167. /// See setValueParamControlledObjectDep() for information about how to
  1168. /// link value action parameters with named properties of controlled objects.
  1169. /// </para></summary>
  1170. /// <returns> Acad::ErrorStatus. </returns>
  1171. ///
  1172. Acad::ErrorStatus updateAllObjectsControlledByValueParams() const;
  1173. /// <summary>
  1174. /// Transforms all constant geometries in all owned AcDbAssocParam(eters).
  1175. /// Example of a constant geometry is an AcGeCurve3d* in AcDbAssocEdgeActionParam
  1176. /// or AcGePoint3d in AcDbAssocVertexActionParam.
  1177. /// </summary>
  1178. /// <param name="transform">
  1179. /// Transformation to be applied to all constant geometries in the owned
  1180. /// AcDbAssocActionParams.
  1181. /// </param>
  1182. /// <returns> Acad::ErrorStatus. </returns>
  1183. ///
  1184. Acad::ErrorStatus transformAllConstantGeometryParams(const AcGeMatrix3d& transform);
  1185. /// <summary>
  1186. /// Scales values of all value action parameters whose units indicate they
  1187. /// represent distances. If the value is defined by an expression, the expression
  1188. /// is replaced with a constant value.
  1189. /// </summary>
  1190. /// <param name="scaleFactor">
  1191. /// Scaling factor to be applied to all distance value action parameters.
  1192. /// </param>
  1193. /// <returns> Acad::ErrorStatus. </returns>
  1194. ///
  1195. Acad::ErrorStatus scaleAllDistanceValueParams(double scaleFactor);
  1196. friend class AcDbImpAssocAction;
  1197. }; // class AcDbAssocAction
  1198. #pragma pack (pop)