Property.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. #ifndef ANKI_SCENE_PROPERTY_H
  2. #define ANKI_SCENE_PROPERTY_H
  3. #include "anki/util/Observer.h"
  4. #include "anki/util/Exception.h"
  5. #include "anki/util/Assert.h"
  6. #include "anki/util/NonCopyable.h"
  7. #include "anki/util/Visitor.h"
  8. #include "anki/Math.h"
  9. #include "anki/resource/Resource.h"
  10. #include "anki/resource/TextureResource.h"
  11. #include "anki/Collision.h"
  12. #include "anki/util/Dictionary.h"
  13. namespace anki {
  14. // Forward
  15. class PropertyBase;
  16. template<typename T>
  17. class Property;
  18. typedef VisitableCommonBase<
  19. PropertyBase, // Base
  20. // Misc
  21. Property<std::string>, Property<bool>, Property<float>,
  22. Property<TextureResourcePointer>,
  23. // Math
  24. Property<Vec2>, Property<Vec3>, Property<Vec4>, Property<Mat3>,
  25. Property<Mat4>, Property<Transform>,
  26. // Collision
  27. Property<OrthographicFrustum>, Property<PerspectiveFrustum>>
  28. PropertyVisitable;
  29. /// Base class for property
  30. class PropertyBase: public NonCopyable, public PropertyVisitable
  31. {
  32. public:
  33. /// @name Constructors/Destructor
  34. /// @{
  35. PropertyBase(const char* name_)
  36. : name(name_)
  37. {}
  38. virtual ~PropertyBase()
  39. {}
  40. /// @}
  41. /// @name Accessors
  42. /// @{
  43. const std::string& getName() const
  44. {
  45. return name;
  46. }
  47. /// Get the property value. Throws if the @a T is incorrect
  48. template<typename TValue>
  49. const TValue& getValue() const
  50. {
  51. checkType<TValue>();
  52. return static_cast<const Property<TValue>*>(this)->getValue();
  53. }
  54. /// Set the property value. Throws if the @a T is incorrect
  55. template<typename TValue>
  56. void setValue(const TValue& x)
  57. {
  58. checkType<TValue>();
  59. return static_cast<Property<TValue>*>(this)->setValue(x);
  60. }
  61. /// @}
  62. /// Upcast to property. It makes a runtime check
  63. template<typename TProp>
  64. TProp& upCast()
  65. {
  66. checkType<TProp::Value>();
  67. return static_cast<TProp&>(*this);
  68. }
  69. private:
  70. std::string name;
  71. /// Runtime type checking
  72. template<typename TValue>
  73. void checkType() const
  74. {
  75. if(PropertyVisitable::getVariadicTypeId<Property<TValue>>() !=
  76. getVisitableTypeId())
  77. {
  78. throw ANKI_EXCEPTION("Types do not match: " + name);
  79. }
  80. }
  81. };
  82. /// Property interface
  83. template<typename T>
  84. class Property: public PropertyBase
  85. {
  86. public:
  87. typedef T Value;
  88. typedef Property<Value> Self;
  89. /// @name Constructors/Destructor
  90. /// @{
  91. /// Read only property
  92. Property(const char* name)
  93. : PropertyBase(name)
  94. {
  95. setupVisitable(this);
  96. }
  97. /// @}
  98. /// @name Accessors
  99. /// @{
  100. virtual const Value& getValue() const
  101. {
  102. throw ANKI_EXCEPTION("Property is not readable: " + getName());
  103. }
  104. /// Set the value and emit the signal valueChanged
  105. virtual void setValue(const Value& x)
  106. {
  107. (void)x;
  108. throw ANKI_EXCEPTION("Property is not writable: " + getName());
  109. }
  110. /// @}
  111. /// Signal that it is emitted when the value gets changed
  112. ANKI_SIGNAL(const Value&, valueChanged)
  113. };
  114. /// Read only property
  115. template<typename T>
  116. class ReadProperty: public Property<T>
  117. {
  118. public:
  119. typedef T Value;
  120. typedef Property<T> Base;
  121. /// @name Constructors/Destructor
  122. /// @{
  123. ReadProperty(const char* name, const Value& initialValue)
  124. : Base(name), x(initialValue)
  125. {}
  126. /// @}
  127. /// @name Accessors
  128. /// @{
  129. /// Overrides Property::getValue()
  130. const Value& getValue() const
  131. {
  132. return x;
  133. }
  134. /// @}
  135. private:
  136. Value x;
  137. };
  138. /// Read write property
  139. template<typename T>
  140. class ReadWriteProperty: public Property<T>
  141. {
  142. public:
  143. typedef T Value;
  144. typedef Property<T> Base;
  145. /// @name Constructors/Destructor
  146. /// @{
  147. ReadWriteProperty(const char* name, const Value& initialValue)
  148. : Base(name), x(initialValue)
  149. {}
  150. /// @}
  151. /// @name Accessors
  152. /// @{
  153. /// Overrides Property::getValue()
  154. const Value& getValue() const
  155. {
  156. return x;
  157. }
  158. /// Overrides Property::setValue()
  159. virtual void setValue(const Value& x_)
  160. {
  161. x = x_;
  162. ANKI_EMIT valueChanged(x);
  163. }
  164. /// @}
  165. private:
  166. Value x;
  167. };
  168. /// Read only property that holds a reference to a value
  169. template<typename T>
  170. class ReadPointerProperty: public Property<T>
  171. {
  172. public:
  173. typedef T Value;
  174. typedef Property<T> Base;
  175. /// @name Constructors/Destructor
  176. /// @{
  177. ReadPointerProperty(const char* name, const Value* ptr_)
  178. : Base(name), ptr(ptr_)
  179. {}
  180. /// @}
  181. /// @name Accessors
  182. /// @{
  183. /// Overrides Property::getValue()
  184. const Value& getValue() const
  185. {
  186. return *ptr;
  187. }
  188. /// @}
  189. private:
  190. const Value* ptr;
  191. };
  192. /// Read write property that alters a reference to the value
  193. template<typename T>
  194. class ReadWritePointerProperty: public Property<T>
  195. {
  196. public:
  197. typedef T Value;
  198. typedef Property<T> Base;
  199. /// @name Constructors/Destructor
  200. /// @{
  201. ReadWritePointerProperty(const char* name, Value* x)
  202. : Base(name), ptr(x)
  203. {}
  204. /// @}
  205. /// @name Accessors
  206. /// @{
  207. /// Overrides Property::getValue()
  208. const Value& getValue() const
  209. {
  210. return *ptr;
  211. }
  212. /// Overrides Property::setValue()
  213. virtual void setValue(const Value& x)
  214. {
  215. *ptr = x;
  216. ANKI_EMIT valueChanged(x);
  217. }
  218. /// @}
  219. private:
  220. Value* ptr;
  221. };
  222. /// Read and Copy on Write property
  223. template<typename T>
  224. class ReadCowPointerProperty: public Property<T>
  225. {
  226. public:
  227. typedef T Value;
  228. typedef Property<T> Base;
  229. /// @name Constructors/Destructor
  230. /// @{
  231. ReadCowPointerProperty(const char* name, const Value* x)
  232. : Base(name), ptr(x)
  233. {}
  234. /// @}
  235. /// @name Accessors
  236. /// @{
  237. /// Overrides Property::getValue()
  238. const Value& getValue() const
  239. {
  240. if(sptr.get())
  241. {
  242. return *sptr;
  243. }
  244. else
  245. {
  246. return *ptr;
  247. }
  248. }
  249. /// Overrides Property::setValue()
  250. virtual void setValue(const Value& x)
  251. {
  252. if(sptr.get())
  253. {
  254. *sptr = x;
  255. }
  256. else
  257. {
  258. sptr.reset(new Value(x));
  259. }
  260. ANKI_EMIT valueChanged(x);
  261. }
  262. /// @}
  263. private:
  264. const Value* ptr;
  265. std::unique_ptr<Value> sptr;
  266. };
  267. /// A set of properties
  268. class PropertyMap
  269. {
  270. public:
  271. typedef Vector<PropertyBase*> Container;
  272. typedef Dictionary<PropertyBase*> NameToPropertyMap;
  273. /// Add new property to the map. The map gets the ownership of this
  274. /// property
  275. template<typename T>
  276. Property<T>& addNewProperty(Property<T>* newp)
  277. {
  278. if(propertyExists(newp->getName().c_str()))
  279. {
  280. throw ANKI_EXCEPTION("Property already exists: " + newp->getName());
  281. }
  282. props.push_back(newp);
  283. map[newp->getName().c_str()] = newp;
  284. return *newp;
  285. }
  286. /// Self explanatory
  287. const PropertyBase& findPropertyBaseByName(const char* name) const
  288. {
  289. NameToPropertyMap::const_iterator it = map.find(name);
  290. if(it == map.end())
  291. {
  292. throw ANKI_EXCEPTION("Property not found: " + name);
  293. }
  294. return *(it->second);
  295. }
  296. /// Self explanatory
  297. PropertyBase& findPropertyBaseByName(const char* name)
  298. {
  299. NameToPropertyMap::iterator it = map.find(name);
  300. if(it == map.end())
  301. {
  302. throw ANKI_EXCEPTION("Property not found: " + name);
  303. }
  304. return *(it->second);
  305. }
  306. /// Alias for findPropertyBaseByName
  307. const PropertyBase& operator[](const char* name) const
  308. {
  309. return findPropertyBaseByName(name);
  310. }
  311. /// Alias for findPropertyBaseByName
  312. PropertyBase& operator[](const char* name)
  313. {
  314. return findPropertyBaseByName(name);
  315. }
  316. /// Return true if the property named @a name exists
  317. bool propertyExists(const char* name) const
  318. {
  319. return map.find(name) != map.end();
  320. }
  321. /// Set the value of a property. It may throw
  322. template<typename T>
  323. void setValue(const char* name, const T& v)
  324. {
  325. findPropertyBaseByName(name).setValue<T>(v);
  326. }
  327. private:
  328. Container props;
  329. NameToPropertyMap map;
  330. };
  331. } // end namespace anki
  332. #endif