Simulant  21.12-574
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
property_value.h
1 #pragma once
2 
3 #include <cstdint>
4 #include "../../math/vec2.h"
5 #include "../../math/vec3.h"
6 #include "../../math/vec4.h"
7 #include "../../math/mat3.h"
8 #include "../../math/mat4.h"
9 #include "../../types.h"
10 #include "../../core/memory.h"
11 
12 namespace smlt {
13 
14 enum MaterialPropertyType {
15  MATERIAL_PROPERTY_TYPE_BOOL,
16  MATERIAL_PROPERTY_TYPE_INT,
17  MATERIAL_PROPERTY_TYPE_FLOAT,
18  MATERIAL_PROPERTY_TYPE_VEC2,
19  MATERIAL_PROPERTY_TYPE_VEC3,
20  MATERIAL_PROPERTY_TYPE_VEC4,
21  MATERIAL_PROPERTY_TYPE_MAT3,
22  MATERIAL_PROPERTY_TYPE_MAT4,
23  MATERIAL_PROPERTY_TYPE_TEXTURE
24 };
25 
26 
27 namespace _impl {
28  template<typename T>
30 
31  template<>
32  struct material_property_lookup<bool> {
33  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_BOOL;
34  };
35 
36  template<>
37  struct material_property_lookup<int32_t> {
38  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_INT;
39  };
40 
41  template<>
42  struct material_property_lookup<float> {
43  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_FLOAT;
44  };
45 
46  template<>
48  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_VEC2;
49  };
50 
51  template<>
53  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_VEC3;
54  };
55 
56  template<>
58  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_VEC4;
59  };
60 
61  template<>
63  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_MAT3;
64  };
65 
66  template<>
68  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_MAT4;
69  };
70 
71  template<>
72  struct material_property_lookup<TexturePtr> {
73  const static MaterialPropertyType type = MATERIAL_PROPERTY_TYPE_TEXTURE;
74  };
75 }
76 
77 template<typename T = void> struct PropertyValue;
78 
80  template<typename T>
81  T* get() const {
82  T* result;
83  do_get(&result);
84  return result;
85  }
86 
87  template<typename T>
88  bool set(const T& value) {
89  return do_set(value);
90  }
91 
92  virtual bool has_value() const = 0;
93  virtual void clear() = 0;
94 
95 private:
96  virtual void do_get(bool** result) const { *result = nullptr; }
97  virtual void do_get(int32_t** result) const { *result = nullptr; }
98  virtual void do_get(float** result) const { *result = nullptr; }
99  virtual void do_get(Vec2** result) const { *result = nullptr; }
100  virtual void do_get(Vec3** result) const { *result = nullptr; }
101  virtual void do_get(Vec4** result) const { *result = nullptr; }
102  virtual void do_get(Mat3** result) const { *result = nullptr; }
103  virtual void do_get(Mat4** result) const { *result = nullptr; }
104  virtual void do_get(TexturePtr** result) const { *result = nullptr; }
105 
106  virtual bool do_set(const bool& value) { S_WARN("Invalid value for property: {0}", value); return false; }
107  virtual bool do_set(const int32_t& value) { S_WARN("Invalid value for property: {0}", value); return false; }
108  virtual bool do_set(const float& value) { S_WARN("Invalid value for property: {0}", value); return false; }
109  virtual bool do_set(const Vec2& value) { S_WARN("Invalid value for property: {0}", value); return false; }
110  virtual bool do_set(const Vec3& value) { S_WARN("Invalid value for property: {0}", value); return false; }
111  virtual bool do_set(const Vec4& value) { S_WARN("Invalid value for property: {0}", value); return false; }
112  virtual bool do_set(const Mat3& value) { S_WARN("Invalid value for property: {0}", value); return false; }
113  virtual bool do_set(const Mat4& value) { _S_UNUSED(value); S_WARN("Invalid value for property"); return false; }
114  virtual bool do_set(const TexturePtr& value) { S_WARN("Invalid value for property: {0}", value); return false; }
115 
116  void do_get(Colour** result) const {
117  do_get((Vec4**) result);
118  }
119 
120  void do_get(uint32_t** result) const {
121  do_get((int32_t**) result);
122  }
123 
124  bool do_set(const Colour& value) { return do_set((const Vec4&) value); }
125 
126  /* FIXME: Support these types properly */
127  bool do_set(const int16_t& value) { return do_set((int32_t) value); }
128  bool do_set(const uint32_t& value) { return do_set((int32_t) value); }
129  bool do_set(const uint16_t& value) { return do_set((int32_t) value); }
130 
131 };
132 
133 template<typename T>
135  bool is_set_ = false;
136  T data;
137 
138  PropertyValue() = default;
139  PropertyValue(T* value) {
140  set(value);
141  }
142 
143  PropertyValue(const PropertyValue& rhs) = default;
144  PropertyValue(PropertyValue&& rhs) noexcept :
145  is_set_(rhs.is_set_),
146  data(std::move(rhs.data)) {}
147 
148  PropertyValue& operator=(const PropertyValue& ) = default;
149 
150  void clear() override {
151  is_set_ = false;
152  }
153 
154  bool has_value() const override {
155  return is_set_;
156  }
157 private:
158  void do_get(T** result) const override {
159  *result = (T*) &data;
160  }
161 
162  bool do_set(const T& value) override {
163  data = value;
164  is_set_ = true;
165  return true;
166  }
167 };
168 
169 template<>
170 struct PropertyValue<void> : public BasePropertyValue {
171  MaterialPropertyType type;
172  uint8_t* data = nullptr;
173 
174  PropertyValue() = default;
175 
176  template<typename T>
177  PropertyValue(T value) {
178  set(value);
179  }
180 
181  PropertyValue& operator=(const PropertyValue& rhs) {
182  switch(rhs.type) {
183  case MATERIAL_PROPERTY_TYPE_BOOL:
184  set(*rhs.get<bool>());
185  break;
186  case MATERIAL_PROPERTY_TYPE_INT:
187  set(*rhs.get<int32_t>());
188  break;
189  case MATERIAL_PROPERTY_TYPE_FLOAT:
190  set(*rhs.get<float>());
191  break;
192  case MATERIAL_PROPERTY_TYPE_VEC2:
193  set(*rhs.get<Vec2>());
194  break;
195  case MATERIAL_PROPERTY_TYPE_VEC3:
196  set(*rhs.get<Vec3>());
197  break;
198  case MATERIAL_PROPERTY_TYPE_VEC4:
199  set(*rhs.get<Vec4>());
200  break;
201  case MATERIAL_PROPERTY_TYPE_MAT3:
202  set(*rhs.get<Mat3>());
203  break;
204  case MATERIAL_PROPERTY_TYPE_MAT4:
205  set(*rhs.get<Mat4>());
206  break;
207  case MATERIAL_PROPERTY_TYPE_TEXTURE:
208  set(*rhs.get<TexturePtr>());
209  break;
210  }
211 
212  return *this;
213  }
214 
215  PropertyValue(PropertyValue&& rhs) noexcept :
216  type(std::move(rhs.type)),
217  data(rhs.data) {
218  rhs.data = nullptr;
219  }
220 
221  PropertyValue(const PropertyValue& rhs) {
222  *this = rhs;
223  }
224 
225  ~PropertyValue() {
226  if(data) {
227  clear();
228  }
229  }
230 
231  void clear() override {
232  if(!data) {
233  return;
234  }
235 
236  switch(type) {
237  case MATERIAL_PROPERTY_TYPE_BOOL:
238  unset<bool>();
239  break;
240  case MATERIAL_PROPERTY_TYPE_INT:
241  unset<int32_t>();
242  break;
243  case MATERIAL_PROPERTY_TYPE_FLOAT:
244  unset<float>();
245  break;
246  case MATERIAL_PROPERTY_TYPE_VEC2:
247  unset<Vec2>();
248  break;
249  case MATERIAL_PROPERTY_TYPE_VEC3:
250  unset<Vec3>();
251  break;
252  case MATERIAL_PROPERTY_TYPE_VEC4:
253  unset<Vec4>();
254  break;
255  case MATERIAL_PROPERTY_TYPE_MAT3:
256  unset<Mat3>();
257  break;
258  case MATERIAL_PROPERTY_TYPE_MAT4:
259  unset<Mat4>();
260  break;
261  case MATERIAL_PROPERTY_TYPE_TEXTURE:
262  unset<TexturePtr>();
263  break;
264  }
265 
266  data = nullptr;
267  }
268 
269  template<typename T>
270  T* get() const {
271  return (T*) data;
272  }
273 
274  template<typename T>
275  void unset() {
276  ((T*) data)->~T();
277  free(data);
278  data = nullptr;
279  }
280 
281  bool has_value() const override {
282  return bool(data);
283  }
284 private:
285  template<typename T>
286  bool _set(const T& value) {
287  clear();
288 
289  data = (uint8_t*) smlt::aligned_alloc(alignof(T), sizeof(T));
290  assert(data);
291  new (data) T(value);
293 
294  return true;
295  }
296 
297  bool do_set(const bool& value) override { return _set(value); }
298  bool do_set(const int32_t& value) override { return _set(value); }
299  bool do_set(const float& value) override { return _set(value); }
300  bool do_set(const Vec2& value) override { return _set(value); }
301  bool do_set(const Vec3& value) override { return _set(value); }
302  bool do_set(const Vec4& value) override { return _set(value); }
303  bool do_set(const Mat3& value) override { return _set(value); }
304  bool do_set(const Mat4& value) override { return _set(value); }
305  bool do_set(const TexturePtr& value) override { return _set(value); }
306 
307  void do_get(bool** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_BOOL) ? (bool*) data : nullptr; }
308  void do_get(int32_t** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_INT) ? (int32_t*) data : nullptr; }
309  void do_get(float** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_FLOAT) ? (float*) data : nullptr; }
310  void do_get(Vec2** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_VEC2) ? (Vec2*) data : nullptr; }
311  void do_get(Vec3** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_VEC3) ? (Vec3*) data : nullptr; }
312  void do_get(Vec4** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_VEC4) ? (Vec4*) data : nullptr; }
313  void do_get(Mat3** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_MAT3) ? (Mat3*) data : nullptr; }
314  void do_get(Mat4** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_MAT4) ? (Mat4*) data : nullptr; }
315  void do_get(TexturePtr** result) const override { *result = (type == MATERIAL_PROPERTY_TYPE_TEXTURE) ? (TexturePtr*) data : nullptr; }
316 };
317 
318 
319 }
smlt::Mat4
Definition: mat4.h:29
smlt::BasePropertyValue
Definition: property_value.h:79
smlt::Vec3
Definition: vec3.h:23
smlt::Mat3
Definition: mat3.h:13
smlt
Definition: animation.cpp:25
smlt::_impl::material_property_lookup
Definition: property_value.h:29
smlt::PropertyValue
Definition: property_value.h:134
smlt::Colour
Definition: colour.h:29
smlt::Vec4
Definition: vec4.h:12
smlt::Vec2
Definition: vec2.h:14