AcDbAssocNetwork.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. // AcDbAssocNetwork concrete class.
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #pragma once
  19. #include "AcString.h"
  20. #include "AcDbAssocAction.h"
  21. #pragma pack (push, 8)
  22. /// <summary> <para>
  23. /// The AcDbAssocNetwork class keeps a network of AcDbAssocActions. Notice that
  24. /// it is derived from AcDbAssocAction, therefore it also behaves as an individual
  25. /// AcDbAssocAction. It means as a whole network can depend on other objects via
  26. /// its AcDbAssocDependencies or be owned by a higher-level AcDbAssocNetwork,
  27. /// allowing to create hierarchical associative structures.
  28. /// </para> <para>
  29. /// The AcDbAssocDependencies between AcDbAssocActions in the AcDbAssocNetwork
  30. /// define how the actions are tied together, how they depend on objects and on
  31. /// each other. For example, if one action modifies (writes) an object and
  32. /// another action uses (reads) the object, then the second action depends on
  33. /// the first one and the second action needs to be evaluated only after the
  34. /// first action has been evaluated.
  35. /// </para> </summary>
  36. ///
  37. class ACDB_PORT AcDbAssocNetwork : public AcDbAssocAction
  38. {
  39. public:
  40. ACRX_DECLARE_MEMBERS(AcDbAssocNetwork);
  41. /// <summary> Default constructor. </summary>
  42. /// <param name="createImpObject"> See AcDbAssocCreateImpObject explanation. </param>
  43. ///
  44. explicit AcDbAssocNetwork(AcDbAssocCreateImpObject createImpObject = kAcDbAssocCreateImpObject);
  45. /// <summary>
  46. /// Returns reference to the *internal* array of AcDbObjectIds of all owned
  47. /// AcDbAssocActions. If used for anything more than just a simple iteration,
  48. /// or when there is any chance that some actions may be added/removed,
  49. /// you need to make a copy of this array FIRST, because the array may change.
  50. /// </summary>
  51. /// <returns>
  52. /// Reference to the internal array of AcDbObjectIds of the owned AcDbAssocActions.
  53. /// </returns>
  54. ///
  55. const AcDbObjectIdArray& getActions() const;
  56. /// <summary>
  57. /// Returns reference to the *internal* array of AcDbObjectIds of owned
  58. /// AcDbAssocActions whose AcDbAssocStatus indicates that they need to be
  59. /// evaluated. If used for anything more than just a simple iteration,
  60. /// or when there is any chance that some actions may be added/removed,
  61. /// you need to make a copy of this array FIRST, because the array may change.
  62. /// Even changing the status of an action may cause the action to be added
  63. /// or removed to/from the array.
  64. /// </summary>
  65. /// <returns>
  66. /// Reference to the internal array of AcDbObjectIds of the owned
  67. /// AcDbAssocActions that need to be evaluated.
  68. /// </returns>
  69. ///
  70. const AcDbObjectIdArray& getActionsToEvaluate() const;
  71. /// <summary> <para>
  72. /// Adds an AcDbAssocAction to be owned by this network. The action being
  73. /// added must not be owned by any network. Every action except for the topmost
  74. /// AcDbAssocNetwork is "logically" owned by a single AcDbAssocNetwork.
  75. /// </para> <para>
  76. /// The network becomes the "logical" owner of the action. It may also become
  77. /// the "physical" database owner of the action (the network has hard-ownership
  78. /// id of the action), but the "physical" owner may be some other object.
  79. /// For example, for networks attached to AcDbBlockTableRecords, the "logical"
  80. /// owner is the top-level network of the whole database but the "physical"
  81. /// database owner is the subdictionary of the extension dictionary of the
  82. /// AcBdBlockTableRecord.
  83. /// </para> </summary>
  84. /// <param name="actionId"> AcDbAssocAction being added to the network. </param>
  85. /// <param name="alsoSetAsDatabaseOwner"> Make this network the database owner of the action. </param>
  86. /// <returns> Acad::ErrorStatus. </returns>
  87. ///
  88. Acad::ErrorStatus addAction(const AcDbObjectId& actionId, bool alsoSetAsDatabaseOwner);
  89. /// <summary>
  90. /// Removes an AcDbAssocAction from the network and optionally erases it.
  91. /// The action being removed must be owned by this network.
  92. /// </summary>
  93. /// <param name="actionId"> AcDbAssocAction being removed from the network. </param>
  94. /// <param name="alsoEraseIt"> Erase the action after removing it. </param>
  95. /// <returns> Acad::ErrorStatus. </returns>
  96. ///
  97. Acad::ErrorStatus removeAction(const AcDbObjectId& actionId, bool alsoEraseIt);
  98. /// <summary> <para>
  99. /// Adds the given AcDbAssocActions to be owned by this network. The actions
  100. /// being added must not be owned by any network.
  101. /// </para> <para>
  102. /// The network becomes the "logical" owner of the action. It may also become
  103. /// the "physical" database owner of the actions (the network has hard-ownership
  104. /// id of the actions), but the "physical" owner may be some other object.
  105. /// For example, for networks attached to AcDbBlockTableRecords, the "logical"
  106. /// owner is the top-level network of the whole database but the "physical"
  107. /// database owner is the subdictionary of the extension dictionary of the
  108. /// AcBdBlockTableRecord.
  109. /// </para> </summary>
  110. /// <param name="actionIds"> AcDbAssocActions being added to the network. </param>
  111. /// <param name="alsoSetAsDatabaseOwner"> Make this network the database owner of the actions. </param>
  112. /// <returns> Acad::ErrorStatus. </returns>
  113. ///
  114. Acad::ErrorStatus addActions(const AcDbObjectIdArray& actionIds, bool alsoSetAsDatabaseOwner);
  115. /// <summary>
  116. /// Removes all AcDbAssocActions from the network and optionally erases them.
  117. /// The network will become empty.
  118. /// </summary>
  119. /// <param name="alsoEraseThem"> Erase the actions after removing them. </param>
  120. /// <returns> Acad::ErrorStatus. </returns>
  121. ///
  122. Acad::ErrorStatus removeAllActions(bool alsoEraseThem);
  123. /// <summary>
  124. /// This callback is called from AcDbAssocAction::setStatus(..., true)
  125. /// and notifies the network owing the action that the status of the
  126. /// action has just been changed. The action is still open for write and
  127. /// already has the new status.
  128. /// </summary>
  129. /// <param name="pOwnedAction"> The action whose status has just been changed. </param>
  130. /// <param name="previousStatus"> Previous status of the action. </param>
  131. /// <returns> Acad::ErrorStatus. </returns>
  132. ///
  133. Acad::ErrorStatus ownedActionStatusChanged(AcDbAssocAction* pOwnedAction,
  134. AcDbAssocStatus previousStatus);
  135. /// <summary> <para>
  136. /// Returns AcDbObjectId of the AcDbAssocNetwork owned by the given
  137. /// database, optionally creating a new one if it does not exist yet.
  138. /// Returns AcDbObjectId::kNull if the network cannot be obtained.
  139. /// </para> <para>
  140. /// The network is owned by a special sub-dictionary owned by the named
  141. /// object dictionary of the database.
  142. /// </para> </summary>
  143. /// <param name="pDatabase"> AcDbDatabase owning the network. </param>
  144. /// <param name="createIfDoesNotExist">
  145. /// If it does not exist yet, create a new subdictionary under the named object
  146. /// dictionary of the database. Create an AcDbAssocNetwork and make it owned
  147. /// by this newly created subdictionary.
  148. /// </param>
  149. /// <param name="dictionaryKey">
  150. /// The name of the sub-dictionary under which the network belongs.
  151. /// If no key name is given, the default "ACAD_ASSOCNETWORK" key is used.
  152. /// </param>
  153. /// <returns> AcDbObjectId of the existing or newly created AcDbAssocNetwork. </returns>
  154. ///
  155. static AcDbObjectId getInstanceFromDatabase(AcDbDatabase* pDatabase,
  156. bool createIfDoesNotExist,
  157. const AcString& dictionaryKey = _T(""));
  158. /// <summary> <para>
  159. /// Returns AcDbObjectId of the AcDbAssocNetwork owned by the extension
  160. /// dictionary of the given AcDbObject, optionally creating a new one if it
  161. /// does not exist yet. Returns AcDbObjectId::kNull if the network cannot be
  162. /// obtained.
  163. /// </para> <para>
  164. /// The network is owned by a special sub-dictionary owned by the extension
  165. /// dictionary of the given object.
  166. /// </para> </summary>
  167. /// <param name="owningObjectId">
  168. /// The AcDbObject owning the sub-dictionary that owns the AcDbAssocNetwork.
  169. /// </param>
  170. /// <param name="createIfDoesNotExist">
  171. /// If it does not exist yet, create a new subdictionary of the extension
  172. /// dictionary of the object. Create an AcDbAssocNetwork and make it owned
  173. /// by this newly created subdictionary.
  174. /// </param>
  175. /// <param name="addToTopLevelNetwork">
  176. /// If the network is newly created, it also adds it to the the top-level
  177. /// network of the database that owns the owningObjectId. It has no effect
  178. /// if the network already exists or if createIfDoesNotExist is false.
  179. /// </param>
  180. /// <param name="dictionaryKey">
  181. /// The name of the sub-dictionary under which the network belongs.
  182. /// If no key name is given, the default "ACAD_ASSOCNETWORK" key is used.
  183. /// </param>
  184. /// <returns> AcDbObjectId of the existing or newly created AcDbAssocNetwork. </returns>
  185. ///
  186. static AcDbObjectId getInstanceFromObject(const AcDbObjectId& owningObjectId,
  187. bool createIfDoesNotExist,
  188. bool addToTopLevelNetwork = true,
  189. const AcString& dictionaryKey = _T(""));
  190. /// <summary>
  191. /// Removes the network and the sub-dictionary that owns it from the extension
  192. /// dictionary of the object.
  193. /// </summary>
  194. /// <param name="owningObjectId">
  195. /// The AcDbObject whose extension dictionary owns the sub-dictionary that
  196. /// owns the AcDbAssocNetwork.
  197. /// </param>
  198. /// <param name="alsoEraseIt"> Erase the network after removing it.
  199. /// </param>
  200. /// <param name="dictionaryKey">
  201. /// The name of the sub-dictionary under which the network belongs.
  202. /// If no key name is given, the default "ACAD_ASSOCNETWORK" key is used.
  203. /// </param>
  204. /// <returns> Acad::ErrorStatus. </returns>
  205. ///
  206. static Acad::ErrorStatus removeInstanceFromObject(const AcDbObjectId& owningObjectId,
  207. bool alsoEraseIt,
  208. const AcString& dictionaryKey = _T(""));
  209. /// <summary>
  210. /// Removes the network and the sub-dictionary that owns it from the named
  211. /// object dictionary of the database.
  212. /// </summary>
  213. /// <param name="owningObjectId">
  214. /// The database whose named object dictionary owns the sub-dictionary that
  215. /// owns the AcDbAssocNetwork.
  216. /// </param>
  217. /// <param name="alsoEraseIt"> Erase the network after removing it.
  218. /// </param>
  219. /// <param name="dictionaryKey">
  220. /// The name of the sub-dictionary under which the network belongs.
  221. /// If no key name is given, the default "ACAD_ASSOCNETWORK" key is used.
  222. /// </param>
  223. /// <returns> Acad::ErrorStatus. </returns>
  224. ///
  225. static Acad::ErrorStatus removeInstanceFromDatabase(AcDbDatabase* pDatabase,
  226. bool alsoEraseIt,
  227. const AcString& dictionaryKey = _T(""));
  228. }; // class AcDbAssocNetwork
  229. /// <summary>
  230. /// A simple class to iterate over all AcDbAssocActions of an AcDbAssocNetwork.
  231. /// <code>
  232. /// AcDbSmartObjectPointer<AcDbAssocNetwork> pNetwork(assocNetworkId, AcDb::kForRead);
  233. ///
  234. /// if (!eOkVerify(pNetwork.openStatus()))
  235. /// {
  236. /// // Cannot open the network ...
  237. /// }
  238. ///
  239. /// AcDbAssocNetworkIterator iter(pNetwork);
  240. ///
  241. /// while (iter.moveNext())
  242. /// {
  243. /// const AcDbObjectId actionId = iter.current();
  244. /// AcDbSmartObjectPointer<AcDbAssocAction> pAction(actionId, AcDb::kForRead);
  245. /// // Process pAction ...
  246. /// }
  247. /// </code>
  248. /// </summary>
  249. ///
  250. class ACDB_PORT AcDbAssocNetworkIterator
  251. {
  252. public:
  253. /// <summary>
  254. /// Creates an iterator allowing to sequentially access all AcDbAssocActions
  255. /// of the given AcDbAssocNetwork. The iterator is initially positioned
  256. /// before the first action in the network. During the iteration no actions
  257. /// may be added/removed to/from the network.
  258. /// </summary>
  259. ///
  260. explicit AcDbAssocNetworkIterator(const AcDbAssocNetwork* pNetwork)
  261. : mpNetwork(pNetwork), mIndex(-1)
  262. {
  263. #ifdef ASSERT
  264. ASSERT(mpNetwork != NULL);
  265. #endif
  266. }
  267. /// <summary>
  268. /// Returns the current element the iterator is pointing to, or
  269. /// AcDbObjectId::kNull if the iteration hasn't started yet or the
  270. /// iteration is over.
  271. /// </summary>
  272. /// <returns> The current AcDbAssocAction or null. </returns>
  273. ///
  274. AcDbObjectId current() const
  275. {
  276. if (mpNetwork != NULL && 0 <= mIndex && mIndex < mpNetwork->getActions().length())
  277. {
  278. return mpNetwork->getActions()[mIndex];
  279. }
  280. else
  281. {
  282. #ifdef ASSERT
  283. ASSERT(false);
  284. #endif
  285. return AcDbObjectId::kNull;
  286. }
  287. }
  288. /// <summary>
  289. /// Advances the iterator to the next AcDbAssocAction in the network.
  290. /// </summary>
  291. /// <returns>
  292. /// Returns true if advanced to the next AcDbAssocAction, false if no more
  293. /// AcDbAssocAction in the network.
  294. /// </returns>
  295. ///
  296. bool moveNext()
  297. {
  298. return mpNetwork != NULL ? ++mIndex < mpNetwork->getActions().length() : false;
  299. }
  300. /// <summary>
  301. /// Position the iterator before the first action in the network.
  302. /// </summary>
  303. ///
  304. void reset() { mIndex = -1; }
  305. private:
  306. const AcDbAssocNetwork* const mpNetwork;
  307. int mIndex;
  308. }; // class AcDbAssocNetworkIterator
  309. #pragma pack (pop)