1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
24 **************************************************************************/
26 // File: vogl_state_vector.h
27 #ifndef VOGL_STATE_VECTOR_H
28 #define VOGL_STATE_VECTOR_H
30 #include "vogl_common.h"
31 #include "vogl_json.h"
34 class vogl_snapshot_context_info;
35 class vogl_state_vector;
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);
44 vogl_state_id(GLenum val, uint index, bool indexed_variant)
47 m_indexed_variant(indexed_variant)
58 m_indexed_variant = false;
61 bool operator==(const vogl_state_id &rhs) const
65 return (m_enum_val == rhs.m_enum_val) && (m_index == rhs.m_index) && (m_indexed_variant == rhs.m_indexed_variant);
68 bool operator!=(const vogl_state_id &rhs) const
72 return !(*this == rhs);
75 bool operator<(const vogl_state_id &rhs) const
79 if (m_enum_val < rhs.m_enum_val)
81 else if (m_enum_val == rhs.m_enum_val)
83 if (m_index < rhs.m_index)
85 else if (m_index == rhs.m_index)
86 return m_indexed_variant < rhs.m_indexed_variant;
91 void set(GLenum val, uint index, bool indexed_variant)
97 m_indexed_variant = indexed_variant;
102 bool m_indexed_variant;
105 class vogl_state_data
107 friend class vogl_state_vector;
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);
114 void init(GLenum enum_val, uint index, uint n, vogl_state_type data_type, bool indexed_variant);
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)
119 init(enum_val, index, n, data_type, indexed_variant);
121 VOGL_ASSERT(sizeof(T) == get_data_type_size());
123 return reinterpret_cast<T *>(m_data.get_ptr());
126 bool init(GLenum enum_val, uint index, const void *pData, uint element_size, bool indexed_variant);
133 m_data_type = cSTInvalid;
137 inline uint get_data_type_size() const
139 return vogl_get_state_type_size(m_data_type);
142 template <typename T>
143 const T *get_data_ptr() const
145 return reinterpret_cast<const T *>(m_data.get_ptr());
147 template <typename T>
150 return reinterpret_cast<T *>(m_data.get_ptr());
153 template <typename T>
154 const T &get_element(uint index) const
156 VOGL_ASSERT(index < m_num_elements);
157 return get_data_ptr<T>()[index];
159 template <typename T>
160 T &get_element(uint index)
162 VOGL_ASSERT(index < m_num_elements);
163 return get_data_ptr<T>()[index];
166 void swap(vogl_state_data &other);
168 bool is_equal(const vogl_state_data &rhs) const;
170 bool operator<(const vogl_state_data &rhs) const
172 return m_id < rhs.m_id;
175 inline const vogl_state_id &get_id() const
179 vogl_state_id &get_id()
184 inline GLenum get_enum_val() const
186 return m_id.m_enum_val;
188 inline uint get_index() const
192 inline bool get_indexed_variant() const
194 return m_id.m_indexed_variant;
197 inline vogl_state_type get_data_type() const
201 inline uint get_num_elements() const
203 return m_num_elements;
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
211 return get_uint(pVals);
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;
219 template <typename T>
220 void get(T *pVals) const;
222 bool serialize(json_node &node) const;
223 bool deserialize(const json_node &node);
228 vogl_state_type m_data_type;
231 vogl::vector<uint8> m_data;
234 // These specializations can't be at class scope.
236 inline void vogl_state_data::get<bool>(bool *pVals) const
238 return get_bool(pVals);
241 inline void vogl_state_data::get<int>(int *pVals) const
243 return get_int(pVals);
246 inline void vogl_state_data::get<uint>(uint *pVals) const
248 return get_uint(pVals);
251 inline void vogl_state_data::get<int64_t>(int64_t *pVals) const
253 return get_int64(pVals);
256 inline void vogl_state_data::get<uint64_t>(uint64_t *pVals) const
258 return get_uint64(pVals);
261 inline void vogl_state_data::get<float>(float *pVals) const
263 return get_float(pVals);
266 inline void vogl_state_data::get<double>(double *pVals) const
268 return get_double(pVals);
271 inline void vogl_state_data::get<void *>(void **ppVals) const
273 return get_pointer(ppVals);
276 class vogl_state_vector
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);
287 bool operator==(const vogl_state_vector &rhs) const;
288 bool operator!=(const vogl_state_vector &rhs) const
290 return !(*this == rhs);
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);
296 inline uint size() const
298 return m_states.size();
301 typedef vogl::map<vogl_state_id, vogl_state_data> state_map;
303 typedef state_map::const_iterator const_iterator;
305 inline const_iterator begin() const
307 return m_states.begin();
309 inline const_iterator end() const
311 return m_states.end();
314 const state_map &get_states() const
318 state_map &get_states()
323 const vogl_state_data *find(GLenum enum_val, uint index = 0, bool indexed_variant = false) const;
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
332 const vogl_state_data *pData = find(enum_val, index, indexed_variant);
335 VOGL_ASSERT(n >= pData->get_num_elements());
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
348 const vogl_state_data *pData = find(enum_val, index, indexed_variant);
351 vogl::growable_array<T, 16> vals(pData->get_num_elements());
352 pData->get(vals.get_ptr());
362 VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_id);
363 VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_data);
364 VOGL_DEFINE_BITWISE_MOVABLE(vogl_state_vector);
367 #endif // VOGL_STATE_VECTOR_H