AcDbAssocVariable.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. //
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Copyright 2015 Autodesk, Inc. All rights reserved.
  5. //
  6. // Use of this software is subject to the terms of the Autodesk license
  7. // agreement provided at the time of installation or download, or which
  8. // otherwise accompanies this software in either electronic or hard copy form.
  9. //
  10. //////////////////////////////////////////////////////////////////////////////
  11. //
  12. // CREATED BY: Jiri Kripac April 2007
  13. //
  14. // DESCRIPTION:
  15. //
  16. // AcDbAssocVariable concrete action class.
  17. //
  18. // Also declaration of AcDbAssocVariableValueProviderPE protocol extension
  19. // class.
  20. //
  21. //////////////////////////////////////////////////////////////////////////////
  22. #pragma once
  23. #include "AcDbAssocValueProviderPE.h"
  24. #include "AcDbAssocAction.h"
  25. #pragma pack (push, 8)
  26. ACDB_PORT AcString& dummyString();
  27. /// <summary> <para>
  28. /// AcDbAssocVariable keeps a name, value and expression. The name is an arbitrary
  29. /// non-empty string but the client code sets rules that define valid variable names.
  30. /// </para> <para>
  31. /// The expression is optional and is in the form of a string. An evaluator
  32. /// id needs to be provided with each espression. It specifies which expression
  33. /// evaluator should be used to parse the expression. The expression can reference
  34. /// other objects that provide values, such as it can reference other variables.
  35. /// The AcDbAssocVariable then owns AcDbAssocValueDependencies on these referenced
  36. /// objects. If the expression string is empty, or if the expression string does
  37. /// not reference other objects, the variable is a constant.
  38. /// </para> <para>
  39. /// The variable value is a scalar value such as a double, int, point, or a string.
  40. /// Currently only these four value types are supported.
  41. /// </para> <para>
  42. /// AcDbAssocVariable exposes AcDbAssocVariableValueProviderPE protocol extension
  43. /// that is used by other variables and generally by other actions that own
  44. /// AcDbAssocValueDependencies to obtain the value of the variable.
  45. /// </para> <para>
  46. /// The evaluate() method of the variable evaluates the expression using the
  47. /// current values of the referenced symbols and sets the evaluated value.
  48. /// </para> </summary>
  49. ///
  50. class ACDB_PORT AcDbAssocVariable : public AcDbAssocAction
  51. {
  52. public:
  53. ACRX_DECLARE_MEMBERS(AcDbAssocVariable);
  54. /// <summary> Default constructor. </summary>
  55. /// <param name="createImpObject"> See AcDbAssocCreateImpObject. </param>
  56. ///
  57. explicit AcDbAssocVariable(AcDbAssocCreateImpObject createImpObject = kAcDbAssocCreateImpObject);
  58. /// <summary> Returns the variable name which is an arbitrary string. </summary>
  59. /// <returns> The name of this variable. </returns>
  60. ///
  61. const AcString& name() const;
  62. /// <summary> Returns the expression or an empty string if the variable is a constant. </summary>
  63. /// <returns> The expression or an empty string. </returns>
  64. ///
  65. const AcString& expression() const;
  66. const AcString& expression(bool convertSymbolNamesFromCanonicalForm) const;
  67. /// <summary> Returns the evaluated and cached value of the variable. </summary>
  68. /// <returns> The value of the variable. </returns>
  69. ///
  70. const AcDbEvalVariant& value() const;
  71. /// <summary>
  72. /// Returns description of the variable which is an arbitrary string. It does
  73. /// not have any additional meaning and does not affect the expression
  74. /// evaluation in any way.
  75. /// </summary>
  76. /// <returns> The description or an empty string. </returns>
  77. ///
  78. const AcString& description() const;
  79. /// <summary> <para>
  80. /// Sets the name of the variable. It does not verify the name.
  81. /// </para> <para>
  82. /// If the updateReferencingExpressions argument is true, it also finds
  83. /// all expressions referencing this variable and changes them (changes
  84. /// their strings) to reflect the new name of the variable.
  85. /// </para> </summary>
  86. /// <param name="newName"> New name of the variable. </param>
  87. /// <param name="updateReferencingExpressions">
  88. /// If true, it finds all expressions referencing this variable and changes
  89. /// them (changes their strings) to reflect the new name of the variable.
  90. /// </param>
  91. /// <returns> Acad::ErrorStatus. </returns>
  92. ///
  93. Acad::ErrorStatus setName(const AcString& newName, bool updateReferencingExpressions);
  94. /// <summary>
  95. /// Anonymous variable has name that is either empty or starts with "*".
  96. /// Anonymous variables are not shown in the PARAMETERS manager. They are
  97. /// used internally when there is a need to keep an expression (such as when
  98. /// a parameter of an action can be defined by an expression that may reference
  99. /// other variables), but there is no need to reference this expression from
  100. /// any other object besides the "owner" of the expression (such as the action
  101. /// whose parameter can be defined by an expression). The "owner" of the
  102. /// anonymous variable is responsible for its management, such as requesting
  103. /// it to be cloned when the "owner" is cloned, erasing the anonymous variable
  104. /// when the "owner" is erased, etc.
  105. /// </summary>
  106. /// <returns> Returns true if the variable is anonymous. </returns>
  107. ///
  108. bool isAnonymous() const;
  109. /// <summary>
  110. /// Using this AcDbAssocVariable as the starting context, searches for an
  111. /// object with the given name. The initial implementation just searches
  112. /// the AcDbAssocNetwork owning this variable, but later we may add more
  113. /// sophisticated searches, such as cross-network references, nested-network
  114. /// references, global references, etc.
  115. /// </summary>
  116. /// <remarks>
  117. /// Currently the only named objects are AcDbAssocVariables, but there may
  118. /// be more object types in the future. We may also in the future promote
  119. /// this method to the base AcDbAssocAction class if we find more cases of
  120. /// named objects.
  121. /// </remarks>
  122. /// <param name="objectName"> The name of the searched-for object. </param>
  123. /// <param name="pObjectClass"> The class of the searched-for object (isKindOf() test is used). </param>
  124. /// <returns> AcDbObjectId of the found object or null AcDbObjectId if no object found. </returns>
  125. ///
  126. AcDbObjectId findObjectByName(const AcString& objectName,
  127. const AcRxClass* pObjectClass) const;
  128. /// <summary> <para>
  129. /// Validates the given nameToValidate, expressionToValidate or both, to see
  130. /// whether they can be used as name and/or expression for this variable.
  131. /// If either string is empty, it is not validated and is assumed that the
  132. /// name and/or expression of this variable is not going to change.
  133. /// </para> <para>
  134. /// For nameToValidate it checks if it is a valid identifier and checks that
  135. /// nameToValidate is not used as name of some other variable in the same
  136. /// network as this variable belongs to.
  137. /// </para> <para>
  138. /// For expressionToValidate it performs syntactic checks of the expression,
  139. /// including checks for references to undefined symbols and for cyclic
  140. /// dependencies between symbols, but it does not evaluate the expression.
  141. /// </para> <para>
  142. /// If these common checks pass, it calls AcDbAssocVariableCallback::validateNameAndExpression()
  143. /// so that the client code can perform additional validation, such as that
  144. /// a variable name is used as dimensional constraint name in no more than
  145. /// one dimensional constraint.
  146. /// </para> </summary>
  147. /// <param name="nameToValidate"> The variable name to validate. May be null. </param>
  148. /// <param name="expressionToValidate"> The variable expression to validate. May be null. </param>
  149. /// <param name="errorMessage"> Error string if the name or expression is not valid, empty otherwise. </param>
  150. /// <returns>
  151. /// Returns Acad::eOk if the name and/or expression can be set to this variable.
  152. /// Otherwise it returns an ErrorStatus and errorMessage that explain the error.
  153. /// </returns>
  154. ///
  155. Acad::ErrorStatus validateNameAndExpression(const AcString& nameToValidate,
  156. const AcString& expressionToValidate,
  157. AcString& errorMessage) const;
  158. /// <summary>
  159. /// Sets the expression (may be an empty string if no expression).
  160. /// The expression is syntactically checked but not evaluated.
  161. /// </summary>
  162. /// <param name="newExpression"> New expression or an empty string. </param>
  163. /// <param name="evaluatorId"> String identifier of expression evaluator.
  164. /// If empty, the default evaluator for current acad version will be used.
  165. /// </param>
  166. /// <param name="checkForCyclicalDependencies">
  167. /// Checks that this variable is not referenced, either directly or indirectly,
  168. /// by the new expression. If it is referenced, it means there is a cyclical
  169. /// dependency between the variables.
  170. /// </param>
  171. /// <param name="updateDependenciesOnReferencedSymbols">
  172. /// If true, it erases all existing AcDbAssocValueDependencies on the
  173. /// symbols referenced by the previous expression and sets up new
  174. /// AcDbAssocValueDependencies on the symbols referenced by the new
  175. /// expression.
  176. /// <param name="errorMessage"> Error string if expression is syntactically invalid. </param>
  177. /// </param>
  178. /// <param name="silentMode"> Does not print a message when the expression is invalid. </param>
  179. /// <returns> Acad::ErrorStatus. </returns>
  180. ///
  181. Acad::ErrorStatus setExpression(const AcString& newExpression,
  182. const AcString& evaluatorId,
  183. bool checkForCyclicalDependencies,
  184. bool updateDependenciesOnReferencedSymbols,
  185. AcString& errorMessage = dummyString(),
  186. bool silentMode = false);
  187. /// <summary>
  188. /// Returns id of the expression evaluator that is used to parse the expression.
  189. /// </summary>
  190. /// <returns> Id of the expression evaluator that is used to parse the expression. </returns>
  191. ///
  192. const AcString& evaluatorId() const;
  193. /// <summary>
  194. /// Sets id of the expression evaluator that is going to be used to parse
  195. /// the expression. An empty string means the default evaluator.
  196. /// </summary>
  197. /// <para name="evalId"> Id of the expression evauator. </para>
  198. /// <returns> Acad::ErrorStatus. </returns>
  199. ///
  200. Acad::ErrorStatus setEvaluatorId(const AcString& evalId);
  201. /// <summary>
  202. /// Sets the evaluated value. Notice that if the expression is not empty,
  203. /// this value will be overwritten the next time the expression is
  204. /// evaluated.
  205. /// </summary>
  206. /// <param name="newValue"> New evaluated value. </param>
  207. /// <returns> Acad::ErrorStatus. </returns>
  208. ///
  209. Acad::ErrorStatus setValue(const AcDbEvalVariant& newValue);
  210. /// <summary>
  211. /// Sets description to the variable. Variable description is just an
  212. /// optional text that does not affect the expression evaluation in any way.
  213. /// </summary>
  214. /// <param name="newDescription"> New description to be set. </param>
  215. /// <returns> Acad::ErrorStatus. </returns>
  216. ///
  217. Acad::ErrorStatus setDescription(const AcString& newDescription);
  218. // These methods are currently intended for internal use only
  219. //
  220. bool isMergeable () const;
  221. bool mustMerge () const;
  222. AcString mergeableVariableName() const;
  223. void setIsMergeable(bool isMerg, bool mustMerg = false, const AcString& mergeableVariableName = AcString());
  224. /// <summary> <para>
  225. /// A helper method allowing to evaluate the expression at any time without
  226. /// modifying the variable. It is a read-only method.
  227. /// </para> <para>
  228. /// Evaluates the expression based on the current values of the referenced
  229. /// symbols and returns it in evaluatedExpressionValue. If there is no
  230. /// expression, the stored value is returned. It does not change the stored
  231. /// value, neither it changes the status of the variable.
  232. /// </para> </summary>
  233. /// <param name="evaluatedExpressionValue"> Returned evaluated value of the expression. </param>
  234. /// <param name="errorMessage"> Error string if expression evaluation has failed. </param>
  235. /// <returns> Acad::ErrorStatus. </returns>
  236. ///
  237. Acad::ErrorStatus evaluateExpression(AcDbEvalVariant& evaluatedExpressionValue,
  238. AcString& errorMessage = dummyString()) const;
  239. /// <summary> <para>
  240. /// A helper method allowing to evaluate the expression at any time without
  241. /// modifying the variable and by explicitly providing values of the referenced
  242. /// objects (variables). It is a read-only method, it does not change the value
  243. /// of this or other variables, neither it changes the status of any variables.
  244. /// </para> <para>
  245. /// Evaluates the expression based on the provided values of the referenced
  246. /// objects. The objectIds array is an array of ids of value-providing objects
  247. /// (such as AcDbAssocVariables) and objectValues is an array of provided
  248. /// values of these objects. These arrays have the same lengths.
  249. /// </para> <para>
  250. /// If the id of this variable is already in objectIds array, the corresponding
  251. /// value from objectValues is returned. Otherwise it evaluates the expression
  252. /// of this variable. Anytime is comes across a symbol referenced by the
  253. /// expression, it checks the objectIds array to see if the value of the object
  254. /// is already known. If yes, it uses this value, otherwise expects that the
  255. /// object is an AcDbAssocVariable, obtains its value by recursively calling
  256. /// this method, and uses the returned value. After the value of a variable has
  257. /// been obtained, the variable id and the just obtained value are added to
  258. /// objectIds and objectValues arrays, so that if the same variable is encountered
  259. /// again, its value is used and not evaluated again.
  260. /// </para> <para>
  261. /// This method does not change the value of this or any other variable, neither
  262. /// it changes the status of any variable. It does however append id-value
  263. /// pairs to the objectIds and objectValues arrays which are in/out arguments.
  264. /// </para> </summary>
  265. /// <param name="objectIds">
  266. /// Array of ids of value-providing objects. It is an in/out argument. It is
  267. /// being appended during the evaluation with ids of the value-providing objects
  268. /// whose values have been obtained (currently these objects are only
  269. /// AcDbAssocVariables).
  270. /// </param>
  271. /// <param name="objectValues">
  272. /// Array of values of value-providing objects. It is an in/out argument. It is
  273. /// being appended during the evaluation with values of the value-providing objects
  274. /// whose values have been obtained (currently these objects are only
  275. /// AcDbAssocVariables).
  276. /// </param>
  277. /// <param name="evaluatedExpressionValue"> Returned evaluated value of the expression. </param>
  278. /// <param name="errorMessage"> Error string if expression evaluation has failed. </param>
  279. /// <returns> Acad::ErrorStatus. </returns>
  280. ///
  281. Acad::ErrorStatus evaluateExpression(AcDbObjectIdArray& objectIds, // in/out argument
  282. AcArray<AcDbEvalVariant>& objectValues, // in/out argument
  283. AcDbEvalVariant& evaluatedExpressionValue,
  284. AcString& errorMessage = dummyString()) const;
  285. /// <summary>
  286. /// Evaluates the given expression in the context of the given AcDbAssocNetwork.
  287. /// </summary>
  288. static Acad::ErrorStatus evaluateExpression(const AcString& expression,
  289. const AcString& evaluatorId,
  290. const AcDbObjectId& networkId, // Provides context for the names
  291. AcDbEvalVariant& evaluatedExpressionValue,
  292. AcString& assignedToSymbolName,
  293. AcString& errorMessage = dummyString());
  294. /// <summary>
  295. /// See the explanation of AcDbAssocVariableCallback. Multiple global callbacks
  296. /// can be registered and they apply to all AcDbAssocVariables.
  297. /// </summary>
  298. /// <param name="pCallback"> The callback to be registered. </param>
  299. ///
  300. static void addGlobalCallback(class AcDbAssocVariableCallback* pCallback);
  301. /// <summary>
  302. /// See the explanation of AcDbAssocVariableCallback. Multiple global callbacks
  303. /// can be registered and they apply to all AcDbAssocVariables.
  304. /// </summary>
  305. /// <param name="pCallback"> The callback to be unregistered. </param>
  306. ///
  307. static void removeGlobalCallback(class AcDbAssocVariableCallback* pCallback);
  308. /// <summary>
  309. /// Returns a callback that is the collection of all callbacks registered by
  310. /// client code. This function is meant mostly for private use and there should
  311. /// not be much need for the client code to use it. Anyway, the client code
  312. /// must never delete or unregister the returned callback, or do anything with
  313. /// it except for calling its methods.
  314. /// </summary>
  315. /// <returns>
  316. /// The global AcDbAssocVariable(Multi)Callback that keeps all the callbacks
  317. /// registered by the client code. The returned pointer is never null.
  318. /// </returns>
  319. ///
  320. static class AcDbAssocVariableCallback* globalCallback();
  321. }; // class AcDbAssocVariable
  322. /// <summary>
  323. /// Client code can register callback(s) derived from AcDbAssocVariableCallback
  324. /// that are then called when some events happen with AcDbAssocVariables.
  325. /// </summary>
  326. ///
  327. class AcDbAssocVariableCallback
  328. {
  329. public:
  330. AcDbAssocVariableCallback() {}
  331. virtual ~AcDbAssocVariableCallback() {}
  332. /// <summary>
  333. /// Allows client code to veto erasing a variable when the variable would
  334. /// be erased because the dimensional constraint that uses the variable is
  335. /// erased and the variable is no more referenced.
  336. /// </summary>
  337. /// <param name="pVariable"> The AcDbAssocVariable that is to be erased. </param>
  338. /// <returns>
  339. /// true == client code allows the variable to be erased. false == client code
  340. /// vetoes the variable erase.
  341. ///</returns>
  342. ///
  343. virtual bool canBeErased(const AcDbAssocVariable* pVariable) = NULL;
  344. /// <summary>
  345. /// Called from AcDbAssocVariable::validateNameAndExpression(). It lets the
  346. /// client code perform additional checks to decide if a given name and/or
  347. /// expression are allowed to be used as a name and/or expression for the
  348. /// given variable.
  349. /// </summary>
  350. /// <param name="pVariable"> The variable whose name and/or expression are being validated. </param>
  351. /// <param name="nameToValidate"> The variable name to validate. May be null. </param>
  352. /// <param name="expressionToValidate"> The variable expression to validate. May be null. </param>
  353. /// <param name="errorMessage"> Error string if the name or expression is not valid, empty otherwise. </param>
  354. /// <returns>
  355. /// Returns Acad::eOk if the name and/or expression can be set to this variable.
  356. /// Otherwise it returns an ErrorStatus and errorMessage that explain the error.
  357. /// </returns>
  358. ///
  359. virtual Acad::ErrorStatus validateNameAndExpression(const AcDbAssocVariable* pVariable,
  360. const AcString& nameToValidate,
  361. const AcString& expressionToValidate,
  362. AcString& errorMessage) = NULL;
  363. };
  364. #pragma pack (pop)
  365. ACDB_PORT void stringDefaultArgumentTest(AcString& str = dummyString());