AcDbAssocDependency.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  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. // AcDbAssocDependency base class.
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #pragma once
  19. #include "AcDbAssocGlobal.h"
  20. #include "AcDbCompoundObjectId.h"
  21. #pragma pack (push, 8)
  22. /// <summary> <para>
  23. /// AcDbAssocDependencies represent information about which AcDbAssocActions depend
  24. /// on or modify which AcDbObjects. This is how the associativity in the drawing is
  25. /// represented. Dependencies are owned by actions and are attached to the objects
  26. /// as persistent reactors. When the dependent-on object changes, it notifies the
  27. /// dependency via the persistent reactor mechanism. The dependency checks
  28. /// whether the change is relevant, such as when the dependency is on an endpoint
  29. /// of a line but the color of the line changed, or the other endpoint changed,
  30. /// and if yes, it changes its status indicating that it needs to be evaluated,
  31. /// and also changes the status of the owning action indicating that it needs
  32. /// to be evaluated (and the action changes the status of the AcDbAssocNetwork
  33. /// that owns it).
  34. /// </para> <para>
  35. /// The base AcDbAssocDependency class can be used as it but there are also
  36. /// provided a few concrete derived dependency classes that represent particular
  37. /// kinds of dependencies on particular objects or subobjects, such as
  38. /// on subentities (faces, edges, vertices) of geometric entities, on objects
  39. /// that provide a numerical value, etc. For example, the dependency on a
  40. /// subentity of a geometric entity keeps AcDbAssocPersSubentId of the subentity
  41. /// and the cached subentity geometry (such as the [x,y,z] of a vertex
  42. /// subentity, the AcDbCurve of an edge subentity, etc.). It can then check
  43. /// whether the subentity really changed by obtaining the subentity geometry
  44. /// from the geometric entity and comparing it with the cached geometry. If they
  45. /// are the same, the change notification is ignored.
  46. /// </para> <para>
  47. /// A better way to add a custom dependency class is to derive a custom
  48. /// AcDbAssocDependencyBody class (see comments at the AcDbAssocDependencyBody
  49. /// class) and make objects of this class owned by the parent AcDbAssocDependency
  50. /// objects. The relation between AcDbAssocDependency and AcDbAssocDependencyBody
  51. /// classes is analogous to the relation between AcDbAssocAction and AcDbAssocActionBody
  52. /// classes, so please read the comments at the AcDbAssocAction class for more
  53. /// information. In particular, the dependency body is fully owned by its parent
  54. /// dependency, such as when the parent dependency is erased, it also erases the
  55. /// owned dependency body.
  56. /// </para> <para>
  57. /// A more memory efficient way to implement custom dependency behavior is to
  58. /// use objects of the AcDbAssocDependency base class and let them delegate to
  59. /// the owning action (see the isDelegatingToOwningAction() property). The
  60. /// AcDbAssocActionBody owned by the action owning the dependency then overrides
  61. /// methods like AcDbAssocActionBody::isRelevantDependencyChangeOverride() to
  62. /// implement the custom dependency behavior.
  63. ///
  64. /// </para> </summary>
  65. ///
  66. class ACDB_PORT AcDbAssocDependency : public AcDbObject
  67. {
  68. public:
  69. ACRX_DECLARE_MEMBERS(AcDbAssocDependency);
  70. /// <summary> Default constructor. </summary>
  71. /// <param name="createImpObject"> See AcDbAssocCreateImpObject. </param>
  72. ///
  73. explicit AcDbAssocDependency(AcDbAssocCreateImpObject createImpObject = kAcDbAssocCreateImpObject);
  74. /// <summary>
  75. /// Returns AcDbObjectId of an object of a class derived from
  76. /// AcDbAssocDependencyBody, or a null id if no dependency body object
  77. /// has been set. The AcDbAssocDependencyBody object is owned by this
  78. /// AcDbAssocDependency object and implements the body of the custom
  79. /// dependency. See the comments at the AcDbAssocDependencyBody class for
  80. /// more information.
  81. /// </summary>
  82. /// <returns>
  83. /// AcDbObjectId of an object of a class derived from AcDbAssocDependencyBody
  84. /// or null id.
  85. /// </returns>
  86. ///
  87. AcDbObjectId dependencyBody() const;
  88. /// <summary>
  89. /// Sets AcDbObjectId of an object of a class derived from
  90. /// AcDbAssocDependencyBody. The AcDbAssocDependencyBody object becomes
  91. /// owned by this AcDbAssocDependency object and implements the body of
  92. /// the custom dependency. See the comments at the AcDbAssocDependencyBody
  93. /// class for more information.
  94. /// </summary>
  95. /// <param name="dependencyBodyId">
  96. /// AcDbObjectId of an object of a class derived from AcDbAssocDependencyBody
  97. /// or null id.
  98. /// </param>
  99. /// <returns> Acad::ErrorStatus. </returns>
  100. ///
  101. Acad::ErrorStatus setDependencyBody(const AcDbObjectId& dependencyBodyId);
  102. /// <summary> Get the current AcDbAssocStatus of this dependency. </summary>
  103. /// <returns> The AcDbAssocStatus of this dependency. </returns>
  104. ///
  105. AcDbAssocStatus status() const;
  106. /// <summary> <para>
  107. /// Sets the AcDbAssocStatus of the dependency. If the status is one of the
  108. /// codes that indicate that the action owning the dependency will need to
  109. /// be evaluated (the isEvaluationRequest() predicate returns true for such
  110. /// a status), it can also notify the action owning the dependency to change
  111. /// its status indicating that it needs to be evaluated. The action may change
  112. /// its status and notify the network owning the action. The network may change
  113. /// its status and notify its owning network, etc. until all the networks
  114. /// in the hirearchy are notified that they contain an action that needs to
  115. /// be evaluated.
  116. /// </para> <para>
  117. /// If the new status satisfies the isEvaluationRequest() predicate and
  118. /// evaluationRequestSeverityLevel() of the new status is lower than the
  119. /// current evaluation request status of the dependency, the current higher
  120. /// status of the dependency is kept and not overwritten by the new lower
  121. /// status. Also, if the current status of the dependency satisfies the
  122. /// isTobeSkipped() predicate, it is not overwritten by any new status that
  123. /// isEvaluationRequest(). To change the dependency status in such a case, the
  124. /// dependency status needs to be first changed to kIsUpToDateAssocStatus,
  125. /// and after that it can be changed to an isEvaluationRequest() status.
  126. /// </para> </summary>
  127. /// <param name="newStatus"> The new AcDbAssocStatus of the dependency. </param>
  128. /// <param name="notifyOwningAction">
  129. /// If true, and the passed-in status indicates that the dependency needs to
  130. /// be evaluated, the status of the AcDbAssocAction owning this dependency
  131. /// is set to the same status (unless the action evaluation status is already
  132. /// more severe than the new one). The action then notifies its owning network.
  133. /// </param>
  134. /// <returns> Acad::ErrorStatus. </returns>
  135. ///
  136. Acad::ErrorStatus setStatus(AcDbAssocStatus newStatus,
  137. bool notifyOwningAction = true);
  138. /// <summary>
  139. /// Returns true iff the AcDbAssocAction owning the dependency uses the
  140. /// value of the dependent-on AcDbObject. It just returns the value of a bool
  141. /// data member owned by AcDbAssocDependency. The default value of this flag
  142. /// is false.
  143. /// </summary>
  144. /// <returns>
  145. /// <para> true = Action uses the value of the dependent-on object. </para>
  146. /// <para> false = Action does not use the value of the dependent-on object. </para>
  147. /// </returns>
  148. ///
  149. bool isReadDependency() const;
  150. /// <summary>
  151. /// Returns true iff the AcDbAssocAction owning the dependency changes the
  152. /// value of the dependent-on AcDbObject. It just returns the value of a bool
  153. /// data member owned by AcDbAssocDependency. The default value of this flag
  154. /// is false.
  155. /// </summary>
  156. /// <returns>
  157. /// <para> true = Action changes the value of the dependent-on object. </para>
  158. /// <para> false = Action does not change the value of the dependent-on object. </para>
  159. /// </returns>
  160. ///
  161. bool isWriteDependency() const;
  162. /// <summary>
  163. /// Sets what isReadDependency() should return.
  164. /// </summary>
  165. /// <param name="yesNo"> Value that isReadDependency() should return. </param>
  166. ///
  167. void setIsReadDependency(bool yesNo);
  168. /// <summary>
  169. /// Sets what isWriteDependency() should return.
  170. /// </summary>
  171. /// <param name="yesNo"> Value that isWriteDependency() should return. </param>
  172. ///
  173. void setIsWriteDependency(bool yesNo);
  174. /// <summary> <para>
  175. /// Returns true iff the AcDbAssocAction owning the dependency requires the
  176. /// dependent-on AcDbObject to be in the expected "object state" with
  177. /// respect to the list of dependencies on the object, before the action can
  178. /// be evaluated.
  179. /// </para> <para>
  180. /// It means actions that own write-type dependencies on the object that
  181. /// precede this dependency in the list of all dependencies on the object
  182. /// need to be evaluated, and actions owning write-type dependencies on the
  183. /// object that follow this dependency in the list must not be evaluated.
  184. /// This also means the object is in the object state just after evaluation
  185. /// of the immediately preceding action that modified the object but before
  186. /// evaluation of the next action that would modify the object again and
  187. /// bring it to the next object state.
  188. /// </para> <para>
  189. /// It just returns the value of a bool data member owned by AcDbAssocDependency.
  190. /// The default value of this flag is true.
  191. /// </para> </summary>
  192. /// <returns>
  193. /// <para>
  194. /// true = Dependency is object state dependent, i.e. its position in the
  195. /// list of dependencies on the object matters.
  196. /// </para>
  197. /// <para>
  198. /// false = Dependency is not object state dependent, i.e. its position in
  199. /// the list of dependencies on the object matters.
  200. /// </para>
  201. /// </returns>
  202. ///
  203. bool isObjectStateDependent() const;
  204. /// <summary>
  205. /// Sets what isObjectStateDependent() should return. It just sets the bool
  206. /// data member owned by AcDbAssocDependency.
  207. /// </summary>
  208. /// <param name="yesNo"> Value that isObjectStateDependent() should return. </param>
  209. ///
  210. void setIsObjectStateDependent(bool yesNo);
  211. /// <summary> <para>
  212. /// Returns order of the dependency, i.e. the order where it should be
  213. /// positioned in the list of all dependencies on an AcDbObject. Dependencies
  214. /// with lower order() are positioned in the list before the dependencies
  215. /// with higher order(). Dependencies with the same order() are ordered
  216. /// based on how they were added to the object, the dependencies added
  217. /// later are positioned after the dependencies added earlier.
  218. /// </para> <para>
  219. /// It just returns the value of an int data member owned by AcDbAssocDependency.
  220. /// Default value of this data member is 0.
  221. /// </para> </summary>
  222. /// <returns>
  223. /// Order is any integer value stored in the dependency. The default
  224. /// value is 0.
  225. /// </returns>
  226. ///
  227. int order() const;
  228. /// <summary>
  229. /// Sets what order() should return. It just sets the int data member owned
  230. /// by AcDbAssocDependency. Notice that if a dependency has already been
  231. /// attached to an object by calling attachToObject(), calling setOrder()
  232. /// does not reposition the dependency in the list and should not be done.
  233. /// </summary>
  234. /// <param name="yesNo"> Value that order() should return. </param>
  235. ///
  236. void setOrder(int newOrder);
  237. /// <summary>
  238. /// Every dependency is owned (in the logical as well as in the AutoCAD
  239. /// database sense) by an AcDbAssocAction.
  240. /// </summary>
  241. /// <returns> The owning AcDbAssocAction. </returns>
  242. ///
  243. AcDbObjectId owningAction() const { return ownerId(); }
  244. /// <summary> <para>
  245. /// Every dependency is owned (in the logical as well as in the AutoCAD
  246. /// database sense) by an AcDbAssocAction.
  247. /// </para> <para>
  248. /// This method should not be called directly, AcDbAssocAction::add/removeDependency()
  249. /// should be used, which in turn calls setOwningAction(), but it does more.
  250. /// </para> </summary>
  251. /// <param name="actionId"> The AcDbAssocAction owning this dependency. </param>
  252. /// <returns> Acad::ErrorStatus. </returns>
  253. ///
  254. Acad::ErrorStatus setOwningAction(const AcDbObjectId& actionId);
  255. /// <summary>
  256. /// A dependency is attached to the dependent-on AcDbObject as a persistent
  257. /// reactor.
  258. /// </summary>
  259. /// <returns>
  260. /// The AcDbObject this dependency is attached to, or AcDbObjectId::kNull
  261. /// if the dependency is not attached to any object.
  262. /// </returns>
  263. ///
  264. AcDbObjectId dependentOnObject() const;
  265. /// <summary>
  266. /// A dependency is attached as a persistent reactors to all objects of
  267. /// the AcDbCompoundObjectId. If the dependency does not use AcDbCompoundObjectId,
  268. /// the returned AcDbCompoundObjectId is of the dependentOnObject() converted
  269. /// to an AcDbCompoundObjectId.
  270. /// </summary>
  271. /// <param name="compoundId">
  272. /// The AcDbCompoundObjectId, either directly kept in this dependency, or
  273. /// created from the dependentOnObject() AcDbObjectId.
  274. /// </param>
  275. /// <returns> Acad::ErrorStatus. </returns>
  276. ///
  277. Acad::ErrorStatus getDependentOnCompoundObject(AcDbCompoundObjectId& compoundId) const;
  278. /// <summary>
  279. /// Returns true if the dependency is using AcDbCompoundObjectId to depend
  280. /// on the dependent-on-object.
  281. /// </summary>
  282. /// <returns>
  283. /// True iff AcDbCompoundObjectId is used to identify the dependent-on-object.
  284. /// </returns>
  285. ///
  286. bool isDependentOnCompoundObject() const;
  287. /// <summary>
  288. /// All dependencies attached to the same AcDbObject are kept in a doubly-linked
  289. /// list. The order in the list is determied by the order() property of the
  290. /// dependencies in the list.
  291. /// </summary>
  292. /// <returns>
  293. /// The previous dependency in the list of dependencies of an AcDbObject or
  294. /// AcDbObjectId::kNull if it is the first dependency in the list.
  295. /// </returns>
  296. ///
  297. AcDbObjectId prevDependencyOnObject() const;
  298. /// <summary>
  299. /// All dependencies attached to the same AcDbObject are kept in a doubly-linked
  300. /// list. The order in the list is determied by the order() property of the
  301. /// dependencies in the list.
  302. /// </summary>
  303. /// <returns>
  304. /// The next dependency in the list of dependencies of an AcDbObject or
  305. /// AcDbObjectId::kNull if it is the last dependency in the list.
  306. /// </returns>
  307. ///
  308. AcDbObjectId nextDependencyOnObject() const;
  309. /// <summary>
  310. /// A dependency is attached to the dependent-on AcDbObject as a persistent
  311. /// reactor, but it may also not be attached to any object. In this case
  312. /// AcDbAssocDependency::dependentOnObject() returns AcDbObjectId::kNull.
  313. /// </summary>
  314. /// <returns> true iff the dependency it attached to an object. </returns>
  315. ///
  316. bool isAttachedToObject() const { return !dependentOnObject().isNull(); }
  317. /// <summary> <para>
  318. /// Attaches this dependency to a given AcDbCompoundObjectId as a persistent
  319. /// reactor and also orders it to be at the correct position in the list
  320. /// of dependencies on the object, based on the dependency order(). The
  321. /// dependency that is being attached must not be currently attached to
  322. /// any object.
  323. /// </para> <para>
  324. /// When the AcDbCompoundObjectId contains multiple ids, it attaches the
  325. /// dependency to the AcDbCompoundObjectId::topId(), and also attaches this
  326. /// dependency as a persistent reactor to all the other objects that the
  327. /// AcDbCompoundObjectId references.
  328. /// </para> <para>
  329. /// The object may refuse dependencies being attached to it by deriving from
  330. /// AcDbAssocDependencyPE AcRx protocol extension class, implementing the
  331. /// allowsDependencies() predicate and attaching the protocol extension to
  332. /// the object. In this case attachToObject() then returns eVetoed error status.
  333. /// The client code should check the returned error status and do not assume
  334. /// that it is always eOk. The AcDbAssocDependencyPE also allows the object
  335. /// to redirect the dependency attachment to another object by implementing
  336. /// the redirectDependencyAttachment() method.
  337. /// </para> </summary>
  338. /// <param name="compoundId"> The AcDbCompoundObjectId to attach the
  339. /// dependency to. If regular AcDbObjectId is passed in, it is automatically
  340. /// converted to AcDbCompoundObjectId.
  341. /// </param>
  342. /// <returns> Acad::ErrorStatus. </returns>
  343. ///
  344. Acad::ErrorStatus attachToObject(const AcDbCompoundObjectId& compoundId);
  345. /// <summary>
  346. /// Transfers the dependency from the current object to another object.
  347. /// It does it by first detaching it from its current object and then attaching
  348. /// to the new one. It is similar to calling detachFromObject() followed
  349. /// by attachToObject(), but it also redirects other information in the dependency,
  350. /// such as the AcDbAssocPersSubentId owned by AcDbAssocGeomDependency.
  351. /// </summary>
  352. ///
  353. Acad::ErrorStatus transferToObject(const AcDbCompoundObjectId& compoundId);
  354. /// <summary>
  355. /// Returns current status of the dependentOnObject, can be eOk,
  356. /// eNotInitializedYet or eInvalidObjectId.
  357. /// </summary>
  358. /// <returns> Acad::ErrorStatus. </returns>
  359. ///
  360. Acad::ErrorStatus dependentOnObjectStatus() const;
  361. /// <summary>
  362. /// Detaches this dependency from the AcDbObject it is currently attached
  363. /// to. It also detatches it from the list of persistent reactors of the
  364. /// dependent-on-object, and if the dependency is on a compound object,
  365. /// it detaches this dependency from the persistent reactor lists of all
  366. /// objects the dependency is currently attached to.
  367. /// </summary>
  368. /// <returns> Acad::ErrorStatus. </returns>
  369. ///
  370. Acad::ErrorStatus detachFromObject();
  371. /// <summary> <para>
  372. /// Updates the object the dependency depends on, based on the information
  373. /// the dependency obtains from the owning action. If the dependency owns
  374. /// an AcDbAssocDependencyBody object, its updateDependentOnObject() method
  375. /// is called, otherwise the default implementation of this method does
  376. /// nothing.
  377. /// </para> <para>
  378. /// The dependency object must be opened at least for read. This method is
  379. /// not made "const" because it could potentially update some cache kept in
  380. /// the dependency, but it is not expected to do so.
  381. /// </para> </summary>
  382. /// <returns> Acad::ErrorStatus. </returns>
  383. ///
  384. Acad::ErrorStatus updateDependentOnObject();
  385. /// <summary> <para>
  386. /// Sets the dependent-on object of this dependency to be the given
  387. /// AcDbCompoundObjectId.
  388. /// </para><para>
  389. /// Unlike attachToObject(), it does not add this dependency to the list of
  390. /// persistent reactors of the object. Therefore the dependency is in limbo,
  391. /// neither attached nor non-attached. To really attach this dependency
  392. /// to an object after setDependentOnObject() has already been called with a
  393. /// non-null AcDbObjectId, setDependentOnObject() needs to be called first
  394. /// with a null compoundId before attachToObject() is called.
  395. /// </para> <para>
  396. /// This method can mess-up the dependency and the client code should not
  397. /// have (m)any reasons to call it.
  398. /// </para> </summary>
  399. /// <param name="compoundId">
  400. /// The AcDbCompoundObjectId the dependency should depend-on (may be null).
  401. /// </param>
  402. ///
  403. void setDependentOnObject(const AcDbCompoundObjectId& compoundId);
  404. /// <summary>
  405. /// Gets the first dependency on the given AcDbObject. Dependencies are attached
  406. /// to AcDbObjects in the form of persistent reactors and are ordered on the
  407. /// object based on their order(). The first dependency in this ordered
  408. /// list is returned.
  409. /// </summary>
  410. /// <param name="pObject">
  411. /// The AcDbObject whose first dependency is requested. The object needs
  412. /// to be open at least for read.
  413. /// </param>
  414. /// <param name="firstDependencyId">
  415. /// The returned first dependency on the AcDbObject, or AcDbObjectId::kNull
  416. /// if there are no dependencies attached to the AcDbObject.
  417. /// </param>
  418. /// <returns> Acad::ErrorStatus. </returns>
  419. ///
  420. static Acad::ErrorStatus getFirstDependencyOnObject(const AcDbObject* pObject,
  421. AcDbObjectId& firstDependencyId);
  422. /// <summary>
  423. /// Gets all dependencies on the given AcDbObject. Dependencies are attached
  424. /// to AcDbObjects in the form of persistent reactors and are ordered on the
  425. /// object based on their order(). The retuned array contains the dependencies
  426. /// properly ordered.
  427. /// </summary>
  428. /// <param name="pObject">
  429. /// The AcDbObject whose dependencies are requested. The object needs
  430. /// to be open at least for read.
  431. /// </param>
  432. /// <param name="readDependenciesWanted"> Read-type dependencies wanted. </param>
  433. /// <param name="writeDependenciesWanted"> Write-type dependencies wanted. </param>
  434. /// <param name="dependencyIds"> Returned AcDbObjectIds of the AcDbAssocDependencies. </param>
  435. /// <returns> Acad::ErrorStatus. </returns>
  436. ///
  437. static Acad::ErrorStatus getDependenciesOnObject(const AcDbObject* pObject,
  438. bool readDependenciesWanted,
  439. bool writeDependenciesWanted,
  440. AcDbObjectIdArray& dependencyIds);
  441. /// <summary>
  442. /// Gets all dependencies on the given AcDbObject and notifies them about a
  443. /// change by setting their status. It notifies both the primary dependencies
  444. /// on the object (when the object is the dependentOnObject() of the dependency)
  445. /// as well as secondary dependencies (when the object is one of the objects
  446. /// in the AcDbCompoundObjectId of the dependency).
  447. /// </summary>
  448. /// <param name="pObject">
  449. /// The AcDbObject whose dependencies are to be notified. The object needs
  450. /// to be open at least for read.
  451. /// </param>
  452. /// <param name="newStatus"> The new status to be set to the dependencies. </param>
  453. /// <returns> Acad::ErrorStatus. </returns>
  454. ///
  455. static Acad::ErrorStatus notifyDependenciesOnObject(const AcDbObject* pObject,
  456. AcDbAssocStatus newStatus);
  457. /// <summary> <para>
  458. /// Returns whether some dependency methods delegate to the action that
  459. /// owns the dependency if the method is not directly implemented in the
  460. /// dependency or in the AcDbAssocDependencyBody object that the dependency
  461. /// may own. The default is true, i.e. the delegation takes place.
  462. /// Examples of dependency methods that perform the delegation to the owning
  463. /// action are methods like isRelevantChange(), hasCachedValue(), isEqualTo(),
  464. /// isDependentOnTheSameThingAs(), evaluate(), etc.
  465. /// </para> <para>
  466. /// The reason for this delegation is to give developers of custom actions
  467. /// more freedom in their choice where to keep the data related to the
  468. /// dependencies owned by their custom actions, and to reduce the need
  469. /// to derive new dependency body classes.
  470. /// </para> </summary>
  471. /// <returns>
  472. /// Returns whether some dependency methods delegate to the owning action.
  473. /// The default is yes, i.e. the dependencies do delegate.
  474. /// </returns>
  475. ///
  476. bool isDelegatingToOwningAction() const;
  477. /// <summary> <para>
  478. /// Controls whether some dependency methods delegate to the action that
  479. /// owns the dependency if the method is not directly implemented in the
  480. /// dependency or in the AcDbAssocDependencyBody object that the dependency
  481. /// may own. The default is true, i.e. the delegation takes place.
  482. /// Examples of dependency methods that perform the delegation to the owning
  483. /// action are methods like isRelevantChange(), hasCachedValue(), isEqualTo(),
  484. /// isDependentOnTheSameThingAs(), evaluate(), etc.
  485. /// </para> <para>
  486. /// The reason for this delegation is to give developers of custom actions
  487. /// more freedom in their choice where to keep the data related to the
  488. /// dependencies owned by their custom actions, and to reduce the need
  489. /// to derive new dependency body classes.
  490. /// </para> </summary>
  491. /// <param name="yesNo">
  492. /// Controls whether some dependency methods delegate to the owning action.
  493. /// The default is yes, i.e. the dependencies do delegate.
  494. /// </param>
  495. ///
  496. void setIsDelegatingToOwningAction(bool yesNo);
  497. /// <summary> <para>
  498. /// Returns true iff the dependency currently holds the cached value of the
  499. /// "thing" it depends on. It does not necessarily mean that the cached value
  500. /// is current and the same as the current value of the dependent-on "thing".
  501. /// If the thing changed, the cached value the dependency holds may still be
  502. /// the previously cached value. But if the dependency status is
  503. /// kIsUpToDateAssocStatus, the cached value should be in sync with the
  504. /// "thing" the dependency depends on.
  505. /// </para> <para>
  506. /// The default implementation of this predicate calls the owning
  507. /// action's AcDbAssocAction::hasDependencyCachedValue(), i.e. it delegates
  508. /// the decision to the action that owns the dependency. This delegation
  509. /// can be turned off by calling setIsDelegatingToOwningAction(false). The
  510. /// default implementation of AcDbAssocAction::hasDependencyCachedValue(),
  511. /// or if there is delegation, returns false.
  512. /// </para> <para>
  513. /// If the dependency owns an AcDbAssocDependencyBody object that overrides
  514. /// the hasCachedValueOverride() predicate, this predicate is called and it
  515. /// supersedes the default implementation.
  516. /// </para> </summary>
  517. /// <returns>
  518. /// Returns true iff the dependency holds a cached value. By default
  519. /// returns false.
  520. /// </returns>
  521. ///
  522. bool hasCachedValue() const;
  523. /// <summary> <para>
  524. /// This predicate returns true iff the dependent-on "thing" really changed
  525. /// in such a way that the change is relevant to this particular dependency
  526. /// type. For example, if the dependency is on a subentity of a geometric
  527. /// entity, it should check whether the geometry of this subentity is really
  528. /// different from what it was before (such as by comparing it with the
  529. /// cached geometry).
  530. /// </para> <para>
  531. /// Using this predicate it is possible to filter-out false or irrelevant
  532. /// change notifications and thus avoid unnecessary action reevaluations.
  533. /// When this predicate returns false, the change notification from the
  534. /// dependent-on object is ignored and the status of this dependency is
  535. /// not changed.
  536. /// </para> <para>
  537. /// The default implementation of this predicate calls the owning
  538. /// action's AcDbAssocAction::isRelevantDependencyChange() predicate, i.e.
  539. /// it delegates the decision to the action that owns the dependency. This
  540. /// delegation can be turned off by calling setIsDelegatingToOwningAction(false).
  541. /// The default implementation of AcDbAssocAction::isRelevantDependencyChange(),
  542. /// or if there is no delegation, returns true.
  543. /// </para> <para>
  544. /// If the dependency owns an AcDbAssocDependencyBody object that overrides
  545. /// the isRelevantChangeOverride() predicate, this predicate is called and it
  546. /// supersedes the default implementation.
  547. /// </para> </summary>
  548. /// <returns>
  549. /// <para> true = The object change is relevant (default). </para>
  550. /// <para> false = The object change is irrelevant and can be ignored. </para>
  551. /// </returns>
  552. ///
  553. bool isRelevantChange() const;
  554. /// <summary>
  555. /// Dependencies can be notified about arbitrary events using the following
  556. /// method.
  557. /// </summary>
  558. ///
  559. Acad::ErrorStatus notification(AcDbAssocNotificationData* pNotifData);
  560. /// <summary> <para>
  561. /// This method returns true iff this dependency depends on exactly the
  562. /// same "thing" (such as on the same subentity of the same entity) as the
  563. /// other dependency.
  564. /// </para> <para>
  565. /// The default implementation compares the AcDbObjectIds of the
  566. /// two dependent-on objects and if they are not equal, returns false.
  567. /// Otherwise it calls the owning action's
  568. /// AcDbAssocAction::areDependenciesOnTheSameThing(), i.e. it
  569. /// delegates the decision to the action that owns the dependency. This
  570. /// delegation can be turned off by calling setIsDelegatingToOwningAction(false).
  571. /// The default implementation of AcDbAssocAction::areDependenciesOnTheSameThing(),
  572. /// or if there is no delegation, returns true.
  573. /// returns true
  574. /// </para> <para>
  575. /// If the dependency owns an AcDbAssocDependencyBody object that overrides
  576. /// the isDependentOnTheSameThingAsOverride() predicate, this predicate is
  577. /// called and it supersedes the default implementation.
  578. /// </para> </summary>
  579. /// <param name="pOtherDependency"> The other dependency needs to be open for read. </param>
  580. /// <returns>
  581. /// <para> true = Both dependencies depend on exactly the same "thing". </para>
  582. /// <para> false = They depend on different "things". </para>
  583. /// </returns>
  584. ///
  585. bool isDependentOnTheSameThingAs(const AcDbAssocDependency* pOtherDependency) const;
  586. /// <summary>
  587. /// Returns true iff the dependent on object is read-only, i.e. the object
  588. /// is not allowed to be changed. The default implementation returns true
  589. /// if the dependent-on object is an AcDbEntity on locked layer, otherwise
  590. /// it returns false.
  591. /// </summary>
  592. /// <returns> True the dependent-on object is not allowed to be changed. </returns>
  593. ///
  594. bool isDependentOnObjectReadOnly() const;
  595. /// <summary> <para>
  596. /// Compares this dependency with the given dependency and returns true if
  597. /// and only if they are equal (whatever it means). Both dependencies need
  598. /// be open at least for read.
  599. /// </para> <para>
  600. /// The default implementation does some general tests and if they turn
  601. /// out that the dependencies are not equal, it returns false. Otherwise
  602. /// it calls the owning action's AcDbAssocAction::areDependenciesEqual(),
  603. /// i.e. it delegates the decision to the action that owns the dependency.
  604. /// This delegation can be turned off by calling setIsDelegatingToOwningAction(false).
  605. /// The default implementation of AcDbAssocAction::areDependenciesEqual(),
  606. /// or if there is no delegation, returns true.
  607. /// </para> <para>
  608. /// If the dependency owns an AcDbAssocDependencyBody object that overrides
  609. /// the isEqualToOverride() predicate, this predicate is called and it
  610. /// supersedes the default implementation.
  611. /// </para> </summary>
  612. /// <param name="pOtherDependency"> The other dependency needs to be open for read. </param>
  613. /// <returns> True iff the two dependencies are equal. </returns>
  614. ///
  615. bool isEqualTo(const AcDbAssocDependency* pOtherDependency) const;
  616. /// <summary> <para>
  617. /// Predicate that returns true iff the system is currently evaluating an
  618. /// action or a network of actions.
  619. /// </para> <para>
  620. /// Notice that when action evaluation is in progress, dependency notifications
  621. /// are disabled. When an object that has dependencies attached to itself is
  622. /// changed, the dependencies ignore this notification and consequently also
  623. /// do not notify the actions owning the dependencies. This is necessary because
  624. /// otherwise if one action evaluation modified some objects, the dependencies
  625. /// on these objects would be notified and the status of other actions owning
  626. /// these dependencies would be changed, requesting the actions to be evaluated
  627. /// again. This would lead to infinite loops.
  628. /// </para> </summary>
  629. /// <returns> True iff action evaluation is in progress. </returns>
  630. ///
  631. bool isActionEvaluationInProgress() const;
  632. /// <summary>
  633. /// Returns the current AcDbAssocEvaluationCallback set by the
  634. /// AcDbAssocAction::evaluate() call, or NULL if no action evaluation
  635. /// is in progress. Notice that when action evaluation is in progress, there
  636. /// always is a non-NULL AcDbAssocEvaluationCallback.
  637. /// </summary>
  638. /// <returns> The current AcDbAssocEvaluationCallback or NULL. </returns>
  639. ///
  640. AcDbAssocEvaluationCallback* currentEvaluationCallback() const;
  641. /// <summary> <para>
  642. /// Called by the AcDbAssocAction::evaluateDependencies() to update the
  643. /// "dirty" dependencies of the action. The custom dependency classes
  644. /// can implement code to cache the dependent-on data in order to allow
  645. /// filtering-out irrelevant notifications, or do some other work.
  646. /// </para> <para>
  647. /// The evalaute() method calls AcDbAssocDependencyBody::evaluateOverride()
  648. /// to do the real work.
  649. /// </para> <para>
  650. /// If there is no owned dependency body object, the default implementation
  651. /// calls AcDbAssocAction::evaluateDependency(), i.e. it delegates the work
  652. /// to the action that owns the dependency. The default implementation of
  653. /// AcDbAssocAction::evaluateDependency() just sets the dependency status
  654. /// to kIsUpToDateAssocStatus. This delegation can be turned off by calling
  655. /// setIsDelegatingToOwningAction(false).
  656. /// </para> </summary>
  657. ///
  658. void evaluate();
  659. /// <summary> <para>
  660. /// Implementation of the persistent reactor notification callback.
  661. /// </para> <para>
  662. /// If the dependency owns an AcDbAssocDependencyBody object, its
  663. /// erasedOverride() method is called at the end of the default
  664. /// implementation.
  665. /// </para> </summary>
  666. /// <param name="dbObj"> </param>
  667. /// <param name="isErasing"> </param>
  668. ///
  669. virtual void erased(const AcDbObject* dbObj, Adesk::Boolean isErasing = true);
  670. /// <summary> <para>
  671. /// Implementation of the persistent reactor notification callback.
  672. /// </para> <para>
  673. /// If the dependency owns an AcDbAssocDependencyBody object, its
  674. /// modifiedOverride() method is called at the end of the default
  675. /// implementation.
  676. /// </para> </summary>
  677. /// <param name="dbObj"> </param>
  678. ///
  679. virtual void modified(const AcDbObject* dbObj);
  680. /// <summary> <para>
  681. /// Implementation of the persistent reactor notification callback.
  682. /// </para> <para>
  683. /// If the dependency owns an AcDbAssocDependencyBody object, its
  684. /// clonedOverride() method is called. After that the owning action's
  685. /// AcDbAssocAction::dependentObjectCloned() callback method is called
  686. /// to notify the action that an object the action depends on has been
  687. /// cloned.
  688. /// </para> </summary>
  689. /// <param name="pDbObj"> The original object. </param>
  690. /// <param name="pNewObj"> The newly created clone. </param>
  691. ///
  692. virtual void copied(const AcDbObject* pDbObj, const AcDbObject* pNewObj);
  693. private:
  694. void setPrevDependencyOnObject(const AcDbObjectId& depId);
  695. void setNextDependencyOnObject(const AcDbObjectId& depId);
  696. friend class AcDbImpAssocDependency;
  697. friend class AcDbAssocDeepCloneRxEventReactor;
  698. friend class AcDbAssocDeepCloneData;
  699. }; // class AcDbAssocDependency
  700. /// <summary>
  701. /// Allows to disable change notifications to AcDbAssocDependencies.
  702. /// </summary>
  703. ///
  704. class ACDB_PORT AcDbAssocDependencyNotificationDisabler
  705. {
  706. public:
  707. explicit AcDbAssocDependencyNotificationDisabler(bool disableIt = true);
  708. ~AcDbAssocDependencyNotificationDisabler();
  709. static bool isDisabled();
  710. private:
  711. const bool mPrev;
  712. };
  713. #pragma pack ( pop )