]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_state_vector.h
Initial vogl checkin
[vogl] / src / voglcommon / vogl_state_vector.h
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  *
24  **************************************************************************/
25
26 // File: vogl_state_vector.h
27 #ifndef VOGL_STATE_VECTOR_H
28 #define VOGL_STATE_VECTOR_H
29
30 #include "vogl_common.h"
31 #include "vogl_json.h"
32 #include "vogl_map.h"
33
34 class vogl_snapshot_context_info;
35 class vogl_state_vector;
36
37 const char *vogl_get_state_type_name(vogl_state_type s);
38 vogl_state_type vogl_get_state_type_from_name(const char *pName);
39 uint vogl_get_state_type_size(vogl_state_type s);
40
41 class vogl_state_id
42 {
43 public:
44     vogl_state_id(GLenum val, uint index, bool indexed_variant)
45         : m_enum_val(val),
46           m_index(index),
47           m_indexed_variant(indexed_variant)
48     {
49         VOGL_FUNC_TRACER
50     }
51
52     void clear()
53     {
54         VOGL_FUNC_TRACER
55
56         m_enum_val = 0;
57         m_index = 0;
58         m_indexed_variant = false;
59     }
60
61     bool operator==(const vogl_state_id &rhs) const
62     {
63         //VOGL_FUNC_TRACER
64
65         return (m_enum_val == rhs.m_enum_val) && (m_index == rhs.m_index) && (m_indexed_variant == rhs.m_indexed_variant);
66     }
67
68     bool operator!=(const vogl_state_id &rhs) const
69     {
70         //VOGL_FUNC_TRACER
71
72         return !(*this == rhs);
73     }
74
75     bool operator<(const vogl_state_id &rhs) const
76     {
77         //VOGL_FUNC_TRACER
78
79         if (m_enum_val < rhs.m_enum_val)
80             return true;
81         else if (m_enum_val == rhs.m_enum_val)
82         {
83             if (m_index < rhs.m_index)
84                 return true;
85             else if (m_index == rhs.m_index)
86                 return m_indexed_variant < rhs.m_indexed_variant;
87         }
88         return false;
89     }
90
91     void set(GLenum val, uint index, bool indexed_variant)
92     {
93         VOGL_FUNC_TRACER
94
95         m_enum_val = val;
96         m_index = index;
97         m_indexed_variant = indexed_variant;
98     }
99
100     GLenum m_enum_val;
101     uint m_index;
102     bool m_indexed_variant;
103 };
104
105 class vogl_state_data
106 {
107     friend class vogl_state_vector;
108
109 public:
110     vogl_state_data();
111     vogl_state_data(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant);
112     vogl_state_data(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant);
113
114     void init(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant);
115
116     template <typename T>
117     inline T *init_and_get_data_ptr(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant)
118     {
119         init(enum_val, index, n, data_type, indexed_variant);
120
121         VOGL_ASSERT(sizeof(T) == get_data_type_size());
122
123         return reinterpret_cast<T *>(m_data.get_ptr());
124     }
125
126     bool init(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant);
127
128     void debug_check();
129
130     inline void clear()
131     {
132         m_id.clear();
133         m_data_type = cSTInvalid;
134         m_data.clear();
135     }
136
137     inline uint get_data_type_size() const
138     {
139         return vogl_get_state_type_size(m_data_type);
140     }
141
142     template <typename T>
143     const T *get_data_ptr() const
144     {
145         return reinterpret_cast<const T *>(m_data.get_ptr());
146     }
147     template <typename T>
148     T *get_data_ptr()
149     {
150         return reinterpret_cast<T *>(m_data.get_ptr());
151     }
152
153     template <typename T>
154     const T &get_element(uint index) const
155     {
156         VOGL_ASSERT(index < m_num_elements);
157         return get_data_ptr<T>()[index];
158     }
159     template <typename T>
160     T &get_element(uint index)
161     {
162         VOGL_ASSERT(index < m_num_elements);
163         return get_data_ptr<T>()[index];
164     }
165
166     void swap(vogl_state_data &other);
167
168     bool is_equal(const vogl_state_data &rhs) const;
169
170     bool operator<(const vogl_state_data &rhs) const
171     {
172         return m_id < rhs.m_id;
173     }
174
175     inline const vogl_state_id &get_id() const
176     {
177         return m_id;
178     }
179     vogl_state_id &get_id()
180     {
181         return m_id;
182     }
183
184     inline GLenum get_enum_val() const
185     {
186         return m_id.m_enum_val;
187     }
188     inline uint get_index() const
189     {
190         return m_id.m_index;
191     }
192     inline bool get_indexed_variant() const
193     {
194         return m_id.m_indexed_variant;
195     }
196
197     inline vogl_state_type get_data_type() const
198     {
199         return m_data_type;
200     }
201     inline uint get_num_elements() const
202     {
203         return m_num_elements;
204     }
205
206     void get_bool(bool *pVals) const;
207     void get_int(int *pVals) const;
208     void get_uint(uint *pVals) const;
209     void get_enum(GLenum *pVals) const
210     {
211         return get_uint(pVals);
212     }
213     void get_int64(int64_t *pVals) const;
214     void get_uint64(uint64_t *pVals) const;
215     void get_float(float *pVals) const;
216     void get_double(double *pVals) const;
217     void get_pointer(void **ppVals) const;
218
219     template <typename T>
220     void get(T *pVals) const;
221
222     bool serialize(json_node &node) const;
223     bool deserialize(const json_node &node);
224
225 private:
226     vogl_state_id m_id;
227
228     vogl_state_type m_data_type;
229     uint m_num_elements;
230
231     vogl::vector<uint8> m_data;
232 };
233
234 // These specializations can't be at class scope.
235 template <>
236 inline void vogl_state_data::get<bool>(bool *pVals) const
237 {
238     return get_bool(pVals);
239 }
240 template <>
241 inline void vogl_state_data::get<int>(int *pVals) const
242 {
243     return get_int(pVals);
244 }
245 template <>
246 inline void vogl_state_data::get<uint>(uint *pVals) const
247 {
248     return get_uint(pVals);
249 }
250 template <>
251 inline void vogl_state_data::get<int64_t>(int64_t *pVals) const
252 {
253     return get_int64(pVals);
254 }
255 template <>
256 inline void vogl_state_data::get<uint64_t>(uint64_t *pVals) const
257 {
258     return get_uint64(pVals);
259 }
260 template <>
261 inline void vogl_state_data::get<float>(float *pVals) const
262 {
263     return get_float(pVals);
264 }
265 template <>
266 inline void vogl_state_data::get<double>(double *pVals) const
267 {
268     return get_double(pVals);
269 }
270 template <>
271 inline void vogl_state_data::get<void *>(void **ppVals) const
272 {
273     return get_pointer(ppVals);
274 }
275
276 class vogl_state_vector
277 {
278 public:
279     vogl_state_vector();
280
281     void clear();
282
283     bool serialize(json_node &node, vogl_blob_manager &blob_manager) const;
284     bool deserialize(const json_node &node, const vogl_blob_manager &blob_manager);
285     bool deserialize(const char *pChild_name, const json_node &parent_node, const vogl_blob_manager &blob_manager);
286
287     bool operator==(const vogl_state_vector &rhs) const;
288     bool operator!=(const vogl_state_vector &rhs) const
289     {
290         return !(*this == rhs);
291     }
292
293     bool insert(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant = false);
294     bool insert(const vogl_state_data &state_data);
295
296     inline uint size() const
297     {
298         return m_states.size();
299     }
300
301     typedef vogl::map<vogl_state_id, vogl_state_data> state_map;
302
303     typedef state_map::const_iterator const_iterator;
304
305     inline const_iterator begin() const
306     {
307         return m_states.begin();
308     }
309     inline const_iterator end() const
310     {
311         return m_states.end();
312     }
313
314     const state_map &get_states() const
315     {
316         return m_states;
317     }
318     state_map &get_states()
319     {
320         return m_states;
321     }
322
323     const vogl_state_data *find(GLenum enum_val, uint index = 0, bool indexed_variant = false) const;
324
325     // true on success, false on failure.
326     // pVals is only modified on success.
327     template <typename T>
328     bool get(GLenum enum_val, uint index, T *pVals, uint n = 1, bool indexed_variant = false) const
329     {
330         VOGL_FUNC_TRACER
331
332         const vogl_state_data *pData = find(enum_val, index, indexed_variant);
333         if (!pData)
334             return false;
335         VOGL_ASSERT(n >= pData->get_num_elements());
336         VOGL_NOTE_UNUSED(n);
337         pData->get(pVals);
338         return true;
339     }
340
341     // Returns the value, or the default.
342     // Safely only returns the first value on states with multiple values.
343     template <typename T>
344     T get_value(GLenum enum_val, uint index = 0, T def = (T)0, bool indexed_variant = false) const
345     {
346         VOGL_FUNC_TRACER
347
348         const vogl_state_data *pData = find(enum_val, index, indexed_variant);
349         if (!pData)
350             return def;
351         vogl::growable_array<T, 16> vals(pData->get_num_elements());
352         pData->get(vals.get_ptr());
353         return vals[0];
354     }
355
356 protected:
357     state_map m_states;
358 };
359
360 namespace vogl
361 {
362     VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_id);
363     VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_data);
364     VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_vector);
365 }
366
367 #endif // VOGL_STATE_VECTOR_H