]> git.cworth.org Git - vogl/blob - src/voglcommon/vogl_handle_tracker.h
Initial vogl checkin
[vogl] / src / voglcommon / vogl_handle_tracker.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 //----------------------------------------------------------------------------------------------------------------------
27 // File: vogl_handle_tracker.h
28 //----------------------------------------------------------------------------------------------------------------------
29 #ifndef VOGL_HANDLE_TRACKER_H
30 #define VOGL_HANDLE_TRACKER_H
31
32 #include "vogl_common.h"
33 #include "vogl_hash_map.h"
34 #include "vogl_sparse_vector.h"
35 #include "vogl_json.h"
36
37 class vogl_handle_tracker
38 {
39 public:
40     typedef uint32 handle_t;
41
42     class handle_def
43     {
44         friend class vogl_handle_tracker;
45
46     public:
47         handle_def()
48         {
49             clear();
50         }
51         handle_def(handle_t handle, handle_t inv_handle, GLenum target)
52             : m_handle(handle), m_inv_handle(inv_handle), m_target(target), m_is_valid(true)
53         {
54             VOGL_FUNC_TRACER
55         }
56
57         void init(handle_t handle, handle_t inv_handle, GLenum target)
58         {
59             m_handle = handle;
60             m_inv_handle = inv_handle;
61             m_target = target;
62             m_is_valid = true;
63             VOGL_FUNC_TRACER
64         }
65
66         void clear()
67         {
68             utils::zero_object(*this);
69         }
70
71         bool is_valid() const
72         {
73             return m_is_valid;
74         }
75
76         handle_t get_handle() const
77         {
78             return m_handle;
79         }
80         handle_t get_inv_handle() const
81         {
82             return m_inv_handle;
83         }
84         GLenum get_target() const
85         {
86             return m_target;
87         }
88
89         void set_target(GLenum target)
90         {
91             m_target = target;
92         }
93
94         bool operator==(const handle_def &rhs) const
95         {
96             return (m_handle == rhs.m_handle) && (m_inv_handle == rhs.m_inv_handle) && (m_target == rhs.m_target) && (m_is_valid == rhs.m_is_valid);
97         }
98
99     private:
100         handle_t m_handle;
101         handle_t m_inv_handle;
102         GLenum m_target;
103         bool m_is_valid;
104
105         void set_handle(handle_t handle)
106         {
107             m_handle = handle;
108         }
109         void set_inv_handle(handle_t inv_handle)
110         {
111             m_inv_handle = inv_handle;
112         }
113     };
114
115     typedef vogl::sparse_vector<handle_def, 5> handle_def_vec;
116     typedef vogl::hash_map<handle_t, uint> handle_hash_map_t;
117
118     vogl_handle_tracker();
119     vogl_handle_tracker(vogl_namespace_t handle_namespace);
120     ~vogl_handle_tracker();
121
122     void clear();
123
124     vogl_namespace_t get_namespace() const
125     {
126         return m_namespace;
127     }
128     void set_namespace(vogl_namespace_t handle_namespace)
129     {
130         m_namespace = handle_namespace;
131     }
132
133     uint get_total_valid_handles() const
134     {
135         return m_inv_handles.size();
136     }
137
138     // size() and operator[] allow you to iterate over the entire handle namespace, but beware that not all handles may be valid!
139     // size() is not necessarily always equal to get_total_valid_handles()!
140     uint size() const
141     {
142         return m_handles.size();
143     }
144     const handle_def &operator[](uint index) const
145     {
146         return m_handles[index];
147     }
148
149     void get_handles(uint_vec &handles);
150     void get_inv_handles(uint_vec &inv_handles);
151
152     const handle_def_vec &get_handles() const
153     {
154         return m_handles;
155     }
156     const handle_hash_map_t get_inv_handles() const
157     {
158         return m_inv_handles;
159     }
160
161     // true if insertion occured, otherwise it already existed and wasn't updated.
162     bool insert(handle_t handle, handle_t inv_handle, GLenum target);
163     //bool insert(handle_t handle, GLenum target) { return insert(handle, handle, target); }
164
165     // If handle is missing, the handle/inv_handle/target is added.
166     // Otherwise, it's only updated if the target is compare_target (and the inv_handle is ignored).
167     bool conditional_update(handle_t handle, handle_t inv_handle, GLenum compare_target, GLenum target);
168     bool conditional_update(handle_t handle, GLenum compare_target, GLenum target)
169     {
170         return conditional_update(handle, handle, compare_target, target);
171     }
172
173     // If handle is missing, the handle/inv_handle/target is added.
174     // Otherwise, the target of the handle is changed, and the inv_handle is ignored.
175     // Returns false if the insertion failed.
176     bool update(handle_t handle, handle_t inv_handle, GLenum target);
177     bool update(handle_t handle, GLenum target)
178     {
179         return update(handle, handle, target);
180     }
181
182     bool update_inv(handle_t inv_handle, handle_t handle, GLenum target);
183
184     // Sets handle's target, false if the handle does not exist.
185     bool set_target(handle_t handle, GLenum target);
186     bool set_target_inv(handle_t inv_handle, GLenum target);
187
188     bool contains(handle_t handle) const
189     {
190         return is_valid_handle(handle);
191     }
192     bool contains_inv(handle_t inv_handle) const
193     {
194         return is_valid_inv_handle(inv_handle);
195     }
196
197     // Given an inverse handle, return the handle associated with it, or false.
198     // Does not set handle on error.
199     bool map_inv_handle_to_handle(handle_t inv_handle, handle_t &handle) const;
200
201     // Given a handle, return the inverse handle associated with it, or false.
202     // Does not set inv_handle on error.
203     bool map_handle_to_inv_handle(handle_t handle, handle_t &inv_handle) const;
204
205     GLenum get_target(handle_t handle) const;
206     GLenum get_target_inv(handle_t inv_handle) const;
207
208     // true if erasure successfully occurred
209     bool erase(handle_t handle);
210     bool erase_inv(handle_t inv_handle);
211
212     bool invert(vogl_handle_tracker &inverted_map) const;
213
214     // Consistency check
215     bool check() const;
216
217     bool operator==(const vogl_handle_tracker &other) const;
218     bool operator!=(const vogl_handle_tracker &other) const
219     {
220         return !(*this == other);
221     }
222
223     bool serialize(json_node &node) const;
224     bool deserialize(const json_node &node);
225
226 private:
227     vogl_namespace_t m_namespace;
228     handle_def_vec m_handles;
229     handle_hash_map_t m_inv_handles;
230
231     bool is_valid_handle(handle_t handle) const
232     {
233         return (handle < m_handles.size()) && (m_handles[handle].is_valid());
234     }
235     bool is_valid_inv_handle(handle_t inv_handle) const
236     {
237         return m_inv_handles.contains(inv_handle);
238     }
239 };
240
241 #endif // VOGL_HANDLE_TRACKER_H