llinitparam.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:54k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2. f * @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=viewergpl$
  7.  * 
  8.  * Copyright (c) 2008-2010, Linden Research, Inc.
  9.  * 
  10.  * Second Life Viewer Source Code
  11.  * The source code in this file ("Source Code") is provided by Linden Lab
  12.  * to you under the terms of the GNU General Public License, version 2.0
  13.  * ("GPL"), unless you have obtained a separate licensing agreement
  14.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  15.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17.  * 
  18.  * There are special exceptions to the terms and conditions of the GPL as
  19.  * it is applied to this Source Code. View the full text of the exception
  20.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  21.  * online at
  22.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23.  * 
  24.  * By copying, modifying or distributing this software, you acknowledge
  25.  * that you have read and understood your obligations described above,
  26.  * and agree to abide by those obligations.
  27.  * 
  28.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30.  * COMPLETENESS OR PERFORMANCE.
  31.  * $/LicenseInfo$
  32.  */
  33. #ifndef LL_LLPARAM_H
  34. #define LL_LLPARAM_H
  35. #include <vector>
  36. #include <stddef.h>
  37. #include <boost/function.hpp>
  38. #include <boost/bind.hpp>
  39. #include <boost/type_traits/is_convertible.hpp>
  40. #include "llregistry.h"
  41. #include "llmemory.h"
  42. namespace LLInitParam
  43. {
  44. template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
  45.     struct ParamCompare 
  46. {
  47.      static bool equals(const T &a, const T &b)
  48. {
  49. return a == b;
  50. }
  51.     };
  52.     
  53. // boost function types are not comparable
  54. template<typename T>
  55. struct ParamCompare<T, true>
  56. {
  57. static bool equals(const T&a, const T &b)
  58. {
  59. return false;
  60. }
  61. };
  62. // default constructor adaptor for InitParam Values
  63. // constructs default instances of the given type, returned by const reference
  64. template <typename T>
  65. struct DefaultInitializer
  66. {
  67. typedef const T& T_const_ref;
  68. // return reference to a single default instance of T
  69. // built-in types will be initialized to zero, default constructor otherwise
  70. static T_const_ref get() { static T t = T(); return t; } 
  71. };
  72. // helper functions and classes
  73. typedef ptrdiff_t param_handle_t;
  74. template <typename T>
  75. class TypeValues
  76. {
  77. public:
  78. // empty default implemenation of key cache
  79. class KeyCache
  80. {
  81. public:
  82. void setKey(const std::string& key) {}
  83. std::string getKey() const { return ""; }
  84. void clearKey(){}
  85. };
  86. static bool get(const std::string& name, T& value)
  87. {
  88. return false;
  89. }
  90. static bool empty()
  91. {
  92. return true;
  93. }
  94. static std::vector<std::string>* getPossibleValues() { return NULL; }
  95. };
  96. template <typename T, typename DERIVED_TYPE = TypeValues<T> >
  97. class TypeValuesHelper
  98. : public LLRegistrySingleton<std::string, T, DERIVED_TYPE >
  99. {
  100. typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE> super_t;
  101. typedef LLSingleton<DERIVED_TYPE> singleton_t;
  102. public:
  103. //TODO: cache key by index to save on param block size
  104. class KeyCache
  105. {
  106. public:
  107. void setKey(const std::string& key) 
  108. {
  109. mKey = key; 
  110. }
  111. void clearKey()
  112. {
  113. mKey = "";
  114. }
  115. std::string getKey() const
  116. return mKey; 
  117. }
  118. private:
  119. std::string mKey;
  120. };
  121. static bool get(const std::string& name, T& value)
  122. {
  123. if (!singleton_t::instance().exists(name)) return false;
  124. value = *singleton_t::instance().getValue(name);
  125. return true;
  126. }
  127. static bool empty()
  128. {
  129. return singleton_t::instance().LLRegistry<std::string, T>::empty();
  130. }
  131. //override this to add name value pairs
  132. static void declareValues() {}
  133. void initSingleton()
  134. {
  135. DERIVED_TYPE::declareValues();
  136. }
  137. static const std::vector<std::string>* getPossibleValues() 
  138. // in order to return a pointer to a member, we lazily
  139. // evaluate the result and store it in mValues here
  140. if (singleton_t::instance().mValues.empty())
  141. {
  142. typename super_t::Registrar::registry_map_t::const_iterator it;
  143. for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it)
  144. {
  145. singleton_t::instance().mValues.push_back(it->first);
  146. }
  147. }
  148. return &singleton_t::instance().mValues; 
  149. }
  150. protected:
  151. static void declare(const std::string& name, const T& value)
  152. {
  153. super_t::defaultRegistrar().add(name, value);
  154. }
  155. private:
  156. std::vector<std::string> mValues;
  157. };
  158. class Parser
  159. {
  160. LOG_CLASS(Parser);
  161. public:
  162. struct CompareTypeID
  163. {
  164. bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
  165. {
  166. return lhs->before(*rhs);
  167. }
  168. };
  169. typedef std::vector<std::pair<std::string, S32> > name_stack_t;
  170. typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator> name_stack_range_t;
  171. typedef std::vector<std::string> possible_values_t;
  172. typedef boost::function<bool (void*)> parser_read_func_t;
  173. typedef boost::function<bool (const void*, const name_stack_t&)> parser_write_func_t;
  174. typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)> parser_inspect_func_t;
  175. typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID> parser_read_func_map_t;
  176. typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID> parser_write_func_map_t;
  177. typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID> parser_inspect_func_map_t;
  178. Parser()
  179. : mParseSilently(false),
  180. mParseGeneration(0)
  181. {}
  182. virtual ~Parser();
  183. template <typename T> bool readValue(T& param)
  184.     {
  185.     parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T));
  186.     if (found_it != mParserReadFuncs.end())
  187.     {
  188.     return found_it->second((void*)&param);
  189.     }
  190.     return false;
  191.     }
  192. template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack)
  193. {
  194.     parser_write_func_map_t::iterator found_it = mParserWriteFuncs.find(&typeid(T));
  195.     if (found_it != mParserWriteFuncs.end())
  196.     {
  197.     return found_it->second((const void*)&param, name_stack);
  198.     }
  199.     return false;
  200. }
  201. // dispatch inspection to registered inspection functions, for each parameter in a param block
  202. template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
  203. {
  204.     parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs.find(&typeid(T));
  205.     if (found_it != mParserInspectFuncs.end())
  206.     {
  207.     found_it->second(name_stack, min_count, max_count, possible_values);
  208. return true;
  209.     }
  210. return false;
  211. }
  212. virtual std::string getCurrentElementName() = 0;
  213. virtual void parserWarning(const std::string& message);
  214. virtual void parserError(const std::string& message);
  215. void setParseSilently(bool silent) { mParseSilently = silent; }
  216. bool getParseSilently() { return mParseSilently; }
  217. S32 getParseGeneration() { return mParseGeneration; }
  218. S32 newParseGeneration() { return ++mParseGeneration; }
  219. protected:
  220. template <typename T>
  221. void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func)
  222. {
  223. mParserReadFuncs.insert(std::make_pair(&typeid(T), read_func));
  224. mParserWriteFuncs.insert(std::make_pair(&typeid(T), write_func));
  225. }
  226. template <typename T>
  227. void registerInspectFunc(parser_inspect_func_t inspect_func)
  228. {
  229. mParserInspectFuncs.insert(std::make_pair(&typeid(T), inspect_func));
  230. }
  231. bool mParseSilently;
  232. private:
  233. parser_read_func_map_t mParserReadFuncs;
  234. parser_write_func_map_t mParserWriteFuncs;
  235. parser_inspect_func_map_t mParserInspectFuncs;
  236. S32 mParseGeneration;
  237. };
  238. class BaseBlock;
  239. class Param
  240. {
  241. public:
  242. // public to allow choice blocks to clear provided flag on stale choices
  243. void setProvided(bool is_provided) { mIsProvided = is_provided; }
  244. protected:
  245. bool getProvided() const { return mIsProvided; }
  246. Param(class BaseBlock* enclosing_block);
  247. // store pointer to enclosing block as offset to reduce space and allow for quick copying
  248. BaseBlock& enclosingBlock() const
  249. const U8* my_addr = reinterpret_cast<const U8*>(this);
  250. // get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
  251. return *const_cast<BaseBlock*>(
  252. reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
  253. }
  254. private:
  255. friend class BaseBlock;
  256. bool mIsProvided;
  257. U16 mEnclosingBlockOffset;
  258. };
  259. // various callbacks and constraints associated with an individual param
  260. struct ParamDescriptor
  261. {
  262. public:
  263. typedef bool(*merge_func_t)(Param&, const Param&, bool);
  264. typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);
  265. typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
  266. typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
  267. typedef bool(*validation_func_t)(const Param*);
  268. ParamDescriptor(param_handle_t p, 
  269. merge_func_t merge_func, 
  270. deserialize_func_t deserialize_func, 
  271. serialize_func_t serialize_func,
  272. validation_func_t validation_func,
  273. inspect_func_t inspect_func,
  274. S32 min_count,
  275. S32 max_count)
  276. : mParamHandle(p),
  277. mMergeFunc(merge_func),
  278. mDeserializeFunc(deserialize_func),
  279. mSerializeFunc(serialize_func),
  280. mValidationFunc(validation_func),
  281. mInspectFunc(inspect_func),
  282. mMinCount(min_count),
  283. mMaxCount(max_count),
  284. mGeneration(0),
  285. mNumRefs(0)
  286. {}
  287. ParamDescriptor()
  288. : mParamHandle(0),
  289. mMergeFunc(NULL),
  290. mDeserializeFunc(NULL),
  291. mSerializeFunc(NULL),
  292. mValidationFunc(NULL),
  293. mInspectFunc(NULL),
  294. mMinCount(0),
  295. mMaxCount(0),
  296. mGeneration(0),
  297. mNumRefs(0)
  298. {}
  299. param_handle_t mParamHandle;
  300. merge_func_t mMergeFunc;
  301. deserialize_func_t mDeserializeFunc;
  302. serialize_func_t mSerializeFunc;
  303. inspect_func_t mInspectFunc;
  304. validation_func_t mValidationFunc;
  305. S32 mMinCount;
  306. S32 mMaxCount;
  307. S32 mGeneration;
  308. S32 mNumRefs;
  309. };
  310. // each derived Block class keeps a static data structure maintaining offsets to various params
  311. class BlockDescriptor
  312. {
  313. public:
  314. BlockDescriptor()
  315. : mMaxParamOffset(0),
  316. mInitializationState(UNINITIALIZED),
  317. mCurrentBlockPtr(NULL)
  318. {}
  319. typedef enum e_initialization_state
  320. {
  321. UNINITIALIZED,
  322. INITIALIZING,
  323. INITIALIZED
  324. } EInitializationState;
  325. void aggregateBlockData(BlockDescriptor& src_block_data);
  326. public:
  327. typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
  328. typedef std::vector<ParamDescriptor*> param_list_t; 
  329. typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
  330. typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t;
  331. param_map_t mNamedParams; // parameters with associated names
  332. param_map_t mSynonyms; // parameters with alternate names
  333. param_list_t mUnnamedParams; // parameters with_out_ associated names
  334. param_validation_list_t mValidationList; // parameters that must be validated
  335. all_params_list_t mAllParams; // all parameters, owns descriptors
  336. size_t mMaxParamOffset;
  337. EInitializationState mInitializationState; // whether or not static block data has been initialized
  338. class BaseBlock* mCurrentBlockPtr; // pointer to block currently being constructed
  339. };
  340. class BaseBlock
  341. {
  342. public:
  343. // "Multiple" constraint types, put here in root class to avoid ambiguity during use
  344. struct AnyAmount
  345. {
  346. static U32 minCount() { return 0; }
  347. static U32 maxCount() { return U32_MAX; }
  348. };
  349. template<U32 MIN_AMOUNT>
  350. struct AtLeast
  351. {
  352. static U32 minCount() { return MIN_AMOUNT; }
  353. static U32 maxCount() { return U32_MAX; }
  354. };
  355. template<U32 MAX_AMOUNT>
  356. struct AtMost
  357. {
  358. static U32 minCount() { return 0; }
  359. static U32 maxCount() { return MAX_AMOUNT; }
  360. };
  361. template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
  362. struct Between
  363. {
  364. static U32 minCount() { return MIN_AMOUNT; }
  365. static U32 maxCount() { return MAX_AMOUNT; }
  366. };
  367. template<U32 EXACT_COUNT>
  368. struct Exactly
  369. {
  370. static U32 minCount() { return EXACT_COUNT; }
  371. static U32 maxCount() { return EXACT_COUNT; }
  372. };
  373. // this typedef identifies derived classes as being blocks
  374. typedef void baseblock_base_class_t;
  375. LOG_CLASS(BaseBlock);
  376. friend class Param;
  377. BaseBlock();
  378. virtual ~BaseBlock();
  379. bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
  380. param_handle_t getHandleFromParam(const Param* param) const;
  381. bool validateBlock(bool emit_errors = true) const;
  382. Param* getParamFromHandle(const param_handle_t param_handle)
  383. {
  384. if (param_handle == 0) return NULL;
  385. U8* baseblock_address = reinterpret_cast<U8*>(this);
  386. return reinterpret_cast<Param*>(baseblock_address + param_handle);
  387. }
  388. const Param* getParamFromHandle(const param_handle_t param_handle) const
  389. {
  390. const U8* baseblock_address = reinterpret_cast<const U8*>(this);
  391. return reinterpret_cast<const Param*>(baseblock_address + param_handle);
  392. }
  393. void addSynonym(Param& param, const std::string& synonym);
  394. // Blocks can override this to do custom tracking of changes
  395. virtual void setLastChangedParam(const Param& last_param, bool user_provided);
  396. S32 getLastChangeVersion() const { return mChangeVersion; }
  397. bool isDefault() const { return mChangeVersion == 0; }
  398. bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
  399. bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
  400. virtual bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
  401. const BlockDescriptor& getBlockDescriptor() const { return *mBlockDescriptor; }
  402. BlockDescriptor& getBlockDescriptor() { return *mBlockDescriptor; }
  403. // take all provided params from other and apply to self
  404. bool overwriteFrom(const BaseBlock& other)
  405. {
  406. return false;
  407. }
  408. // take all provided params that are not already provided, and apply to self
  409. bool fillFrom(const BaseBlock& other)
  410. {
  411. return false;
  412. }
  413. static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name);
  414. protected:
  415. void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
  416. // take all provided params from other and apply to self
  417. bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
  418. // can be updated in getters
  419. mutable S32 mChangeVersion;
  420. BlockDescriptor* mBlockDescriptor; // most derived block descriptor
  421. static BlockDescriptor& blockDescriptor()
  422. {
  423. static BlockDescriptor sBlockDescriptor;
  424. return sBlockDescriptor;
  425. }
  426. private:
  427. const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
  428. ParamDescriptor* findParamDescriptor(param_handle_t handle);
  429. };
  430. template<typename T>
  431. struct ParamIterator
  432. {
  433. typedef typename std::vector<T>::const_iterator const_iterator;
  434. typedef typename std::vector<T>::iterator iterator;
  435. };
  436. // these templates allow us to distinguish between template parameters
  437. // that derive from BaseBlock and those that don't
  438. // this is supposedly faster than boost::is_convertible and its ilk
  439. template<typename T, typename Void = void>
  440. struct IsBaseBlock
  441. {
  442. static const bool value = false;
  443. };
  444. template<typename T>
  445. struct IsBaseBlock<T, typename T::baseblock_base_class_t>
  446. {
  447. static const bool value = true;
  448. };
  449. // specialize for custom parsing/decomposition of specific classes
  450. // e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
  451. template<typename T,
  452. typename NAME_VALUE_LOOKUP = TypeValues<T>,
  453. bool HAS_MULTIPLE_VALUES = false,
  454. bool VALUE_IS_BLOCK = IsBaseBlock<T>::value>
  455. class TypedParam 
  456. : public Param
  457. {
  458. public:
  459. typedef const T& value_const_ref_t;
  460. typedef value_const_ref_t value_assignment_t;
  461. typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
  462. typedef TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK> self_t;
  463. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
  464. : Param(block_descriptor.mCurrentBlockPtr)
  465. {
  466. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  467. {
  468. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  469. &mergeWith,
  470. &deserializeParam,
  471. &serializeParam,
  472. validate_func,
  473. &inspectParam,
  474. min_count, max_count);
  475. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  476. }
  477. mData.mValue = value;
  478. bool isProvided() const { return Param::getProvided(); }
  479. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
  480. self_t& typed_param = static_cast<self_t&>(param);
  481. // no further names in stack, attempt to parse value now
  482. if (name_stack.first == name_stack.second)
  483. {
  484. if (parser.readValue<T>(typed_param.mData.mValue))
  485. {
  486. typed_param.setProvided(true);
  487. typed_param.enclosingBlock().setLastChangedParam(param, true);
  488. return true;
  489. }
  490. // try to parse a known named value
  491. if(!NAME_VALUE_LOOKUP::empty())
  492. {
  493. // try to parse a known named value
  494. std::string name;
  495. if (parser.readValue<std::string>(name))
  496. {
  497. // try to parse a per type named value
  498. if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue))
  499. {
  500. typed_param.mData.setKey(name);
  501. typed_param.setProvided(true);
  502. typed_param.enclosingBlock().setLastChangedParam(param, true);
  503. return true;
  504. }
  505. }
  506. }
  507. }
  508. return false;
  509. }
  510. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  511. {
  512. const self_t& typed_param = static_cast<const self_t&>(param);
  513. if (!typed_param.isProvided()) return;
  514. if (!name_stack.empty())
  515. {
  516. name_stack.back().second = parser.newParseGeneration();
  517. }
  518. std::string key = typed_param.mData.getKey();
  519. // first try to write out name of name/value pair
  520. if (!key.empty())
  521. {
  522. if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
  523. {
  524. if (!parser.writeValue<std::string>(key, name_stack))
  525. {
  526. return;
  527. }
  528. }
  529. }
  530. // then try to serialize value directly
  531. else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get())) {
  532. if (!parser.writeValue<T>(typed_param.mData.mValue, name_stack)) 
  533. {
  534. return;
  535. }
  536. }
  537. }
  538. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  539. {
  540. // tell parser about our actual type
  541. parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
  542. // then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
  543. if (NAME_VALUE_LOOKUP::getPossibleValues())
  544. {
  545. parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
  546. }
  547. }
  548. void set(value_assignment_t val, bool flag_as_provided = true)
  549. {
  550. mData.mValue = val;
  551. mData.clearKey();
  552. setProvided(flag_as_provided);
  553. Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
  554. }
  555. void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
  556. {
  557. if (!isProvided())
  558. {
  559. set(val, flag_as_provided);
  560. }
  561. }
  562. // implicit conversion
  563. operator value_assignment_t() const { return get(); } 
  564. // explicit conversion
  565. value_assignment_t operator()() const { return get(); } 
  566. protected:
  567. value_assignment_t get() const
  568. {
  569. return mData.mValue;
  570. }
  571. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  572. {
  573. const self_t& src_typed_param = static_cast<const self_t&>(src);
  574. self_t& dst_typed_param = static_cast<self_t&>(dst);
  575. if (src_typed_param.isProvided()
  576. && (overwrite || !dst_typed_param.isProvided()))
  577. {
  578. dst_typed_param.mData.clearKey();
  579. dst_typed_param = src_typed_param;
  580. return true;
  581. }
  582. return false;
  583. }
  584. struct Data : public key_cache_t
  585. {
  586. T mValue;
  587. };
  588. Data mData;
  589. };
  590. // parameter that is a block
  591. template <typename T, typename NAME_VALUE_LOOKUP>
  592. class TypedParam<T, NAME_VALUE_LOOKUP, false, true> 
  593. : public T,
  594. public Param
  595. {
  596. public:
  597. typedef const T value_const_t;
  598. typedef T value_t;
  599. typedef value_const_t& value_const_ref_t;
  600. typedef value_const_ref_t value_assignment_t;
  601. typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
  602. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true> self_t;
  603. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  604. : Param(block_descriptor.mCurrentBlockPtr),
  605. T(value)
  606. {
  607. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  608. {
  609. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  610. &mergeWith,
  611. &deserializeParam,
  612. &serializeParam,
  613. validate_func, 
  614. &inspectParam,
  615. min_count, max_count);
  616. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  617. }
  618. }
  619. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
  620. self_t& typed_param = static_cast<self_t&>(param);
  621. // attempt to parse block...
  622. if(typed_param.deserializeBlock(parser, name_stack))
  623. {
  624. typed_param.enclosingBlock().setLastChangedParam(param, true);
  625. return true;
  626. }
  627. if(!NAME_VALUE_LOOKUP::empty())
  628. {
  629. // try to parse a known named value
  630. std::string name;
  631. if (parser.readValue<std::string>(name))
  632. {
  633. // try to parse a per type named value
  634. if (NAME_VALUE_LOOKUP::get(name, typed_param))
  635. {
  636. typed_param.enclosingBlock().setLastChangedParam(param, true);
  637. typed_param.mData.setKey(name);
  638. typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion();
  639. return true;
  640. }
  641. }
  642. }
  643. return false;
  644. }
  645. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  646. {
  647. const self_t& typed_param = static_cast<const self_t&>(param);
  648. if (!name_stack.empty())
  649. {
  650. name_stack.back().second = parser.newParseGeneration();
  651. }
  652. std::string key = typed_param.mData.getKey();
  653. if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion())
  654. {
  655. if (!parser.writeValue<std::string>(key, name_stack))
  656. {
  657. return;
  658. }
  659. }
  660. else
  661. {
  662. typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
  663. }
  664. }
  665. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  666. {
  667. // I am a param that is also a block, so just recurse into my contents
  668. const self_t& typed_param = static_cast<const self_t&>(param);
  669. typed_param.inspectBlock(parser, name_stack);
  670. }
  671. // a param-that-is-a-block is provided when the user has set one of its child params
  672. // *and* the block as a whole validates
  673. bool isProvided() const 
  674. // only validate block when it hasn't already passed validation and user has supplied *some* value
  675. if (Param::getProvided() && mData.mValidatedVersion < T::getLastChangeVersion())
  676. {
  677. // a sub-block is "provided" when it has been filled in enough to be valid
  678. mData.mValidated = T::validateBlock(false);
  679. mData.mValidatedVersion = T::getLastChangeVersion();
  680. }
  681. return Param::getProvided() && mData.mValidated;
  682. }
  683. // assign block contents to this param-that-is-a-block
  684. void set(value_assignment_t val, bool flag_as_provided = true)
  685. {
  686. value_t::operator=(val);
  687. mData.clearKey();
  688. // force revalidation of block by clearing known provided version
  689. // next call to isProvided() will update provision status based on validity
  690. mData.mValidatedVersion = 0;
  691. setProvided(flag_as_provided);
  692. Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
  693. }
  694. void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
  695. {
  696. if (!isProvided())
  697. {
  698. set(val, flag_as_provided);
  699. }
  700. }
  701. // propagate changed status up to enclosing block
  702. /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
  703. T::setLastChangedParam(last_param, user_provided);
  704. Param::enclosingBlock().setLastChangedParam(*this, user_provided);
  705. if (user_provided)
  706. {
  707. // a child param has been explicitly changed
  708. // so *some* aspect of this block is now provided
  709. setProvided(true);
  710. }
  711. }
  712. // implicit conversion
  713. operator value_assignment_t() const { return get(); } 
  714. // explicit conversion
  715. value_assignment_t operator()() const { return get(); } 
  716. protected:
  717. value_assignment_t get() const
  718. {
  719. return *this;
  720. }
  721. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  722. {
  723. const self_t& src_typed_param = static_cast<const self_t&>(src);
  724. self_t& dst_typed_param = static_cast<self_t&>(dst);
  725. if (overwrite)
  726. {
  727. if (dst_typed_param.T::overwriteFrom(src_typed_param))
  728. {
  729. dst_typed_param.mData.clearKey();
  730. return true;
  731. }
  732. }
  733. else
  734. {
  735. if (dst_typed_param.T::fillFrom(src_typed_param))
  736. {
  737. dst_typed_param.mData.clearKey();
  738. return true;
  739. }
  740. }
  741. return false;
  742. }
  743. struct Data : public key_cache_t
  744. {
  745. S32  mKeyVersion;
  746. mutable S32  mValidatedVersion;
  747. mutable bool  mValidated; // lazy validation flag
  748. Data() 
  749. : mKeyVersion(0),
  750. mValidatedVersion(0),
  751. mValidated(false)
  752. {}
  753. };
  754. Data mData;
  755. };
  756. // container of non-block parameters
  757. template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
  758. class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> 
  759. : public Param
  760. {
  761. public:
  762. typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> self_t;
  763. typedef typename std::vector<VALUE_TYPE> container_t;
  764. typedef const container_t& value_assignment_t;
  765. typedef VALUE_TYPE value_t;
  766. typedef value_t& value_ref_t;
  767. typedef const value_t& value_const_ref_t;
  768. typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
  769. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
  770. : Param(block_descriptor.mCurrentBlockPtr),
  771. mValues(value)
  772. {
  773. mCachedKeys.resize(mValues.size());
  774. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  775. {
  776. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  777. &mergeWith,
  778. &deserializeParam,
  779. &serializeParam,
  780. validate_func,
  781. &inspectParam,
  782. min_count, max_count);
  783. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  784. }
  785. bool isProvided() const { return Param::getProvided(); }
  786. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
  787. self_t& typed_param = static_cast<self_t&>(param);
  788. value_t value;
  789. // no further names in stack, attempt to parse value now
  790. if (name_stack.first == name_stack.second)
  791. {
  792. // attempt to read value directly
  793. if (parser.readValue<value_t>(value))
  794. {
  795. typed_param.mValues.push_back(value);
  796. // save an empty name/value key as a placeholder
  797. typed_param.mCachedKeys.push_back(key_cache_t());
  798. typed_param.enclosingBlock().setLastChangedParam(param, true);
  799. typed_param.setProvided(true);
  800. return true;
  801. }
  802. // try to parse a known named value
  803. if(!NAME_VALUE_LOOKUP::empty())
  804. {
  805. // try to parse a known named value
  806. std::string name;
  807. if (parser.readValue<std::string>(name))
  808. {
  809. // try to parse a per type named value
  810. if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues))
  811. {
  812. typed_param.mValues.push_back(value);
  813. typed_param.mCachedKeys.push_back(key_cache_t());
  814. typed_param.mCachedKeys.back().setKey(name);
  815. typed_param.enclosingBlock().setLastChangedParam(param, true);
  816. typed_param.setProvided(true);
  817. return true;
  818. }
  819. }
  820. }
  821. }
  822. return false;
  823. }
  824. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  825. {
  826. const self_t& typed_param = static_cast<const self_t&>(param);
  827. if (!typed_param.isProvided() || name_stack.empty()) return;
  828. typename container_t::const_iterator it = typed_param.mValues.begin();
  829. for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin();
  830. it != typed_param.mValues.end();
  831. ++key_it, ++it)
  832. {
  833. std::string key = key_it->get();
  834. name_stack.back().second = parser.newParseGeneration();
  835. if(!key.empty())
  836. {
  837. if(!parser.writeValue<std::string>(key, name_stack))
  838. {
  839. return;
  840. }
  841. }
  842. // not parse via name values, write out value directly
  843. else if (!parser.writeValue<VALUE_TYPE>(*it, name_stack))
  844. {
  845. return;
  846. }
  847. }
  848. }
  849. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  850. {
  851. parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
  852. if (NAME_VALUE_LOOKUP::getPossibleValues())
  853. {
  854. parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues());
  855. }
  856. }
  857. void set(value_assignment_t val, bool flag_as_provided = true)
  858. {
  859. mValues = val;
  860. mCachedKeys.clear();
  861. mCachedKeys.resize(mValues.size());
  862. setProvided(flag_as_provided);
  863. Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
  864. }
  865. void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
  866. {
  867. if (!isProvided())
  868. {
  869. set(val, flag_as_provided);
  870. }
  871. }
  872. value_ref_t add()
  873. {
  874. mValues.push_back(value_t());
  875. mCachedKeys.push_back(key_cache_t());
  876. setProvided(true);
  877. return mValues.back();
  878. }
  879. void add(value_const_ref_t item)
  880. {
  881. mValues.push_back(item);
  882. mCachedKeys.push_back(key_cache_t());
  883. setProvided(true);
  884. }
  885. // implicit conversion
  886. operator value_assignment_t() const { return self_t::get(); } 
  887. // explicit conversion
  888. value_assignment_t operator()() const { return get(); } 
  889. U32 numValidElements() const
  890. {
  891. return mValues.size();
  892. }
  893. protected:
  894. value_assignment_t get() const
  895. {
  896. return mValues;
  897. }
  898. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  899. {
  900. const self_t& src_typed_param = static_cast<const self_t&>(src);
  901. self_t& dst_typed_param = static_cast<self_t&>(dst);
  902. if (src_typed_param.isProvided()
  903. && (overwrite || !isProvided()))
  904. {
  905. dst_typed_param = src_typed_param;
  906. return true;
  907. }
  908. return false;
  909. }
  910. container_t mValues;
  911. std::vector<key_cache_t> mCachedKeys;
  912. };
  913. // container of block parameters
  914. template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
  915. class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> 
  916. : public Param
  917. {
  918. public:
  919. typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> self_t;
  920. typedef typename std::vector<VALUE_TYPE> container_t;
  921. typedef const container_t& value_assignment_t;
  922. typedef VALUE_TYPE value_t;
  923. typedef value_t& value_ref_t;
  924. typedef const value_t& value_const_ref_t;
  925. typedef typename NAME_VALUE_LOOKUP::KeyCache key_cache_t;
  926. TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
  927. : Param(block_descriptor.mCurrentBlockPtr),
  928. mValues(value),
  929. mLastParamGeneration(0)
  930. {
  931. mCachedKeys.resize(mValues.size());
  932. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  933. {
  934. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  935. &mergeWith,
  936. &deserializeParam,
  937. &serializeParam,
  938. validate_func,
  939. &inspectParam,
  940. min_count, max_count);
  941. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  942. }
  943. bool isProvided() const { return Param::getProvided(); }
  944. value_ref_t operator[](S32 index) { return mValues[index]; }
  945. value_const_ref_t operator[](S32 index) const { return mValues[index]; }
  946. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
  947. self_t& typed_param = static_cast<self_t&>(param);
  948. if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty())
  949. {
  950. typed_param.mValues.push_back(value_t());
  951. typed_param.mCachedKeys.push_back(Data());
  952. typed_param.enclosingBlock().setLastChangedParam(param, true);
  953. typed_param.mLastParamGeneration = generation;
  954. }
  955. value_t& value = typed_param.mValues.back();
  956. // attempt to parse block...
  957. if(value.deserializeBlock(parser, name_stack))
  958. {
  959. typed_param.setProvided(true);
  960. return true;
  961. }
  962. if(!NAME_VALUE_LOOKUP::empty())
  963. {
  964. // try to parse a known named value
  965. std::string name;
  966. if (parser.readValue<std::string>(name))
  967. {
  968. // try to parse a per type named value
  969. if (NAME_VALUE_LOOKUP::get(name, value))
  970. {
  971. typed_param.mCachedKeys.back().setKey(name);
  972. typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion();
  973. typed_param.enclosingBlock().setLastChangedParam(param, true);
  974. typed_param.setProvided(true);
  975. return true;
  976. }
  977. }
  978. }
  979. return false;
  980. }
  981. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  982. {
  983. const self_t& typed_param = static_cast<const self_t&>(param);
  984. if (!typed_param.isProvided() || name_stack.empty()) return;
  985. typename container_t::const_iterator it = typed_param.mValues.begin();
  986. for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin();
  987. it != typed_param.mValues.end();
  988. ++key_it, ++it)
  989. {
  990. name_stack.back().second = parser.newParseGeneration();
  991. std::string key = key_it->getKey();
  992. if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion())
  993. {
  994. if(!parser.writeValue<std::string>(key, name_stack))
  995. {
  996. return;
  997. }
  998. }
  999. // Not parsed via named values, write out value directly
  1000. // NOTE: currently we don't worry about removing default values in Multiple
  1001. else if (!it->serializeBlock(parser, name_stack, NULL))
  1002. {
  1003. return;
  1004. }
  1005. }
  1006. }
  1007. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  1008. {
  1009. // I am a vector of blocks, so describe my contents recursively
  1010. value_t().inspectBlock(parser, name_stack);
  1011. }
  1012. void set(value_assignment_t val, bool flag_as_provided = true)
  1013. {
  1014. mValues = val;
  1015. mCachedKeys.clear();
  1016. mCachedKeys.resize(mValues.size());
  1017. setProvided(flag_as_provided);
  1018. Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
  1019. }
  1020. void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
  1021. {
  1022. if (!isProvided())
  1023. {
  1024. set(val, flag_as_provided);
  1025. }
  1026. }
  1027. value_ref_t add()
  1028. {
  1029. mValues.push_back(value_t());
  1030. mCachedKeys.push_back(Data());
  1031. setProvided(true);
  1032. return mValues.back();
  1033. }
  1034. void add(value_const_ref_t item)
  1035. {
  1036. mValues.push_back(item);
  1037. mCachedKeys.push_back(Data());
  1038. setProvided(true);
  1039. }
  1040. // implicit conversion
  1041. operator value_assignment_t() const { return self_t::get(); } 
  1042. // explicit conversion
  1043. value_assignment_t operator()() const { return get(); } 
  1044. U32 numValidElements() const
  1045. {
  1046. U32 count = 0;
  1047. for (typename container_t::const_iterator it = mValues.begin();
  1048. it != mValues.end();
  1049. ++it)
  1050. {
  1051. if(it->validateBlock(false)) count++;
  1052. }
  1053. return count;
  1054. }
  1055. protected:
  1056. value_assignment_t get() const
  1057. {
  1058. return mValues;
  1059. }
  1060. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  1061. {
  1062. const self_t& src_typed_param = static_cast<const self_t&>(src);
  1063. self_t& dst_typed_param = static_cast<self_t&>(dst);
  1064. if (src_typed_param.isProvided()
  1065. && (overwrite || !dst_typed_param.isProvided()))
  1066. {
  1067. dst_typed_param = src_typed_param;
  1068. return true;
  1069. }
  1070. return false;
  1071. }
  1072. struct Data : public key_cache_t
  1073. {
  1074. S32 mKeyVersion; // version of block for which key was last valid
  1075. Data() : mKeyVersion(0) {}
  1076. };
  1077. container_t mValues;
  1078. std::vector<Data> mCachedKeys;
  1079. S32 mLastParamGeneration;
  1080. };
  1081. template <typename DERIVED_BLOCK>
  1082. class Choice : public BaseBlock
  1083. {
  1084. typedef Choice<DERIVED_BLOCK> self_t;
  1085. typedef Choice<DERIVED_BLOCK> enclosing_block_t;
  1086. LOG_CLASS(self_t);
  1087. public:
  1088. // take all provided params from other and apply to self
  1089. bool overwriteFrom(const self_t& other)
  1090. {
  1091. mCurChoice = other.mCurChoice;
  1092. return BaseBlock::merge(blockDescriptor(), other, true);
  1093. }
  1094. // take all provided params that are not already provided, and apply to self
  1095. bool fillFrom(const self_t& other)
  1096. {
  1097. return false;
  1098. }
  1099. // clear out old choice when param has changed
  1100. /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
  1101. param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&last_param);
  1102. // if we have a new choice...
  1103. if (changed_param_handle != mCurChoice)
  1104. {
  1105. // clear provided flag on previous choice
  1106. Param* previous_choice = BaseBlock::getParamFromHandle(mCurChoice);
  1107. if (previous_choice) 
  1108. {
  1109. previous_choice->setProvided(false);
  1110. }
  1111. mCurChoice = changed_param_handle;
  1112. }
  1113. BaseBlock::setLastChangedParam(last_param, user_provided);
  1114. }
  1115. protected:
  1116. Choice()
  1117. : mCurChoice(0)
  1118. {
  1119. BaseBlock::init(blockDescriptor(), BaseBlock::blockDescriptor(), sizeof(DERIVED_BLOCK));
  1120. }
  1121. // Alternatives are mutually exclusive wrt other Alternatives in the same block.  
  1122. // One alternative in a block will always have isChosen() == true.
  1123. // At most one alternative in a block will have isProvided() == true.
  1124. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1125. class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1126. {
  1127. public:
  1128. friend class Choice<DERIVED_BLOCK>;
  1129. typedef Alternative<T, NAME_VALUE_LOOKUP> self_t;
  1130. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
  1131. typedef typename super_t::value_assignment_t value_assignment_t;
  1132. explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get())
  1133. : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1),
  1134. mOriginalValue(val)
  1135. {
  1136. // assign initial choice to first declared option
  1137. DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr);
  1138. if (DERIVED_BLOCK::blockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
  1139. && blockp->mCurChoice == 0)
  1140. {
  1141. blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
  1142. }
  1143. }
  1144. Alternative& operator=(value_assignment_t val)
  1145. {
  1146. super_t::set(val);
  1147. return *this;
  1148. }
  1149. void operator()(typename super_t::value_assignment_t val) 
  1150. super_t::set(val);
  1151. }
  1152. operator value_assignment_t() const 
  1153. if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
  1154. {
  1155. return super_t::get(); 
  1156. }
  1157. return mOriginalValue;
  1158. value_assignment_t operator()() const 
  1159. if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
  1160. {
  1161. return super_t::get(); 
  1162. }
  1163. return mOriginalValue;
  1164. bool isChosen() const
  1165. {
  1166. return static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this;
  1167. }
  1168. private:
  1169. T mOriginalValue;
  1170. };
  1171. protected:
  1172. static BlockDescriptor& blockDescriptor()
  1173. {
  1174. static BlockDescriptor sBlockDescriptor;
  1175. return sBlockDescriptor;
  1176. }
  1177. private:
  1178. param_handle_t mCurChoice;
  1179. const Param* getCurrentChoice() const
  1180. {
  1181. return BaseBlock::getParamFromHandle(mCurChoice);
  1182. }
  1183. };
  1184. template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
  1185. class Block 
  1186. : public BASE_BLOCK
  1187. {
  1188. typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t;
  1189. typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t;
  1190. public:
  1191. typedef BASE_BLOCK base_block_t;
  1192. // take all provided params from other and apply to self
  1193. bool overwriteFrom(const self_t& other)
  1194. {
  1195. return BaseBlock::merge(blockDescriptor(), other, true);
  1196. }
  1197. // take all provided params that are not already provided, and apply to self
  1198. bool fillFrom(const self_t& other)
  1199. {
  1200. return BaseBlock::merge(blockDescriptor(), other, false);
  1201. }
  1202. protected:
  1203. Block()
  1204. {
  1205. //#pragma message("Parsing LLInitParam::Block")
  1206. BaseBlock::init(blockDescriptor(), BASE_BLOCK::blockDescriptor(), sizeof(DERIVED_BLOCK));
  1207. }
  1208. //
  1209. // Nested classes for declaring parameters
  1210. //
  1211. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1212. class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1213. {
  1214. public:
  1215. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
  1216. typedef typename super_t::value_assignment_t value_assignment_t;
  1217. explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
  1218. : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1)
  1219. {
  1220. //#pragma message("Parsing LLInitParam::Block::Optional")
  1221. }
  1222. Optional& operator=(value_assignment_t val)
  1223. {
  1224. set(val);
  1225. return *this;
  1226. }
  1227. DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
  1228. {
  1229. super_t::set(val);
  1230. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1231. }
  1232. using super_t::operator();
  1233. };
  1234. template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1235. class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
  1236. {
  1237. public:
  1238. typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value> super_t;
  1239. typedef Mandatory<T, NAME_VALUE_LOOKUP> self_t;
  1240. typedef typename super_t::value_assignment_t value_assignment_t;
  1241. // mandatory parameters require a name to be parseable
  1242. explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
  1243. : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, 1, 1)
  1244. {}
  1245. Mandatory& operator=(value_assignment_t val)
  1246. {
  1247. set(val);
  1248. return *this;
  1249. }
  1250. DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
  1251. {
  1252. super_t::set(val);
  1253. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1254. }
  1255. using super_t::operator();
  1256. static bool validate(const Param* p)
  1257. {
  1258. // valid only if provided
  1259. return static_cast<const self_t*>(p)->isProvided();
  1260. }
  1261. };
  1262. template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
  1263. class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
  1264. {
  1265. public:
  1266. typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBaseBlock<T>::value> super_t;
  1267. typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP> self_t;
  1268. typedef typename super_t::container_t container_t;
  1269. typedef typename super_t::value_assignment_t value_assignment_t;
  1270. typedef typename container_t::iterator iterator;
  1271. typedef typename container_t::const_iterator const_iterator;
  1272. explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
  1273. : super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
  1274. {}
  1275. using super_t::operator();
  1276. Multiple& operator=(value_assignment_t val)
  1277. {
  1278. set(val);
  1279. return *this;
  1280. }
  1281. DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
  1282. {
  1283. super_t::set(val);
  1284. return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
  1285. }
  1286. static bool validate(const Param* paramp) 
  1287. {
  1288. U32 num_valid = ((super_t*)paramp)->numValidElements();
  1289. return RANGE::minCount() <= num_valid && num_valid <= RANGE::maxCount();
  1290. }
  1291. };
  1292. class Deprecated : public Param
  1293. {
  1294. public:
  1295. explicit Deprecated(const char* name)
  1296. : Param(DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr)
  1297. {
  1298. BlockDescriptor& block_descriptor = DERIVED_BLOCK::blockDescriptor();
  1299. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  1300. {
  1301. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  1302. NULL,
  1303. &deserializeParam,
  1304. NULL,
  1305. NULL,
  1306. NULL, 
  1307. 0, S32_MAX);
  1308. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  1309. }
  1310. }
  1311. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
  1312. {
  1313. if (name_stack.first == name_stack.second)
  1314. {
  1315. //std::string message = llformat("Deprecated value %s ignored", getName().c_str());
  1316. //parser.parserWarning(message);
  1317. return true;
  1318. }
  1319. return false;
  1320. }
  1321. };
  1322. typedef Deprecated Ignored;
  1323. protected:
  1324. static BlockDescriptor& blockDescriptor()
  1325. {
  1326. static BlockDescriptor sBlockDescriptor;
  1327. return sBlockDescriptor;
  1328. }
  1329. };
  1330. template<typename T, typename DERIVED = TypedParam<T> >
  1331. class BlockValue
  1332. : public Block<TypedParam<T, TypeValues<T>, false> >,
  1333. public Param
  1334. {
  1335. public:
  1336. typedef BlockValue<T> self_t;
  1337. typedef Block<TypedParam<T, TypeValues<T>, false> > block_t;
  1338. typedef const T& value_const_ref_t;
  1339. typedef value_const_ref_t value_assignment_t;
  1340. typedef typename TypeValues<T>::KeyCache key_cache_t;
  1341. BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
  1342. : Param(block_descriptor.mCurrentBlockPtr),
  1343. mData(value)
  1344. {
  1345. if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
  1346. {
  1347. ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
  1348. &mergeWith,
  1349. &deserializeParam,
  1350. &serializeParam,
  1351. validate_func,
  1352. &inspectParam,
  1353. min_count, max_count);
  1354. BaseBlock::addParam(block_descriptor, param_descriptor, name);
  1355. }
  1356. }
  1357. // implicit conversion
  1358. operator value_assignment_t() const { return get(); } 
  1359. // explicit conversion
  1360. value_assignment_t operator()() const { return get(); } 
  1361. static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
  1362. {
  1363. self_t& typed_param = static_cast<self_t&>(param);
  1364. // type to apply parse direct value T
  1365. if (name_stack.first == name_stack.second)
  1366. {
  1367. if(parser.readValue<T>(typed_param.mData.mValue))
  1368. {
  1369. typed_param.enclosingBlock().setLastChangedParam(param, true);
  1370. typed_param.setProvided(true);
  1371. typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
  1372. return true;
  1373. }
  1374. if(!TypeValues<T>::empty())
  1375. {
  1376. // try to parse a known named value
  1377. std::string name;
  1378. if (parser.readValue<std::string>(name))
  1379. {
  1380. // try to parse a per type named value
  1381. if (TypeValues<T>::get(name, typed_param.mData.mValue))
  1382. {
  1383. typed_param.mData.setKey(name);
  1384. typed_param.enclosingBlock().setLastChangedParam(param, true);
  1385. typed_param.setProvided(true);
  1386. typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
  1387. return true;
  1388. }
  1389. }
  1390. }
  1391. }
  1392. // fall back on parsing block components for T
  1393. // if we deserialized at least one component...
  1394. if (typed_param.BaseBlock::deserializeBlock(parser, name_stack))
  1395. {
  1396. // ...our block is provided, and considered changed
  1397. typed_param.enclosingBlock().setLastChangedParam(param, true);
  1398. typed_param.setProvided(true);
  1399. return true;
  1400. }
  1401. return false;
  1402. }
  1403. static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
  1404. {
  1405. const self_t& typed_param = static_cast<const self_t&>(param);
  1406. if (!typed_param.isProvided()) return;
  1407. std::string key = typed_param.mData.getKey();
  1408. // first try to write out name of name/value pair
  1409. if (!key.empty())
  1410. {
  1411. if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key))
  1412. {
  1413. if (!parser.writeValue<std::string>(key, name_stack))
  1414. {
  1415. return;
  1416. }
  1417. }
  1418. }
  1419. // then try to serialize value directly
  1420. else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))
  1421.             {
  1422. if (parser.writeValue<T>(typed_param.mData.mValue, name_stack)) 
  1423. {
  1424. return;
  1425. }
  1426. //RN: *always* serialize provided components of BlockValue (don't pass diff_param on),
  1427. // since these tend to be viewed as the constructor arguments for the value T.  It seems
  1428. // cleaner to treat the uniqueness of a BlockValue according to the generated value, and
  1429. // not the individual components.  This way <color red="0" green="1" blue="0"/> will not
  1430. // be exported as <color green="1"/>, since it was probably the intent of the user to 
  1431. // be specific about the RGB color values.  This also fixes an issue where we distinguish
  1432. // between rect.left not being provided and rect.left being explicitly set to 0 (same as default)
  1433. typed_param.BaseBlock::serializeBlock(parser, name_stack, NULL);
  1434. }
  1435. }
  1436. static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
  1437. {
  1438. // first, inspect with actual type...
  1439. parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
  1440. if (TypeValues<T>::getPossibleValues())
  1441. {
  1442. //...then inspect with possible string values...
  1443. parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
  1444. }
  1445. // then recursively inspect contents...
  1446. const self_t& typed_param = static_cast<const self_t&>(param);
  1447. typed_param.inspectBlock(parser, name_stack);
  1448. }
  1449. bool isProvided() const 
  1450. {
  1451. // either param value provided directly or block is sufficiently filled in
  1452. // if cached value is stale, regenerate from params
  1453. if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion())
  1454. {
  1455. if (block_t::validateBlock(false))
  1456. {
  1457. static_cast<const DERIVED*>(this)->setValueFromBlock();
  1458. // clear stale keyword associated with old value
  1459. mData.clearKey();
  1460. mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
  1461. return true;
  1462. }
  1463. else
  1464. {
  1465. //block value incomplete, so not considered provided
  1466. // will attempt to revalidate on next call to isProvided()
  1467. return false;  
  1468. }
  1469. }
  1470. // either no data provided, or we have a valid value in hand
  1471. return Param::getProvided();
  1472. }
  1473. void set(value_assignment_t val, bool flag_as_provided = true)
  1474. {
  1475. Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
  1476. // set param version number to be up to date, so we ignore block contents
  1477. mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
  1478. mData.mValue = val;
  1479. mData.clearKey();
  1480. setProvided(flag_as_provided);
  1481. static_cast<DERIVED*>(this)->setBlockFromValue();
  1482. }
  1483. void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true)
  1484. {
  1485. // don't override any user provided value
  1486. if (!isProvided())
  1487. {
  1488. set(val, flag_as_provided);
  1489. }
  1490. }
  1491.   // propagate change status up to enclosing block
  1492. /*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided)
  1493. BaseBlock::setLastChangedParam(last_param, user_provided);
  1494. Param::enclosingBlock().setLastChangedParam(*this, user_provided);
  1495. if (user_provided)
  1496. {
  1497. setProvided(true);  // some component provided
  1498. }
  1499. }
  1500. protected:
  1501. value_assignment_t get() const
  1502. {
  1503. // if some parameters were provided, issue warnings on invalid blocks
  1504. if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion()))
  1505. {
  1506. // go ahead and issue warnings at this point if any param is invalid
  1507. if(block_t::validateBlock(true))
  1508. {
  1509. static_cast<const DERIVED*>(this)->setValueFromBlock();
  1510. mData.clearKey();
  1511. mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
  1512. }
  1513. }
  1514. return mData.mValue;
  1515. }
  1516. // mutable to allow lazy updates on get
  1517. struct Data : public key_cache_t
  1518. {
  1519. Data(const T& value) 
  1520. : mValue(value),
  1521. mLastParamVersion(0)
  1522. {}
  1523. T mValue;
  1524. S32 mLastParamVersion;
  1525. };
  1526. mutable Data mData;
  1527. private:
  1528. static bool mergeWith(Param& dst, const Param& src, bool overwrite)
  1529. {
  1530. const self_t& src_typed_param = static_cast<const self_t&>(src);
  1531. self_t& dst_typed_param = static_cast<self_t&>(dst);
  1532. if (src_typed_param.isProvided()
  1533. && (overwrite || !dst_typed_param.isProvided()))
  1534. {
  1535. // assign individual parameters
  1536. dst_typed_param.BaseBlock::merge(block_t::blockDescriptor(), src_typed_param, overwrite);
  1537. // then copy actual value
  1538. dst_typed_param.mData.mValue = src_typed_param.get();
  1539. dst_typed_param.mData.clearKey();
  1540. dst_typed_param.setProvided(true);
  1541. // Propagate value back to block params since the value was updated during this merge.
  1542. // This will result in mData.mValue and the block params being in sync.
  1543. static_cast<DERIVED&>(dst_typed_param).setBlockFromValue();
  1544. return true;
  1545. }
  1546. return false;
  1547. }
  1548. };
  1549. template<> 
  1550. struct ParamCompare<LLSD, false>
  1551. {
  1552. static bool equals(const LLSD &a, const LLSD &b);
  1553. };
  1554. }
  1555. #endif // LL_LLPARAM_H