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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llregistry.h
  3.  * @brief template classes for registering name, value pairs in nested scopes, statically, etc.
  4.  *
  5.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2001-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #ifndef LL_LLREGISTRY_H
  33. #define LL_LLREGISTRY_H
  34. #include <list>
  35. #include <boost/type_traits.hpp>
  36. #include "llsingleton.h"
  37. template <typename T>
  38. class LLRegistryDefaultComparator
  39. {
  40. bool operator()(const T& lhs, const T& rhs) { return lhs < rhs; }
  41. };
  42. template <typename KEY, typename VALUE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
  43. class LLRegistry
  44. {
  45. public:
  46. typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
  47. typedef typename boost::add_reference<typename boost::add_const<KEY>::type>::type ref_const_key_t;
  48. typedef typename boost::add_reference<typename boost::add_const<VALUE>::type>::type ref_const_value_t;
  49. typedef typename boost::add_reference<VALUE>::type ref_value_t;
  50. typedef typename boost::add_pointer<typename boost::add_const<VALUE>::type>::type ptr_const_value_t;
  51. typedef typename boost::add_pointer<VALUE>::type ptr_value_t;
  52. class Registrar
  53. {
  54. friend class LLRegistry<KEY, VALUE, COMPARATOR>;
  55. public:
  56. typedef typename std::map<KEY, VALUE> registry_map_t;
  57. bool add(ref_const_key_t key, ref_const_value_t value)
  58. {
  59. if (mMap.insert(std::make_pair(key, value)).second == false)
  60. {
  61. llwarns << "Tried to register " << key << " but it was already registered!" << llendl;
  62. return false;
  63. }
  64. return true;
  65. }
  66. void remove(ref_const_key_t key)
  67. {
  68. mMap.erase(key);
  69. }
  70. typename registry_map_t::const_iterator beginItems() const
  71. {
  72. return mMap.begin();
  73. }
  74. typename registry_map_t::const_iterator endItems() const
  75. {
  76. return mMap.end();
  77. }
  78. protected:
  79. ptr_value_t getValue(ref_const_key_t key)
  80. {
  81. typename registry_map_t::iterator found_it = mMap.find(key);
  82. if (found_it != mMap.end())
  83. {
  84. return &(found_it->second);
  85. }
  86. return NULL;
  87. }
  88. ptr_const_value_t getValue(ref_const_key_t key) const
  89. {
  90. typename registry_map_t::const_iterator found_it = mMap.find(key);
  91. if (found_it != mMap.end())
  92. {
  93. return &(found_it->second);
  94. }
  95. return NULL;
  96. }
  97. // if the registry is used to store pointers, and null values are valid entries
  98. // then use this function to check the existence of an entry
  99. bool exists(ref_const_key_t key) const
  100. {
  101. return mMap.find(key) != mMap.end();
  102. }
  103. bool empty() const
  104. {
  105. return mMap.empty();
  106. }
  107. protected:
  108. // use currentRegistrar() or defaultRegistrar()
  109. Registrar() {}
  110. ~Registrar() {}
  111. private:
  112. registry_map_t mMap;
  113. };
  114. typedef typename std::list<Registrar*> scope_list_t;
  115. typedef typename std::list<Registrar*>::iterator scope_list_iterator_t;
  116. typedef typename std::list<Registrar*>::const_iterator scope_list_const_iterator_t;
  117. LLRegistry() 
  118. {}
  119. ~LLRegistry() {}
  120. ptr_value_t getValue(ref_const_key_t key)
  121. {
  122. for(scope_list_iterator_t it = mActiveScopes.begin();
  123. it != mActiveScopes.end();
  124. ++it)
  125. {
  126. ptr_value_t valuep = (*it)->getValue(key);
  127. if (valuep != NULL) return valuep;
  128. }
  129. return mDefaultRegistrar.getValue(key);
  130. }
  131. ptr_const_value_t getValue(ref_const_key_t key) const
  132. {
  133. for(scope_list_const_iterator_t it = mActiveScopes.begin();
  134. it != mActiveScopes.end();
  135. ++it)
  136. {
  137. ptr_value_t valuep = (*it)->getValue(key);
  138. if (valuep != NULL) return valuep;
  139. }
  140. return mDefaultRegistrar.getValue(key);
  141. }
  142. bool exists(ref_const_key_t key) const
  143. {
  144. for(scope_list_const_iterator_t it = mActiveScopes.begin();
  145. it != mActiveScopes.end();
  146. ++it)
  147. {
  148. if ((*it)->exists(key)) return true;
  149. }
  150. return mDefaultRegistrar.exists(key);
  151. }
  152. bool empty() const
  153. {
  154. for(scope_list_const_iterator_t it = mActiveScopes.begin();
  155. it != mActiveScopes.end();
  156. ++it)
  157. {
  158. if (!(*it)->empty()) return false;
  159. }
  160. return mDefaultRegistrar.empty();
  161. }
  162. Registrar& defaultRegistrar()
  163. {
  164. return mDefaultRegistrar;
  165. }
  166. const Registrar& defaultRegistrar() const
  167. {
  168. return mDefaultRegistrar;
  169. }
  170. Registrar& currentRegistrar()
  171. {
  172. if (!mActiveScopes.empty()) 
  173. {
  174. return *mActiveScopes.front();
  175. }
  176. return mDefaultRegistrar;
  177. }
  178. const Registrar& currentRegistrar() const
  179. {
  180. if (!mActiveScopes.empty()) 
  181. {
  182. return *mActiveScopes.front();
  183. }
  184. return mDefaultRegistrar;
  185. }
  186. protected:
  187. void addScope(Registrar* scope)
  188. {
  189. // newer scopes go up front
  190. mActiveScopes.insert(mActiveScopes.begin(), scope);
  191. }
  192. void removeScope(Registrar* scope)
  193. {
  194. // O(N) but should be near the beggining and N should be small and this is safer than storing iterators
  195. scope_list_iterator_t iter = std::find(mActiveScopes.begin(), mActiveScopes.end(), scope);
  196. if (iter != mActiveScopes.end())
  197. {
  198. mActiveScopes.erase(iter);
  199. }
  200. }
  201. private:
  202. scope_list_t mActiveScopes;
  203. Registrar mDefaultRegistrar;
  204. };
  205. template <typename KEY, typename VALUE, typename DERIVED_TYPE, typename COMPARATOR = LLRegistryDefaultComparator<KEY> >
  206. class LLRegistrySingleton
  207. : public LLRegistry<KEY, VALUE, COMPARATOR>,
  208. public LLSingleton<DERIVED_TYPE>
  209. {
  210. friend class LLSingleton<DERIVED_TYPE>;
  211. public:
  212. typedef LLRegistry<KEY, VALUE, COMPARATOR> registry_t;
  213. typedef const KEY& ref_const_key_t;
  214. typedef const VALUE& ref_const_value_t;
  215. typedef VALUE* ptr_value_t;
  216. typedef const VALUE* ptr_const_value_t;
  217. typedef LLSingleton<DERIVED_TYPE> singleton_t;
  218. class ScopedRegistrar : public registry_t::Registrar
  219. {
  220. public:
  221. ScopedRegistrar(bool push_scope = true) 
  222. {
  223. if (push_scope)
  224. {
  225. pushScope();
  226. }
  227. }
  228. ~ScopedRegistrar()
  229. {
  230. if (!singleton_t::destroyed())
  231. {
  232. popScope();
  233. }
  234. }
  235. void pushScope()
  236. {
  237. singleton_t::instance().addScope(this);
  238. }
  239. void popScope()
  240. {
  241. singleton_t::instance().removeScope(this);
  242. }
  243. ptr_value_t getValueFromScope(ref_const_key_t key)
  244. {
  245. return getValue(key);
  246. }
  247. ptr_const_value_t getValueFromScope(ref_const_key_t key) const
  248. {
  249. return getValue(key);
  250. }
  251. private:
  252. typename std::list<typename registry_t::Registrar*>::iterator mListIt;
  253. };
  254. class StaticRegistrar : public registry_t::Registrar
  255. {
  256. public:
  257. virtual ~StaticRegistrar() {}
  258. StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
  259. {
  260. singleton_t::instance().mStaticScope->add(key, value);
  261. }
  262. };
  263. // convenience functions
  264. typedef typename LLRegistry<KEY, VALUE, COMPARATOR>::Registrar& ref_registrar_t;
  265. static ref_registrar_t currentRegistrar()
  266. {
  267. return singleton_t::instance().registry_t::currentRegistrar();
  268. }
  269. static ref_registrar_t defaultRegistrar()
  270. {
  271. return singleton_t::instance().registry_t::defaultRegistrar();
  272. }
  273. static ptr_value_t getValue(ref_const_key_t key)
  274. {
  275. return singleton_t::instance().registry_t::getValue(key);
  276. }
  277. protected:
  278. // DERIVED_TYPE needs to derive from LLRegistrySingleton
  279. LLRegistrySingleton()
  280. : mStaticScope(NULL)
  281. {}
  282. virtual void initSingleton()
  283. {
  284. mStaticScope = new ScopedRegistrar();
  285. }
  286. virtual ~LLRegistrySingleton() 
  287. {
  288. delete mStaticScope;
  289. }
  290. private:
  291. ScopedRegistrar* mStaticScope;
  292. };
  293. #endif