vsg: include/vsg/core/Object.h Source File

vsg 1.1.13 VulkanSceneGraph library

Loading...
Searching...
No Matches
Object.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2018 Robert Osfield
6
7Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8
9The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12
13</editor-fold> */
14
15#include <atomic>
16#include <map>
17#include <string>
18#include <typeindex>
19#include <vector>
20
21#include <vsg/core/Version.h>
22#include <vsg/core/ref_ptr.h>
23#include <vsg/core/type_name.h>
24
25namespace vsg
26{
27
28 // forward declare
29 class Auxiliary;
30 class Visitor;
31 class ConstVisitor;
32 class RecordTraversal;
33 class Input;
34 class Output;
35 class Object;
36 class Duplicate;
37
38 template<typename T>
39 constexpr bool has_read_write() { return false; }
40
41 class CopyOp
42 {
43 public:
44 mutable ref_ptr<Duplicate> duplicate;
45
47 template<class T>
48 inline ref_ptr<T> operator()(ref_ptr<T> ptr) const;
49
51 template<class C>
52 inline C operator()(const C& src) const;
53
54 explicit operator bool() const noexcept { return duplicate.valid(); }
55 };
56
57 VSG_type_name(vsg::Object);
58
59 class VSG_DECLSPEC Object
60 {
61 public:
62 Object();
63
64 Object(const Object& object, const CopyOp& copyop = {});
65 Object& operator=(const Object&);
66
67 static ref_ptr<Object> create() { return ref_ptr<Object>(new Object); }
68
69 static ref_ptr<Object> create_if(bool flag)
70 {
71 if (flag)
72 return ref_ptr<Object>(new Object);
73 else
74 return {};
75 }
76
78 static void* operator new(std::size_t count);
79 static void operator delete(void* ptr);
80
81 virtual std::size_t sizeofObject() const noexcept { return sizeof(Object); }
82 virtual const char* className() const noexcept { return type_name<Object>(); }
83
85 virtual const std::type_info& type_info() const noexcept { return typeid(Object); }
86 virtual bool is_compatible(const std::type_info& type) const noexcept { return typeid(Object) == type; }
87
88#if VSG_USE_dynamic_cast
89 template<class T>
90 T* cast() { return dynamic_cast<T*>(this); }
91
92 template<class T>
93 const T* cast() const { return dynamic_cast<const T*>(this); }
94#else
95 template<class T>
96 T* cast() { return is_compatible(typeid(T)) ? static_cast<T*>(this) : nullptr; }
97
98 template<class T>
99 const T* cast() const { return is_compatible(typeid(T)) ? static_cast<const T*>(this) : nullptr; }
100#endif
101
104 virtual ref_ptr<Object> clone(const CopyOp& copyop = {}) const;
105
107 virtual int compare(const Object& rhs) const;
108
109 virtual void accept(Visitor& visitor);
110 virtual void traverse(Visitor&) {}
111
112 virtual void accept(ConstVisitor& visitor) const;
113 virtual void traverse(ConstVisitor&) const {}
114
115 virtual void accept(RecordTraversal& visitor) const;
116 virtual void traverse(RecordTraversal&) const {}
117
118 virtual void read(Input& input);
119 virtual void write(Output& output) const;
120
121 // ref counting methods
122 inline void ref() const noexcept { _referenceCount.fetch_add(1, std::memory_order_relaxed); }
123 inline void unref() const noexcept
124 {
125 if (_referenceCount.fetch_sub(1, std::memory_order_seq_cst) <= 1) _attemptDelete();
126 }
127 inline void unref_nodelete() const noexcept { _referenceCount.fetch_sub(1, std::memory_order_seq_cst); }
128 inline unsigned int referenceCount() const noexcept { return _referenceCount.load(); }
129
132 template<typename T>
133 void setValue(const std::string& key, const T& value);
134
136 void setValue(const std::string& key, const char* value) { setValue(key, value ? std::string(value) : std::string()); }
137
139 template<typename T>
140 bool getValue(const std::string& key, T& value) const;
141
143 void setObject(const std::string& key, ref_ptr<Object> object);
144
146 Object* getObject(const std::string& key);
147
149 const Object* getObject(const std::string& key) const;
150
152 template<class T>
153 T* getObject(const std::string& key) { return dynamic_cast<T*>(getObject(key)); }
154
156 template<class T>
157 const T* getObject(const std::string& key) const { return dynamic_cast<const T*>(getObject(key)); }
158
160 ref_ptr<Object> getRefObject(const std::string& key);
161
163 ref_ptr<const Object> getRefObject(const std::string& key) const;
164
166 template<class T>
167 ref_ptr<T> getRefObject(const std::string& key) { return getRefObject(key).cast<T>(); }
168
170 template<class T>
171 const ref_ptr<const T> getRefObject(const std::string& key) const { return getRefObject(key).cast<const T>(); }
172
174 void removeObject(const std::string& key);
175
176 // Auxiliary object access methods, the optional Auxiliary is used to store meta data
177 Auxiliary* getOrCreateAuxiliary();
178 Auxiliary* getAuxiliary() { return _auxiliary; }
179 const Auxiliary* getAuxiliary() const { return _auxiliary; }
180
181 protected:
182 virtual ~Object();
183
184 virtual void _attemptDelete() const;
185 void setAuxiliary(Auxiliary* auxiliary);
186
187 private:
188 friend class Auxiliary;
189
190 mutable std::atomic_uint _referenceCount;
191
192 Auxiliary* _auxiliary;
193 };
194
195 template<class T, class R>
196 T* cast(const ref_ptr<R>& object)
197 {
198 return object ? object->template cast<T>() : nullptr;
199 }
200
201 template<class T, class R>
202 T* cast(R* object)
203 {
204 return object ? object->template cast<T>() : nullptr;
205 }
206
207 template<>
208 constexpr bool has_read_write<Object>() { return true; }
209
210 using RefObjectPath = std::vector<ref_ptr<Object>>;
211 using ObjectPath = std::vector<Object*>;
212
213 class Duplicate : public Object
214 {
215 public:
216 using DuplicateMap = std::map<const Object*, ref_ptr<Object>>;
217 using iterator = DuplicateMap::iterator;
218 using key_type = DuplicateMap::key_type;
219 using mapped_type = DuplicateMap::mapped_type;
220
221 DuplicateMap duplicates;
222
223 inline iterator find(const key_type& key) { return duplicates.find(key); }
224 inline iterator begin() { return duplicates.begin(); }
225 inline iterator end() { return duplicates.end(); }
226 std::size_t size() const { return duplicates.size(); }
227 inline mapped_type& operator[](const Object* object) { return duplicates[object]; }
228
229 bool contains(const Object* object) const { return duplicates.count(object) != 0; }
230 void insert(const Object* first, ref_ptr<Object> second = {}) { duplicates[first] = second; }
231 void clear() { duplicates.clear(); }
232
233 void reset()
234 {
235 for (auto itr = duplicates.begin(); itr != duplicates.end(); ++itr)
236 {
237 itr->second.reset();
238 }
239 }
240 };
241
242 template<class T>
243 inline ref_ptr<T> CopyOp::operator()(ref_ptr<T> ptr) const
244 {
245 if (ptr && duplicate)
246 {
247 if (auto itr = duplicate->find(ptr); itr != duplicate->end())
248 {
249 if (!itr->second) itr->second = ptr->clone(*this);
250 if (itr->second) return itr->second.template cast<T>();
251 }
252 }
253 return ptr;
254 }
255
256 template<class C>
257 inline C CopyOp::operator()(const C& src) const
258 {
259 if (!duplicate) return src;
260
261 C dest;
262 dest.reserve(src.size());
263 for (auto& ptr : src)
264 {
265 dest.push_back(operator()(ptr));
266 }
267 return dest;
268 }
269
270 template<class T>
271 ref_ptr<T> clone(vsg::ref_ptr<const T> object)
272 {
273 if (!object) return {};
274 auto new_object = object->clone();
275 return new_object.template cast<T>();
276 }
277
278 template<class T>
279 ref_ptr<T> clone(vsg::ref_ptr<T> object)
280 {
281 if (!object) return {};
282 auto new_object = object->clone();
283 return new_object.template cast<T>();
284 }
285
286} // namespace vsg
vsg::Auxiliary
Definition Auxiliary.h:26
vsg::ConstVisitor
Definition ConstVisitor.h:179
vsg::CopyOp
Definition Object.h:42
vsg::CopyOp::operator()
ref_ptr< T > operator()(ref_ptr< T > ptr) const
copy/clone pointer
Definition Object.h:243
vsg::Duplicate
Definition Object.h:214
vsg::Input
Definition Input.h:44
vsg::Object
Definition Object.h:60
vsg::Object::setObject
void setObject(const std::string &key, ref_ptr< Object > object)
assign an Object associated with key
vsg::Object::getObject
const T * getObject(const std::string &key) const
get const object pointer of specified type associated with key, return nullptr if no object associate...
Definition Object.h:157
vsg::Object::getRefObject
const ref_ptr< const T > getRefObject(const std::string &key) const
get ref_ptr<const T> of specified type associated with key, return nullptr if no object associated wi...
Definition Object.h:171
vsg::Object::getRefObject
ref_ptr< Object > getRefObject(const std::string &key)
get ref_ptr<Object> associated with key, return nullptr if no object associated with key has been ass...
vsg::Object::setValue
void setValue(const std::string &key, const char *value)
specialization of setValue to handle passing C strings
Definition Object.h:136
vsg::Object::getObject
Object * getObject(const std::string &key)
get Object pointer associated with key, return nullptr if no object associated with key has been assi...
vsg::Object::clone
virtual ref_ptr< Object > clone(const CopyOp &copyop={}) const
vsg::Object::getRefObject
ref_ptr< T > getRefObject(const std::string &key)
get ref_ptr<T> of specified type associated with key, return nullptr if no object associated with key...
Definition Object.h:167
vsg::Object::compare
virtual int compare(const Object &rhs) const
compare two objects, return -1 if this object is less than rhs, return 0 if it's equal,...
vsg::Object::getRefObject
ref_ptr< const Object > getRefObject(const std::string &key) const
get ref_ptr<const Object> pointer associated with key, return nullptr if no object associated with ke...
vsg::Object::getObject
T * getObject(const std::string &key)
get object pointer of specified type associated with key, return nullptr if no object associated with...
Definition Object.h:153
vsg::Object::getObject
const Object * getObject(const std::string &key) const
get const Object pointer associated with key, return nullptr if no object associated with key has bee...
vsg::Object::removeObject
void removeObject(const std::string &key)
remove meta object or value associated with key
vsg::Object::type_info
virtual const std::type_info & type_info() const noexcept
return the std::type_info of this Object
Definition Object.h:85
vsg::Output
Definition Output.h:41
vsg::RecordTraversal
RecordTraversal traverses a scene graph doing view frustum culling and invoking state/commands to rec...
Definition RecordTraversal.h:74
vsg::Visitor
Definition Visitor.h:179
vsg::ref_ptr
Definition ref_ptr.h:22