PageRenderTime 32ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llxuixml/llinitparam.h

https://bitbucket.org/lindenlab/viewer-beta/
C Header | 2294 lines | 1788 code | 355 blank | 151 comment | 159 complexity | 7b571de92f32ce2e0ecf79e16a2c9acc MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llinitparam.h
  3. * @brief parameter block abstraction for creating complex objects and
  4. * parsing construction parameters from xml and LLSD
  5. *
  6. * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #ifndef LL_LLPARAM_H
  28. #define LL_LLPARAM_H
  29. #include <vector>
  30. #include <boost/function.hpp>
  31. #include <boost/type_traits/is_convertible.hpp>
  32. #include <boost/unordered_map.hpp>
  33. #include <boost/shared_ptr.hpp>
  34. #include "llerror.h"
  35. namespace LLInitParam
  36. {
  37. // used to indicate no matching value to a given name when parsing
  38. struct Flag{};
  39. template<typename T> const T& defaultValue() { static T value; return value; }
  40. template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
  41. struct ParamCompare
  42. {
  43. static bool equals(const T &a, const T &b)
  44. {
  45. return a == b;
  46. }
  47. };
  48. // boost function types are not comparable
  49. template<typename T>
  50. struct ParamCompare<T, true>
  51. {
  52. static bool equals(const T&a, const T &b)
  53. {
  54. return false;
  55. }
  56. };
  57. template<>
  58. struct ParamCompare<LLSD, false>
  59. {
  60. static bool equals(const LLSD &a, const LLSD &b) { return false; }
  61. };
  62. template<>
  63. struct ParamCompare<Flag, false>
  64. {
  65. static bool equals(const Flag& a, const Flag& b) { return false; }
  66. };
  67. // helper functions and classes
  68. typedef ptrdiff_t param_handle_t;
  69. // empty default implementation of key cache
  70. // leverages empty base class optimization
  71. template <typename T>
  72. class TypeValues
  73. {
  74. private:
  75. struct Inaccessable{};
  76. public:
  77. typedef std::map<std::string, T> value_name_map_t;
  78. typedef Inaccessable name_t;
  79. void setValueName(const std::string& key) {}
  80. std::string getValueName() const { return ""; }
  81. std::string calcValueName(const T& value) const { return ""; }
  82. void clearValueName() const {}
  83. static bool getValueFromName(const std::string& name, T& value)
  84. {
  85. return false;
  86. }
  87. static bool valueNamesExist()
  88. {
  89. return false;
  90. }
  91. static std::vector<std::string>* getPossibleValues()
  92. {
  93. return NULL;
  94. }
  95. static value_name_map_t* getValueNames() {return NULL;}
  96. };
  97. template <typename T, typename DERIVED_TYPE = TypeValues<T> >
  98. class TypeValuesHelper
  99. {
  100. public:
  101. typedef typename std::map<std::string, T> value_name_map_t;
  102. typedef std::string name_t;
  103. //TODO: cache key by index to save on param block size
  104. void setValueName(const std::string& value_name)
  105. {
  106. mValueName = value_name;
  107. }
  108. std::string getValueName() const
  109. {
  110. return mValueName;
  111. }
  112. std::string calcValueName(const T& value) const
  113. {
  114. value_name_map_t* map = getValueNames();
  115. for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
  116. it != end_it;
  117. ++it)
  118. {
  119. if (ParamCompare<T>::equals(it->second, value))
  120. {
  121. return it->first;
  122. }
  123. }
  124. return "";
  125. }
  126. void clearValueName() const
  127. {
  128. mValueName.clear();
  129. }
  130. static bool getValueFromName(const std::string& name, T& value)
  131. {
  132. value_name_map_t* map = getValueNames();
  133. typename value_name_map_t::iterator found_it = map->find(name);
  134. if (found_it == map->end()) return false;
  135. value = found_it->second;
  136. return true;
  137. }
  138. static bool valueNamesExist()
  139. {
  140. return !getValueNames()->empty();
  141. }
  142. static value_name_map_t* getValueNames()
  143. {
  144. static value_name_map_t sMap;
  145. static bool sInitialized = false;
  146. if (!sInitialized)
  147. {
  148. sInitialized = true;
  149. DERIVED_TYPE::declareValues();
  150. }
  151. return &sMap;
  152. }
  153. static std::vector<std::string>* getPossibleValues()
  154. {
  155. static std::vector<std::string> sValues;
  156. value_name_map_t* map = getValueNames();
  157. for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
  158. it != end_it;
  159. ++it)
  160. {
  161. sValues.push_back(it->first);
  162. }
  163. return &sValues;
  164. }
  165. static void declare(const std::string& name, const T& value)
  166. {
  167. (*getValueNames())[name] = value;
  168. }
  169. protected:
  170. static void getName(const std::string& name, const T& value)
  171. {}
  172. mutable std::string mValueName;
  173. };
  174. class Parser
  175. {
  176. LOG_CLASS(Parser);
  177. public:
  178. struct CompareTypeID
  179. {
  180. bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
  181. {
  182. return lhs->before(*rhs);
  183. }
  184. };
  185. typedef std::vector<std::pair<std::string, bool> > name_stack_t;
  186. typedef std::pair<name_stack_t::iterator, name_stack_t::iterator> name_stack_range_t;
  187. typedef std::vector<std::string> possible_values_t;
  188. typedef bool (*parser_read_func_t)(Parser& parser, void* output);
  189. typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
  190. typedef boost::function<void (name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
  191. typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
  192. typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
  193. typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
  194. Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
  195. : mParseSilently(false),
  196. mParserReadFuncs(&read_map),
  197. mParserWriteFuncs(&write_map),
  198. mParserInspectFuncs(&inspect_map)
  199. {}
  200. virtual ~Parser();
  201. template <typename T> bool readValue(T& param)
  202. {
  203. parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
  204. if (found_it != mParserReadFuncs->end())
  205. {
  206. return found_it->second(*this, (void*)&param);
  207. }
  208. return false;
  209. }
  210. template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
  211. {
  212. parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
  213. if (found_it != mParserWriteFuncs->end())
  214. {
  215. return found_it->second(*this, (const void*)&param, name_stack);
  216. }
  217. return false;
  218. }
  219. // dispatch inspection to registered inspection functions, for each parameter in a param block
  220. template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
  221. {
  222. parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
  223. if (found_it != mParserInspectFuncs->end())
  224. {
  225. found_it->second(name_stack, min_count, max_count, possible_values);
  226. return true;
  227. }
  228. return false;
  229. }
  230. virtual std::string getCurrentElementName() = 0;
  231. virtual void parserWarning(const std::string& message);
  232. virtual void parserError(const std::string& message);
  233. void setParseSilently(bool silent) { mParseSilently = silent; }
  234. protected:
  235. template <typename T>
  236. void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
  237. {
  238. mParserReadFuncs->insert(std::make_pair(&typeid(T), read_func));
  239. mParserWriteFuncs->insert(std::make_pair(&typeid(T), write_func));
  240. }
  241. template <typename T>
  242. void registerInspectFunc(parser_inspect_func_t inspect_func)
  243. {
  244. mParserInspectFuncs->insert(std::make_pair(&typeid(T), inspect_func));
  245. }
  246. bool mParseSilently;
  247. private:
  248. parser_read_func_map_t* mParserReadFuncs;
  249. parser_write_func_map_t* mParserWriteFuncs;
  250. parser_inspect_func_map_t* mParserInspectFuncs;
  251. };
  252. class Param;
  253. // various callbacks and constraints associated with an individual param
  254. struct ParamDescriptor
  255. {
  256. struct UserData
  257. {
  258. virtual ~UserData() {}
  259. };
  260. typedef bool(*merge_func_t)(Param&, const Param&, bool);
  261. typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
  262. typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
  263. typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
  264. typedef bool(*validation_func_t)(const Param*);
  265. ParamDescriptor(param_handle_t p,
  266. merge_func_t merge_func,
  267. deserialize_func_t deserialize_func,
  268. serialize_func_t serialize_func,
  269. validation_func_t validation_func,
  270. inspect_func_t inspect_func,
  271. S32 min_count,
  272. S32 max_count);
  273. ParamDescriptor();
  274. ~ParamDescriptor();
  275. param_handle_t mParamHandle;
  276. merge_func_t mMergeFunc;
  277. deserialize_func_t mDeserializeFunc;
  278. serialize_func_t mSerializeFunc;
  279. inspect_func_t mInspectFunc;
  280. validation_func_t mValidationFunc;
  281. S32 mMinCount;
  282. S32 mMaxCount;
  283. S32 mNumRefs;
  284. UserData* mUserData;
  285. };
  286. typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr;
  287. // each derived Block class keeps a static data structure maintaining offsets to various params
  288. class BlockDescriptor
  289. {
  290. public:
  291. BlockDescriptor();
  292. typedef enum e_initialization_state
  293. {
  294. UNINITIALIZED,
  295. INITIALIZING,
  296. INITIALIZED
  297. } EInitializationState;
  298. void aggregateBlockData(BlockDescriptor& src_block_data);
  299. typedef boost::unordered_map<const std::string, ParamDescriptorPtr> param_map_t;
  300. typedef std::vector<ParamDescriptorPtr> param_list_t;
  301. typedef std::list<ParamDescriptorPtr> all_params_list_t;
  302. typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
  303. param_map_t mNamedParams; // parameters with associated names
  304. param_list_t mUnnamedParams; // parameters with_out_ associated names
  305. param_validation_list_t mValidationList; // parameters that must be validated
  306. all_params_list_t mAllParams; // all parameters, owns descriptors
  307. size_t mMaxParamOffset;
  308. EInitializationState mInitializationState; // whether or not static block data has been initialized
  309. class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
  310. };
  311. class BaseBlock
  312. {
  313. public:
  314. //TODO: implement in terms of owned_ptr
  315. template<typename T>
  316. class Lazy
  317. {
  318. public:
  319. Lazy()
  320. : mPtr(NULL)
  321. {}
  322. ~Lazy()
  323. {
  324. delete mPtr;
  325. }
  326. Lazy(const Lazy& other)
  327. {
  328. if (other.mPtr)
  329. {
  330. mPtr = new T(*other.mPtr);
  331. }
  332. else
  333. {
  334. mPtr = NULL;
  335. }
  336. }
  337. Lazy<T>& operator = (const Lazy<T>& other)
  338. {
  339. if (other.mPtr)
  340. {
  341. mPtr = new T(*other.mPtr);
  342. }
  343. else
  344. {
  345. mPtr = NULL;
  346. }
  347. return *this;
  348. }
  349. bool empty() const
  350. {
  351. return mPtr == NULL;
  352. }
  353. void set(const T& other)
  354. {
  355. delete mPtr;
  356. mPtr = new T(other);
  357. }
  358. const T& get() const
  359. {
  360. return ensureInstance();
  361. }
  362. T& get()
  363. {
  364. return ensureInstance();
  365. }
  366. private:
  367. // lazily allocate an instance of T
  368. T* ensureInstance() const
  369. {
  370. if (mPtr == NULL)
  371. {
  372. mPtr = new T();
  373. }
  374. return mPtr;
  375. }
  376. private:
  377. // if you get a compilation error with this, that means you are using a forward declared struct for T
  378. // unfortunately, the type traits we rely on don't work with forward declared typed
  379. //static const int dummy = sizeof(T);
  380. mutable T* mPtr;
  381. };
  382. // "Multiple" constraint types, put here in root class to avoid ambiguity during use
  383. struct AnyAmount
  384. {
  385. enum { minCount = 0 };
  386. enum { maxCount = U32_MAX };
  387. };
  388. template<U32 MIN_AMOUNT>
  389. struct AtLeast
  390. {
  391. enum { minCount = MIN_AMOUNT };
  392. enum { maxCount = U32_MAX };
  393. };
  394. template<U32 MAX_AMOUNT>
  395. struct AtMost
  396. {
  397. enum { minCount = 0 };
  398. enum { maxCount = MAX_AMOUNT };
  399. };
  400. template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
  401. struct Between
  402. {
  403. enum { minCount = MIN_AMOUNT };
  404. enum { maxCount = MAX_AMOUNT };
  405. };
  406. template<U32 EXACT_COUNT>
  407. struct Exactly
  408. {
  409. enum { minCount = EXACT_COUNT };
  410. enum { maxCount = EXACT_COUNT };
  411. };
  412. // this typedef identifies derived classes as being blocks
  413. typedef void baseblock_base_class_t;
  414. LOG_CLASS(BaseBlock);
  415. friend class Param;
  416. virtual ~BaseBlock() {}
  417. bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
  418. param_handle_t getHandleFromParam(const Param* param) const;
  419. bool validateBlock(bool emit_errors = true) const;
  420. Param* getParamFromHandle(const param_handle_t param_handle)
  421. {
  422. if (param_handle == 0) return NULL;
  423. U8* baseblock_address = reinterpret_cast<U8*>(this);
  424. return reinterpret_cast<Param*>(baseblock_address + param_handle);
  425. }
  426. const Param* getParamFromHandle(const param_handle_t param_handle) const
  427. {
  428. const U8* baseblock_address = reinterpret_cast<const U8*>(this);
  429. return reinterpret_cast<const Param*>(baseblock_address + param_handle);
  430. }
  431. void addSynonym(Param& param, const std::string& synonym);
  432. // Blocks can override this to do custom tracking of changes
  433. virtual void paramChanged(const Param& changed_param, bool user_provided) {}
  434. bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
  435. void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
  436. bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
  437. virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
  438. virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
  439. // take all provided params from other and apply to self
  440. bool overwriteFrom(const BaseBlock& other)
  441. {
  442. return false;
  443. }
  444. // take all provided params that are not already provided, and apply to self
  445. bool fillFrom(const BaseBlock& other)
  446. {
  447. return false;
  448. }
  449. static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
  450. ParamDescriptorPtr findParamDescriptor(const Param& param);
  451. protected:
  452. void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
  453. bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
  454. {
  455. return mergeBlock(block_data, source, overwrite);
  456. }
  457. // take all provided params from other and apply to self
  458. bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
  459. static BlockDescriptor& selfBlockDescriptor()
  460. {
  461. static BlockDescriptor sBlockDescriptor;
  462. return sBlockDescriptor;
  463. }
  464. private:
  465. const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
  466. };
  467. template<typename T>
  468. struct ParamCompare<BaseBlock::Lazy<T>, false >
  469. {
  470. static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
  471. };
  472. class Param
  473. {
  474. public:
  475. void setProvided(bool is_provided = true)
  476. {
  477. mIsProvided = is_provided;
  478. enclosingBlock().paramChanged(*this, is_provided);
  479. }
  480. Param& operator =(const Param& other)
  481. {
  482. mIsProvided = other.mIsProvided;
  483. // don't change mEnclosingblockoffset
  484. return *this;
  485. }
  486. protected:
  487. bool anyProvided() const { return mIsProvided; }
  488. Param(BaseBlock* enclosing_block);
  489. // store pointer to enclosing block as offset to reduce space and allow for quick copying
  490. BaseBlock& enclosingBlock() const
  491. {
  492. const U8* my_addr = reinterpret_cast<const U8*>(this);
  493. // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
  494. return *const_cast<BaseBlock*>
  495. (reinterpret_cast<const BaseBlock*>
  496. (my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
  497. }
  498. private:
  499. friend class BaseBlock;
  500. U32 mEnclosingBlockOffset:31;
  501. U32 mIsProvided:1;
  502. };
  503. // these templates allow us to distinguish between template parameters
  504. // that derive from BaseBlock and those that don't
  505. template<typename T, typename Void = void>
  506. struct IsBlock
  507. {
  508. static const bool value = false;
  509. struct EmptyBase {};
  510. typedef EmptyBase base_class_t;
  511. };
  512. template<typename T>
  513. struct IsBlock<T, typename T::baseblock_base_class_t>
  514. {
  515. static const bool value = true;
  516. typedef BaseBlock base_class_t;
  517. };
  518. template<typename T>
  519. struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
  520. {
  521. static const bool value = true;
  522. typedef BaseBlock base_class_t;
  523. };
  524. template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
  525. class ParamValue : public NAME_VALUE_LOOKUP
  526. {
  527. public:
  528. typedef const T& value_assignment_t;
  529. typedef T value_t;
  530. typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK> self_t;
  531. ParamValue(): mValue() {}
  532. ParamValue(value_assignment_t other) : mValue(other) {}
  533. void setValue(value_assignment_t val)
  534. {
  535. mValue = val;
  536. }
  537. value_assignment_t getValue() const
  538. {
  539. return mValue;
  540. }
  541. T& getValue()
  542. {
  543. return mValue;
  544. }
  545. operator value_assignment_t() const
  546. {
  547. return mValue;
  548. }
  549. value_assignment_t operator()() const
  550. {
  551. return mValue;
  552. }
  553. void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
  554. {
  555. *this = name;
  556. }
  557. self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
  558. {
  559. if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
  560. {
  561. setValueName(name);
  562. }
  563. return *this;
  564. }
  565. protected:
  566. T mValue;
  567. };
  568. template<typename T, typename NAME_VALUE_LOOKUP>
  569. class ParamValue<T, NAME_VALUE_LOOKUP, true>
  570. : public T,
  571. public NAME_VALUE_LOOKUP
  572. {
  573. public:
  574. typedef const T& value_assignment_t;
  575. typedef T value_t;
  576. typedef ParamValue<T, NAME_VALUE_LOOKUP, true> self_t;
  577. ParamValue()
  578. : T(),
  579. mValidated(false)
  580. {}
  581. ParamValue(value_assignment_t other)
  582. : T(other),
  583. mValidated(false)
  584. {}
  585. void setValue(value_assignment_t val)
  586. {
  587. *this = val;
  588. }
  589. value_assignment_t getValue() const
  590. {
  591. return *this;
  592. }
  593. T& getValue()
  594. {
  595. return *this;
  596. }
  597. operator value_assignment_t() const
  598. {
  599. return *this;
  600. }
  601. value_assignment_t operator()() const
  602. {
  603. return *this;
  604. }
  605. void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
  606. {
  607. *this = name;
  608. }
  609. self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
  610. {
  611. if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
  612. {
  613. setValueName(name);
  614. }
  615. return *this;
  616. }
  617. protected:
  618. mutable bool mValidated; // lazy validation flag
  619. };
  620. template<typename NAME_VALUE_LOOKUP>
  621. class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
  622. : public NAME_VALUE_LOOKUP
  623. {
  624. public:
  625. typedef const std::string& value_assignment_t;
  626. typedef std::string value_t;
  627. typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false> self_t;
  628. ParamValue(): mValue() {}
  629. ParamValue(value_assignment_t other) : mValue(other) {}
  630. void setValue(value_assignment_t val)
  631. {
  632. if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
  633. {
  634. NAME_VALUE_LOOKUP::setValueName(val);
  635. }
  636. else
  637. {
  638. mValue = val;
  639. }
  640. }
  641. value_assignment_t getValue() const
  642. {
  643. return mValue;
  644. }
  645. std::string& getValue()
  646. {
  647. return mValue;
  648. }
  649. operator value_assignment_t() const
  650. {
  651. return mValue;
  652. }
  653. value_assignment_t operator()() const
  654. {
  655. return mValue;
  656. }
  657. protected:
  658. std::string mValue;
  659. };
  660. template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  661. struct ParamIterator
  662. {
  663. typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator const_iterator;
  664. typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator iterator;
  665. };
  666. // specialize for custom parsing/decomposition of specific classes
  667. // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
  668. template<typename T,
  669. typename NAME_VALUE_LOOKUP = TypeValues<T>,
  670. bool HAS_MULTIPLE_VALUES = false,
  671. bool VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
  672. class TypedParam
  673. : public Param,
  674. public ParamValue<T, NAME_VALUE_LOOKUP>
  675. {
  676. public:
  677. typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
  678. typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
  679. typedef typename param_value_t::value_assignment_t value_assignment_t;
  680. typedef NAME_VALUE_LOOKUP name_value_lookup_t;
  681. using param_value_t::operator();
  682. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  683. : Param(block_descriptor.mCurrentBlockPtr)
  684. {
  685. if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
  686. {
  687. ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
  688. block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  689. &mergeWith,
  690. &deserializeParam,
  691. &serializeParam,
  692. validate_func,
  693. &inspectParam,
  694. min_count, max_count));
  695. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  696. }
  697. setValue(value);
  698. }
  699. bool isProvided() const { return Param::anyProvided(); }
  700. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
  701. {
  702. self_t& typed_param = static_cast<self_t&>(param);
  703. // no further names in stack, attempt to parse value now
  704. if (name_stack_range.first == name_stack_range.second)
  705. {
  706. if (parser.readValue(typed_param.getValue()))
  707. {
  708. typed_param.clearValueName();
  709. typed_param.setProvided();
  710. return true;
  711. }
  712. // try to parse a known named value
  713. if(name_value_lookup_t::valueNamesExist())
  714. {
  715. // try to parse a known named value
  716. std::string name;
  717. if (parser.readValue(name))
  718. {
  719. // try to parse a per type named value
  720. if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
  721. {
  722. typed_param.setValueName(name);
  723. typed_param.setProvided();
  724. return true;
  725. }
  726. }
  727. }
  728. }
  729. return false;
  730. }
  731. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  732. {
  733. const self_t& typed_param = static_cast<const self_t&>(param);
  734. if (!typed_param.isProvided()) return;
  735. if (!name_stack.empty())
  736. {
  737. name_stack.back().second = true;
  738. }
  739. std::string key = typed_param.getValueName();
  740. // first try to write out name of name/value pair
  741. if (!key.empty())
  742. {
  743. if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
  744. {
  745. parser.writeValue(key, name_stack);
  746. }
  747. }
  748. // then try to serialize value directly
  749. else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue()))
  750. {
  751. if (!parser.writeValue(typed_param.getValue(), name_stack))
  752. {
  753. std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
  754. if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
  755. {
  756. parser.writeValue(calculated_key, name_stack);
  757. }
  758. }
  759. }
  760. }
  761. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  762. {
  763. // tell parser about our actual type
  764. parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
  765. // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
  766. if (name_value_lookup_t::getPossibleValues())
  767. {
  768. parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
  769. }
  770. }
  771. void set(value_assignment_t val, bool flag_as_provided = true)
  772. {
  773. param_value_t::clearValueName();
  774. setValue(val);
  775. setProvided(flag_as_provided);
  776. }
  777. self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
  778. {
  779. return static_cast<self_t&>(param_value_t::operator =(name));
  780. }
  781. protected:
  782. self_t& operator =(const self_t& other)
  783. {
  784. param_value_t::operator =(other);
  785. Param::operator =(other);
  786. return *this;
  787. }
  788. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  789. {
  790. const self_t& src_typed_param = static_cast<const self_t&>(src);
  791. self_t& dst_typed_param = static_cast<self_t&>(dst);
  792. if (src_typed_param.isProvided()
  793. && (overwrite || !dst_typed_param.isProvided()))
  794. {
  795. dst_typed_param.set(src_typed_param.getValue());
  796. return true;
  797. }
  798. return false;
  799. }
  800. };
  801. // parameter that is a block
  802. template <typename T, typename NAME_VALUE_LOOKUP>
  803. class TypedParam<T, NAME_VALUE_LOOKUP, false, true>
  804. : public Param,
  805. public ParamValue<T, NAME_VALUE_LOOKUP>
  806. {
  807. public:
  808. typedef ParamValue<T, NAME_VALUE_LOOKUP> param_value_t;
  809. typedef typename param_value_t::value_assignment_t value_assignment_t;
  810. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
  811. typedef NAME_VALUE_LOOKUP name_value_lookup_t;
  812. using param_value_t::operator();
  813. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  814. : Param(block_descriptor.mCurrentBlockPtr),
  815. param_value_t(value)
  816. {
  817. if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
  818. {
  819. ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
  820. block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  821. &mergeWith,
  822. &deserializeParam,
  823. &serializeParam,
  824. validate_func,
  825. &inspectParam,
  826. min_count, max_count));
  827. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  828. }
  829. }
  830. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
  831. {
  832. self_t& typed_param = static_cast<self_t&>(param);
  833. // attempt to parse block...
  834. if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
  835. {
  836. typed_param.clearValueName();
  837. typed_param.setProvided();
  838. return true;
  839. }
  840. if(name_value_lookup_t::valueNamesExist())
  841. {
  842. // try to parse a known named value
  843. std::string name;
  844. if (parser.readValue(name))
  845. {
  846. // try to parse a per type named value
  847. if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
  848. {
  849. typed_param.setValueName(name);
  850. typed_param.setProvided();
  851. return true;
  852. }
  853. }
  854. }
  855. return false;
  856. }
  857. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  858. {
  859. const self_t& typed_param = static_cast<const self_t&>(param);
  860. if (!typed_param.isProvided()) return;
  861. if (!name_stack.empty())
  862. {
  863. name_stack.back().second = true;
  864. }
  865. std::string key = typed_param.getValueName();
  866. if (!key.empty())
  867. {
  868. if (!parser.writeValue(key, name_stack))
  869. {
  870. return;
  871. }
  872. }
  873. else
  874. {
  875. typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
  876. }
  877. }
  878. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  879. {
  880. // I am a param that is also a block, so just recurse into my contents
  881. const self_t& typed_param = static_cast<const self_t&>(param);
  882. typed_param.inspectBlock(parser, name_stack, min_count, max_count);
  883. }
  884. // a param-that-is-a-block is provided when the user has set one of its child params
  885. // *and* the block as a whole validates
  886. bool isProvided() const
  887. {
  888. // only validate block when it hasn't already passed validation with current data
  889. if (Param::anyProvided() && !param_value_t::mValidated)
  890. {
  891. // a sub-block is "provided" when it has been filled in enough to be valid
  892. param_value_t::mValidated = param_value_t::validateBlock(false);
  893. }
  894. return Param::anyProvided() && param_value_t::mValidated;
  895. }
  896. // assign block contents to this param-that-is-a-block
  897. void set(value_assignment_t val, bool flag_as_provided = true)
  898. {
  899. setValue(val);
  900. param_value_t::clearValueName();
  901. // force revalidation of block
  902. // next call to isProvided() will update provision status based on validity
  903. param_value_t::mValidated = false;
  904. setProvided(flag_as_provided);
  905. }
  906. self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
  907. {
  908. return static_cast<self_t&>(param_value_t::operator =(name));
  909. }
  910. // propagate changed status up to enclosing block
  911. /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
  912. {
  913. param_value_t::paramChanged(changed_param, user_provided);
  914. if (user_provided)
  915. {
  916. // a child param has been explicitly changed
  917. // so *some* aspect of this block is now provided
  918. param_value_t::mValidated = false;
  919. setProvided();
  920. param_value_t::clearValueName();
  921. }
  922. else
  923. {
  924. Param::enclosingBlock().paramChanged(*this, user_provided);
  925. }
  926. }
  927. protected:
  928. self_t& operator =(const self_t& other)
  929. {
  930. param_value_t::operator =(other);
  931. Param::operator =(other);
  932. return *this;
  933. }
  934. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  935. {
  936. const self_t& src_typed_param = static_cast<const self_t&>(src);
  937. self_t& dst_typed_param = static_cast<self_t&>(dst);
  938. if (src_typed_param.anyProvided())
  939. {
  940. if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
  941. {
  942. dst_typed_param.clearValueName();
  943. dst_typed_param.setProvided(true);
  944. return true;
  945. }
  946. }
  947. return false;
  948. }
  949. };
  950. // container of non-block parameters
  951. template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
  952. class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>
  953. : public Param
  954. {
  955. public:
  956. typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
  957. typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
  958. typedef typename std::vector<param_value_t> container_t;
  959. typedef const container_t& value_assignment_t;
  960. typedef typename param_value_t::value_t value_t;
  961. typedef NAME_VALUE_LOOKUP name_value_lookup_t;
  962. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  963. : Param(block_descriptor.mCurrentBlockPtr)
  964. {
  965. std::copy(value.begin(), value.end(), std::back_inserter(mValues));
  966. if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
  967. {
  968. ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
  969. block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  970. &mergeWith,
  971. &deserializeParam,
  972. &serializeParam,
  973. validate_func,
  974. &inspectParam,
  975. min_count, max_count));
  976. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  977. }
  978. }
  979. bool isProvided() const { return Param::anyProvided(); }
  980. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
  981. {
  982. self_t& typed_param = static_cast<self_t&>(param);
  983. value_t value;
  984. // no further names in stack, attempt to parse value now
  985. if (name_stack_range.first == name_stack_range.second)
  986. {
  987. // attempt to read value directly
  988. if (parser.readValue(value))
  989. {
  990. typed_param.add(value);
  991. return true;
  992. }
  993. // try to parse a known named value
  994. if(name_value_lookup_t::valueNamesExist())
  995. {
  996. // try to parse a known named value
  997. std::string name;
  998. if (parser.readValue(name))
  999. {
  1000. // try to parse a per type named value
  1001. if (name_value_lookup_t::getValueFromName(name, value))
  1002. {
  1003. typed_param.add(value);
  1004. typed_param.mValues.back().setValueName(name);
  1005. return true;
  1006. }
  1007. }
  1008. }
  1009. }
  1010. return false;
  1011. }
  1012. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  1013. {
  1014. const self_t& typed_param = static_cast<const self_t&>(param);
  1015. if (!typed_param.isProvided() || name_stack.empty()) return;
  1016. for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
  1017. it != end_it;
  1018. ++it)
  1019. {
  1020. std::string key = it->getValueName();
  1021. name_stack.back().second = true;
  1022. if(key.empty())
  1023. // not parsed via name values, write out value directly
  1024. {
  1025. bool value_written = parser.writeValue(*it, name_stack);
  1026. if (!value_written)
  1027. {
  1028. std::string calculated_key = it->calcValueName(it->getValue());
  1029. if (!parser.writeValue(calculated_key, name_stack))
  1030. {
  1031. break;
  1032. }
  1033. }
  1034. }
  1035. else
  1036. {
  1037. if(!parser.writeValue(key, name_stack))
  1038. {
  1039. break;
  1040. }
  1041. }
  1042. }
  1043. }
  1044. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  1045. {
  1046. parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
  1047. if (name_value_lookup_t::getPossibleValues())
  1048. {
  1049. parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
  1050. }
  1051. }
  1052. void set(value_assignment_t val, bool flag_as_provided = true)
  1053. {
  1054. mValues = val;
  1055. setProvided(flag_as_provided);
  1056. }
  1057. param_value_t& add()
  1058. {
  1059. mValues.push_back(param_value_t(value_t()));
  1060. Param::setProvided();
  1061. return mValues.back();
  1062. }
  1063. void add(const value_t& item)
  1064. {
  1065. param_value_t param_value;
  1066. param_value.setValue(item);
  1067. mValues.push_back(param_value);
  1068. setProvided();
  1069. }
  1070. void add(const typename name_value_lookup_t::name_t& name)
  1071. {
  1072. value_t value;
  1073. // try to parse a per type named value
  1074. if (name_value_lookup_t::getValueFromName(name, value))
  1075. {
  1076. add(value);
  1077. mValues.back().setValueName(name);
  1078. }
  1079. }
  1080. // implicit conversion
  1081. operator value_assignment_t() const { return mValues; }
  1082. // explicit conversion
  1083. value_assignment_t operator()() const { return mValues; }
  1084. typedef typename container_t::iterator iterator;
  1085. typedef typename container_t::const_iterator const_iterator;
  1086. iterator begin() { return mValues.begin(); }
  1087. iterator end() { return mValues.end(); }
  1088. const_iterator begin() const { return mValues.begin(); }
  1089. const_iterator end() const { return mValues.end(); }
  1090. bool empty() const { return mValues.empty(); }
  1091. size_t size() const { return mValues.size(); }
  1092. U32 numValidElements() const
  1093. {
  1094. return mValues.size();
  1095. }
  1096. protected:
  1097. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  1098. {
  1099. const self_t& src_typed_param = static_cast<const self_t&>(src);
  1100. self_t& dst_typed_param = static_cast<self_t&>(dst);
  1101. if (overwrite)
  1102. {
  1103. std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
  1104. }
  1105. else
  1106. {
  1107. container_t new_values(src_typed_param.mValues);
  1108. std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
  1109. std::swap(dst_typed_param.mValues, new_values);
  1110. }
  1111. if (src_typed_param.begin() != src_typed_param.end())
  1112. {
  1113. dst_typed_param.setProvided();
  1114. }
  1115. return true;
  1116. }
  1117. container_t mValues;
  1118. };
  1119. // container of block parameters
  1120. template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
  1121. class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>
  1122. : public Param
  1123. {
  1124. public:
  1125. typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
  1126. typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP> param_value_t;
  1127. typedef typename std::vector<param_value_t> container_t;
  1128. typedef const container_t& value_assignment_t;
  1129. typedef typename param_value_t::value_t value_t;
  1130. typedef NAME_VALUE_LOOKUP name_value_lookup_t;
  1131. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  1132. : Param(block_descriptor.mCurrentBlockPtr)
  1133. {
  1134. std::copy(value.begin(), value.end(), back_inserter(mValues));
  1135. if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
  1136. {
  1137. ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
  1138. block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  1139. &mergeWith,
  1140. &deserializeParam,
  1141. &serializeParam,
  1142. validate_func,
  1143. &inspectParam,
  1144. min_count, max_count));
  1145. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  1146. }
  1147. }
  1148. bool isProvided() const { return Param::anyProvided(); }
  1149. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
  1150. {
  1151. self_t& typed_param = static_cast<self_t&>(param);
  1152. bool new_value = false;
  1153. if (new_name || typed_param.mValues.empty())
  1154. {
  1155. new_value = true;
  1156. typed_param.mValues.push_back(value_t());
  1157. }
  1158. param_value_t& value = typed_param.mValues.back();
  1159. // attempt to parse block...
  1160. if(value.deserializeBlock(parser, name_stack_range, new_name))
  1161. {
  1162. typed_param.setProvided();
  1163. return true;
  1164. }
  1165. else if(name_value_lookup_t::valueNamesExist())
  1166. {
  1167. // try to parse a known named value
  1168. std::string name;
  1169. if (parser.readValue(name))
  1170. {
  1171. // try to parse a per type named value
  1172. if (name_value_lookup_t::getValueFromName(name, value.getValue()))
  1173. {
  1174. typed_param.mValues.back().setValueName(name);
  1175. typed_param.setProvided();
  1176. return true;
  1177. }
  1178. }
  1179. }
  1180. if (new_value)
  1181. { // failed to parse new value, pop it off
  1182. typed_param.mValues.pop_back();
  1183. }
  1184. return false;
  1185. }
  1186. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  1187. {
  1188. const self_t& typed_param = static_cast<const self_t&>(param);
  1189. if (!typed_param.isProvided() || name_stack.empty()) return;
  1190. for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
  1191. it != end_it;
  1192. ++it)
  1193. {
  1194. name_stack.back().second = true;
  1195. std::string key = it->getValueName();
  1196. if (!key.empty())
  1197. {
  1198. parser.writeValue(key, name_stack);
  1199. }
  1200. // Not parsed via named values, write out value directly
  1201. // NOTE: currently we don't worry about removing default values in Multiple
  1202. else
  1203. {
  1204. it->serializeBlock(parser, name_stack, NULL);
  1205. }
  1206. }
  1207. }
  1208. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  1209. {
  1210. // I am a vector of blocks, so describe my contents recursively
  1211. param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
  1212. }
  1213. void set(value_assignment_t val, bool flag_as_provided = true)
  1214. {
  1215. mValues = val;
  1216. setProvided(flag_as_provided);
  1217. }
  1218. param_value_t& add()
  1219. {
  1220. mValues.push_back(value_t());
  1221. setProvided();
  1222. return mValues.back();
  1223. }
  1224. void add(const value_t& item)
  1225. {
  1226. mValues.push_back(item);
  1227. setProvided();
  1228. }
  1229. void add(const typename name_value_lookup_t::name_t& name)
  1230. {
  1231. value_t value;
  1232. // try to parse a per type named value
  1233. if (name_value_lookup_t::getValueFromName(name, value))
  1234. {
  1235. add(value);
  1236. mValues.back().setValueName(name);
  1237. }
  1238. }
  1239. // implicit conversion
  1240. operator value_assignment_t() const { return mValues; }
  1241. // explicit conversion
  1242. value_assignment_t operator()() const { return mValues; }
  1243. typedef typename container_t::iterator iterator;
  1244. typedef typename container_t::const_iterator const_iterator;
  1245. iterator begin() { return mValues.begin(); }
  1246. iterator end() { return mValues.end(); }
  1247. const_iterator begin() const { return mValues.begin(); }
  1248. const_iterator end() const { return mValues.end(); }
  1249. bool empty() const { return mValues.empty(); }
  1250. size_t size() const { return mValues.size(); }
  1251. U32 numValidElements() const
  1252. {
  1253. U32 count = 0;
  1254. for (const_iterator it = mValues.begin(), end_it = mValues.end();
  1255. it != end_it;
  1256. ++it)
  1257. {
  1258. if(it->validateBlock(false)) count++;
  1259. }
  1260. return count;
  1261. }
  1262. protected:
  1263. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  1264. {
  1265. const self_t& src_typed_param = static_cast<const self_t&>(src);
  1266. self_t& dst_typed_param = static_cast<self_t&>(dst);
  1267. if (overwrite)
  1268. {
  1269. std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));
  1270. }
  1271. else
  1272. {
  1273. container_t new_values(src_typed_param.mValues);
  1274. std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values));
  1275. std::swap(dst_typed_param.mValues, new_values);
  1276. }
  1277. if (src_typed_param.begin() != src_typed_param.end())
  1278. {
  1279. dst_typed_param.setProvided();
  1280. }
  1281. return true;
  1282. }
  1283. container_t mValues;
  1284. };
  1285. template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
  1286. class ChoiceBlock : public BASE_BLOCK
  1287. {
  1288. typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
  1289. typedef ChoiceBlock<DERIVED_BLOCK, BASE_BLOCK> enclosing_block_t;
  1290. typedef BASE_BLOCK base_block_t;
  1291. LOG_CLASS(self_t);
  1292. public:
  1293. // take all provided params from other and apply to self
  1294. bool overwriteFrom(const self_t& other)
  1295. {
  1296. return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
  1297. }
  1298. // take all provided params that are not already provided, and apply to self
  1299. bool fillFrom(const self_t& other)
  1300. {
  1301. return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
  1302. }
  1303. bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
  1304. {
  1305. bool source_override = source_provided && (overwrite || !dest_provided);
  1306. if (source_override || source.mCurChoice == mCurChoice)
  1307. {
  1308. return mergeBlock(block_data, source, overwrite);
  1309. }
  1310. return false;
  1311. }
  1312. // merge with other block
  1313. bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
  1314. {
  1315. mCurChoice = other.mCurChoice;
  1316. return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
  1317. }
  1318. // clear out old choice when param has changed
  1319. /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
  1320. {
  1321. param_handle_t changed_param_handle = base_block_t::getHandleFromParam(&changed_param);
  1322. // if we have a new choice...
  1323. if (changed_param_handle != mCurChoice)
  1324. {
  1325. // clear provided flag on previous choice
  1326. Param* previous_choice = base_block_t::getParamFromHandle(mCurChoice);
  1327. if (previous_choice)
  1328. {
  1329. previous_choice->setProvided(false);
  1330. }
  1331. mCurChoice = changed_param_handle;
  1332. }
  1333. base_block_t::paramChanged(changed_param, user_provided);
  1334. }
  1335. virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
  1336. virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
  1337. protected:
  1338. ChoiceBlock()
  1339. : mCurChoice(0)
  1340. {
  1341. BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
  1342. }
  1343. // Alternatives are mutually exclusive wrt other Alternatives in the same block.
  1344. // One alternative in a block will always have isChosen() == true.
  1345. // At most one alternative in a block will have isProvided() == true.
  1346. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1347. class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1348. {
  1349. public:
  1350. friend class ChoiceBlock<DERIVED_BLOCK>;
  1351. typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
  1352. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
  1353. typedef typename super_t::value_assignment_t value_assignment_t;
  1354. using super_t::operator =;
  1355. explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
  1356. : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
  1357. mOriginalValue(val)
  1358. {
  1359. // assign initial choice to first declared option
  1360. DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
  1361. if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
  1362. {
  1363. if(blockp->mCurChoice == 0)
  1364. {
  1365. blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
  1366. }
  1367. }
  1368. }
  1369. void choose()
  1370. {
  1371. static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
  1372. }
  1373. void chooseAs(value_assignment_t val)
  1374. {
  1375. super_t::set(val);
  1376. }
  1377. void operator =(value_assignment_t val)
  1378. {
  1379. super_t::set(val);
  1380. }
  1381. void operator()(typename super_t::value_assignment_t val)
  1382. {
  1383. super_t::set(val);
  1384. }
  1385. operator value_assignment_t() const
  1386. {
  1387. return (*this)();
  1388. }
  1389. value_assignment_t operator()() const
  1390. {
  1391. if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
  1392. {
  1393. return super_t::getValue();
  1394. }
  1395. return mOriginalValue;
  1396. }
  1397. bool isChosen() const
  1398. {
  1399. return static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this;
  1400. }
  1401. private:
  1402. T mOriginalValue;
  1403. };
  1404. protected:
  1405. static BlockDescriptor& selfBlockDescriptor()
  1406. {
  1407. static BlockDescriptor sBlockDescriptor;
  1408. return sBlockDescriptor;
  1409. }
  1410. private:
  1411. param_handle_t mCurChoice;
  1412. const Param* getCurrentChoice() const
  1413. {
  1414. return base_block_t::getParamFromHandle(mCurChoice);
  1415. }
  1416. };
  1417. template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
  1418. class Block
  1419. : public BASE_BLOCK
  1420. {
  1421. typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
  1422. typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
  1423. public:
  1424. typedef BASE_BLOCK base_block_t;
  1425. // take all provided params from other and apply to self
  1426. bool overwriteFrom(const self_t& other)
  1427. {
  1428. return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
  1429. }
  1430. // take all provided params that are not already provided, and apply to self
  1431. bool fillFrom(const self_t& other)
  1432. {
  1433. return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
  1434. }
  1435. virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
  1436. virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
  1437. protected:
  1438. Block()
  1439. {
  1440. //#pragma message("Parsing LLInitParam::Block")
  1441. BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
  1442. }
  1443. //
  1444. // Nested classes for declaring parameters
  1445. //
  1446. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1447. class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1448. {
  1449. public:
  1450. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
  1451. typedef typename super_t::value_assignment_t value_assignment_t;
  1452. using super_t::operator();
  1453. using super_t::operator =;
  1454. explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
  1455. : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
  1456. {
  1457. //#pragma message("Parsing LLInitParam::Block::Optional")
  1458. }
  1459. Optional& operator =(value_assignment_t val)
  1460. {
  1461. set(val);
  1462. return *this;
  1463. }
  1464. DERIVED_BLOCK& operator()(value_assignment_t val)
  1465. {
  1466. super_t::set(val);
  1467. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1468. }
  1469. };
  1470. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1471. class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1472. {
  1473. public:
  1474. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
  1475. typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
  1476. typedef typename super_t::value_assignment_t value_assignment_t;
  1477. using super_t::operator();
  1478. using super_t::operator =;
  1479. // mandatory parameters require a name to be parseable
  1480. explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
  1481. : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
  1482. {}
  1483. Mandatory& operator =(value_assignment_t val)
  1484. {
  1485. set(val);
  1486. return *this;
  1487. }
  1488. DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
  1489. {
  1490. super_t::set(val);
  1491. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1492. }
  1493. static bool validate(const Param* p)
  1494. {
  1495. // valid only if provided
  1496. return static_cast<const self_t*>(p)->isProvided();
  1497. }
  1498. };
  1499. template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1500. class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
  1501. {
  1502. public:
  1503. typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value> super_t;
  1504. typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
  1505. typedef typename super_t::container_t container_t;
  1506. typedef typename super_t::value_assignment_t value_assignment_t;
  1507. typedef typename super_t::iterator iterator;
  1508. typedef typename super_t::const_iterator const_iterator;
  1509. explicit Multiple(const char* name = "")
  1510. : super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
  1511. {}
  1512. Multiple& operator =(value_assignment_t val)
  1513. {
  1514. set(val);
  1515. return *this;
  1516. }
  1517. DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
  1518. {
  1519. super_t::set(val);
  1520. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1521. }
  1522. static bool validate(const Param* paramp)
  1523. {
  1524. U32 num_valid = ((super_t*)paramp)->numValidElements();
  1525. return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
  1526. }
  1527. };
  1528. class Deprecated : public Param
  1529. {
  1530. public:
  1531. explicit Deprecated(const char* name)
  1532. : Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
  1533. {
  1534. BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
  1535. if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
  1536. {
  1537. ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
  1538. block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  1539. NULL,
  1540. &deserializeParam,
  1541. NULL,
  1542. NULL,
  1543. NULL,
  1544. 0, S32_MAX));
  1545. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  1546. }
  1547. }
  1548. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
  1549. {
  1550. if (name_stack_range.first == name_stack_range.second)
  1551. {
  1552. //std::string message = llformat("Deprecated value %s ignored", getName().c_str());
  1553. //parser.parserWarning(message);
  1554. return true;
  1555. }
  1556. return false;
  1557. }
  1558. };
  1559. // different semantics for documentation purposes, but functionally identical
  1560. typedef Deprecated Ignored;
  1561. protected:
  1562. static BlockDescriptor& selfBlockDescriptor()
  1563. {
  1564. static BlockDescriptor sBlockDescriptor;
  1565. return sBlockDescriptor;
  1566. }
  1567. template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
  1568. void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param,
  1569. typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
  1570. {
  1571. if (!param.isProvided())
  1572. {
  1573. param.set(value, false);
  1574. }
  1575. }
  1576. };
  1577. template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
  1578. class BatchBlock
  1579. : public Block<DERIVED_BLOCK, BASE_BLOCK>
  1580. {
  1581. public:
  1582. typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
  1583. typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
  1584. BatchBlock()
  1585. {}
  1586. bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
  1587. {
  1588. if (new_name)
  1589. {
  1590. // reset block
  1591. *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
  1592. }
  1593. return super_t::deserializeBlock(p, name_stack_range, new_name);
  1594. }
  1595. bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
  1596. {
  1597. if (overwrite)
  1598. {
  1599. *static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
  1600. // merge individual parameters into destination
  1601. return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
  1602. }
  1603. return false;
  1604. }
  1605. protected:
  1606. static const DERIVED_BLOCK& defaultBatchValue()
  1607. {
  1608. static DERIVED_BLOCK default_value;
  1609. return default_value;
  1610. }
  1611. };
  1612. // FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
  1613. // and not the derived class with the actual params
  1614. template<typename DERIVED_BLOCK,
  1615. typename BASE_BLOCK,
  1616. typename NAME_VALUE_LOOKUP>
  1617. class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
  1618. NAME_VALUE_LOOKUP,
  1619. true>
  1620. : public NAME_VALUE_LOOKUP,
  1621. protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
  1622. {
  1623. public:
  1624. typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
  1625. typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& value_assignment_t;
  1626. typedef block_t value_t;
  1627. ParamValue()
  1628. : block_t(),
  1629. mValidated(false)
  1630. {}
  1631. ParamValue(value_assignment_t other)
  1632. : block_t(other),
  1633. mValidated(false)
  1634. {
  1635. }
  1636. void setValue(value_assignment_t val)
  1637. {
  1638. *this = val;
  1639. }
  1640. value_assignment_t getValue() const
  1641. {
  1642. return *this;
  1643. }
  1644. BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
  1645. {
  1646. return *this;
  1647. }
  1648. operator value_assignment_t() const
  1649. {
  1650. return *this;
  1651. }
  1652. value_assignment_t operator()() const
  1653. {
  1654. return *this;
  1655. }
  1656. protected:
  1657. mutable bool mValidated; // lazy validation flag
  1658. };
  1659. template<typename T, bool IS_BLOCK>
  1660. class ParamValue <BaseBlock::Lazy<T>,
  1661. TypeValues<T>,
  1662. IS_BLOCK>
  1663. : public IsBlock<T>::base_class_t
  1664. {
  1665. public:
  1666. typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
  1667. typedef const T& value_assignment_t;
  1668. typedef T value_t;
  1669. ParamValue()
  1670. : mValue(),
  1671. mValidated(false)
  1672. {}
  1673. ParamValue(value_assignment_t other)
  1674. : mValue(other),
  1675. mValidated(false)
  1676. {}
  1677. void setValue(value_assignment_t val)
  1678. {
  1679. mValue.set(val);
  1680. }
  1681. value_assignment_t getValue() const
  1682. {
  1683. return mValue.get();
  1684. }
  1685. T& getValue()
  1686. {
  1687. return mValue.get();
  1688. }
  1689. operator value_assignment_t() const
  1690. {
  1691. return mValue.get();
  1692. }
  1693. value_assignment_t operator()() const
  1694. {
  1695. return mValue.get();
  1696. }
  1697. bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
  1698. {
  1699. return mValue.get().deserializeBlock(p, name_stack_range, new_name);
  1700. }
  1701. void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
  1702. {
  1703. if (mValue.empty()) return;
  1704. mValue.get().serializeBlock(p, name_stack, diff_block);
  1705. }
  1706. bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
  1707. {
  1708. if (mValue.empty()) return false;
  1709. return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
  1710. }
  1711. protected:
  1712. mutable bool mValidated; // lazy validation flag
  1713. private:
  1714. BaseBlock::Lazy<T> mValue;
  1715. };
  1716. template <>
  1717. class ParamValue <LLSD,
  1718. TypeValues<LLSD>,
  1719. false>
  1720. : public TypeValues<LLSD>,
  1721. public BaseBlock
  1722. {
  1723. public:
  1724. typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
  1725. typedef const LLSD& value_assignment_t;
  1726. ParamValue()
  1727. : mValidated(false)
  1728. {}
  1729. ParamValue(value_assignment_t other)
  1730. : mValue(other),
  1731. mValidated(false)
  1732. {}
  1733. void setValue(value_assignment_t val) { mValue = val; }
  1734. value_assignment_t getValue() const { return mValue; }
  1735. LLSD& getValue() { return mValue; }
  1736. operator value_assignment_t() const { return mValue; }
  1737. value_assignment_t operator()() const { return mValue; }
  1738. // block param interface
  1739. bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
  1740. void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
  1741. bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
  1742. {
  1743. //TODO: implement LLSD params as schema type Any
  1744. return true;
  1745. }
  1746. protected:
  1747. mutable bool mValidated; // lazy validation flag
  1748. private:
  1749. static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
  1750. LLSD mValue;
  1751. };
  1752. template<typename T>
  1753. class CustomParamValue
  1754. : public Block<ParamValue<T, TypeValues<T> > >,
  1755. public TypeValues<T>
  1756. {
  1757. public:
  1758. typedef enum e_value_age
  1759. {
  1760. VALUE_NEEDS_UPDATE, // mValue needs to be refreshed from the block parameters
  1761. VALUE_AUTHORITATIVE, // mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue)
  1762. BLOCK_AUTHORITATIVE // mValue is derived from the block parameters, which are authoritative
  1763. } EValueAge;
  1764. typedef ParamValue<T, TypeValues<T> > derived_t;
  1765. typedef CustomParamValue<T> self_t;
  1766. typedef Block<derived_t> block_t;
  1767. typedef const T& value_assignment_t;
  1768. typedef T value_t;
  1769. CustomParamValue(const T& value = T())
  1770. : mValue(value),
  1771. mValueAge(VALUE_AUTHORITATIVE),
  1772. mValidated(false)
  1773. {}
  1774. bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
  1775. {
  1776. derived_t& typed_param = static_cast<derived_t&>(*this);
  1777. // try to parse direct value T
  1778. if (name_stack_range.first == name_stack_range.second)
  1779. {
  1780. if(parser.readValue(typed_param.mValue))
  1781. {
  1782. typed_param.mValueAge = VALUE_AUTHORITATIVE;
  1783. typed_param.updateBlockFromValue(false);
  1784. typed_param.clearValueName();
  1785. return true;
  1786. }
  1787. }
  1788. // fall back on parsing block components for T
  1789. return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
  1790. }
  1791. void serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
  1792. {
  1793. const derived_t& typed_param = static_cast<const derived_t&>(*this);
  1794. const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
  1795. std::string key = typed_param.getValueName();
  1796. // first try to write out name of name/value pair
  1797. if (!key.empty())
  1798. {
  1799. if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
  1800. {
  1801. parser.writeValue(key, name_stack);
  1802. }
  1803. }
  1804. // then try to serialize value directly
  1805. else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
  1806. {
  1807. if (!parser.writeValue(typed_param.getValue(), name_stack))
  1808. {
  1809. //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
  1810. // since these tend to be viewed as the constructor arguments for the value T. It seems
  1811. // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
  1812. // not the individual components. This way <color red="0" green="1" blue="0"/> will not
  1813. // be exported as <color green="1"/>, since it was probably the intent of the user to
  1814. // be specific about the RGB color values. This also fixes an issue where we distinguish
  1815. // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
  1816. if (typed_param.mValueAge == VALUE_AUTHORITATIVE)
  1817. {
  1818. // if the value is authoritative but the parser doesn't accept the value type
  1819. // go ahead and make a copy, and splat the value out to its component params
  1820. // and serialize those params
  1821. derived_t copy(typed_param);
  1822. copy.updateBlockFromValue(true);
  1823. copy.block_t::serializeBlock(parser, name_stack, NULL);
  1824. }
  1825. else
  1826. {
  1827. block_t::serializeBlock(parser, name_stack, NULL);
  1828. }
  1829. }
  1830. }
  1831. }
  1832. bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
  1833. {
  1834. // first, inspect with actual type...
  1835. parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
  1836. if (TypeValues<T>::getPossibleValues())
  1837. {
  1838. //...then inspect with possible string values...
  1839. parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
  1840. }
  1841. // then recursively inspect contents...
  1842. return block_t::inspectBlock(parser, name_stack, min_count, max_count);
  1843. }
  1844. bool validateBlock(bool emit_errors = true) const
  1845. {
  1846. if (mValueAge == VALUE_NEEDS_UPDATE)
  1847. {
  1848. if (block_t::validateBlock(emit_errors))
  1849. {
  1850. // clear stale keyword associated with old value
  1851. TypeValues<T>::clearValueName();
  1852. mValueAge = BLOCK_AUTHORITATIVE;
  1853. static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
  1854. return true;
  1855. }
  1856. else
  1857. {
  1858. //block value incomplete, so not considered provided
  1859. // will attempt to revalidate on next call to isProvided()
  1860. return false;
  1861. }
  1862. }
  1863. else
  1864. {
  1865. // we have a valid value in hand
  1866. return true;
  1867. }
  1868. }
  1869. // propagate change status up to enclosing block
  1870. /*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
  1871. {
  1872. BaseBlock::paramChanged(changed_param, user_provided);
  1873. if (user_provided)
  1874. {
  1875. // a parameter changed, so our value is out of date
  1876. mValueAge = VALUE_NEEDS_UPDATE;
  1877. }
  1878. }
  1879. void setValue(value_assignment_t val)
  1880. {
  1881. derived_t& typed_param = static_cast<derived_t&>(*this);
  1882. // set param version number to be up to date, so we ignore block contents
  1883. mValueAge = VALUE_AUTHORITATIVE;
  1884. mValue = val;
  1885. typed_param.clearValueName();
  1886. static_cast<derived_t*>(this)->updateBlockFromValue(false);
  1887. }
  1888. value_assignment_t getValue() const
  1889. {
  1890. validateBlock(true);
  1891. return mValue;
  1892. }
  1893. T& getValue()
  1894. {
  1895. validateBlock(true);
  1896. return mValue;
  1897. }
  1898. operator value_assignment_t() const
  1899. {
  1900. return getValue();
  1901. }
  1902. value_assignment_t operator()() const
  1903. {
  1904. return getValue();
  1905. }
  1906. protected:
  1907. // use this from within updateValueFromBlock() to set the value without making it authoritative
  1908. void updateValue(value_assignment_t value)
  1909. {
  1910. mValue = value;
  1911. }
  1912. bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
  1913. {
  1914. bool source_override = source_provided && (overwrite || !dst_provided);
  1915. const derived_t& src_typed_param = static_cast<const derived_t&>(source);
  1916. if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
  1917. {
  1918. // copy value over
  1919. setValue(src_typed_param.getValue());
  1920. return true;
  1921. }
  1922. // merge individual parameters into destination
  1923. if (mValueAge == VALUE_AUTHORITATIVE)
  1924. {
  1925. static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);
  1926. }
  1927. return mergeBlock(block_data, source, overwrite);
  1928. }
  1929. bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
  1930. {
  1931. return block_t::mergeBlock(block_data, source, overwrite);
  1932. }
  1933. mutable bool mValidated; // lazy validation flag
  1934. private:
  1935. mutable T mValue;
  1936. mutable EValueAge mValueAge;
  1937. };
  1938. }
  1939. #endif // LL_LLPARAM_H