vsg 1.1.3
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/Export.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 template<class T>
89 T* cast() { return is_compatible(typeid(T)) ? static_cast<T*>(this) : nullptr; }
90
91 template<class T>
92 const T* cast() const { return is_compatible(typeid(T)) ? static_cast<const T*>(this) : nullptr; }
93
96 virtual ref_ptr<Object> clone(const CopyOp& copyop = {}) const;
97
99 virtual int compare(const Object& rhs) const;
100
101 virtual void accept(Visitor& visitor);
102 virtual void traverse(Visitor&) {}
103
104 virtual void accept(ConstVisitor& visitor) const;
105 virtual void traverse(ConstVisitor&) const {}
106
107 virtual void accept(RecordTraversal& visitor) const;
108 virtual void traverse(RecordTraversal&) const {}
109
110 virtual void read(Input& input);
111 virtual void write(Output& output) const;
112
113 // ref counting methods
114 inline void ref() const noexcept { _referenceCount.fetch_add(1, std::memory_order_relaxed); }
115 inline void unref() const noexcept
116 {
117 if (_referenceCount.fetch_sub(1, std::memory_order_seq_cst) <= 1) _attemptDelete();
118 }
119 inline void unref_nodelete() const noexcept { _referenceCount.fetch_sub(1, std::memory_order_seq_cst); }
120 inline unsigned int referenceCount() const noexcept { return _referenceCount.load(); }
121
124 template<typename T>
125 void setValue(const std::string& key, const T& value);
126
128 void setValue(const std::string& key, const char* value) { setValue(key, value ? std::string(value) : std::string()); }
129
131 template<typename T>
132 bool getValue(const std::string& key, T& value) const;
133
135 void setObject(const std::string& key, ref_ptr<Object> object);
136
138 Object* getObject(const std::string& key);
139
141 const Object* getObject(const std::string& key) const;
142
144 template<class T>
145 T* getObject(const std::string& key) { return dynamic_cast<T*>(getObject(key)); }
146
148 template<class T>
149 const T* getObject(const std::string& key) const { return dynamic_cast<const T*>(getObject(key)); }
150
152 ref_ptr<Object> getRefObject(const std::string& key);
153
155 ref_ptr<const Object> getRefObject(const std::string& key) const;
156
158 template<class T>
159 ref_ptr<T> getRefObject(const std::string& key) { return getRefObject(key).cast<T>(); }
160
162 template<class T>
163 const ref_ptr<const T> getRefObject(const std::string& key) const { return getRefObject(key).cast<const T>(); }
164
166 void removeObject(const std::string& key);
167
168 // Auxiliary object access methods, the optional Auxiliary is used to store meta data
169 Auxiliary* getOrCreateAuxiliary();
170 Auxiliary* getAuxiliary() { return _auxiliary; }
171 const Auxiliary* getAuxiliary() const { return _auxiliary; }
172
173 protected:
174 virtual ~Object();
175
176 virtual void _attemptDelete() const;
177 void setAuxiliary(Auxiliary* auxiliary);
178
179 private:
180 friend class Auxiliary;
181
182 mutable std::atomic_uint _referenceCount;
183
184 Auxiliary* _auxiliary;
185 };
186
187 template<class T, class R>
188 T* cast(const ref_ptr<R>& object)
189 {
190 return object ? object->template cast<T>() : nullptr;
191 }
192
193 template<class T, class R>
194 T* cast(R* object)
195 {
196 return object ? object->template cast<T>() : nullptr;
197 }
198
199 template<>
200 constexpr bool has_read_write<Object>() { return true; }
201
202 using RefObjectPath = std::vector<ref_ptr<Object>>;
203 using ObjectPath = std::vector<Object*>;
204
205 class Duplicate : public Object
206 {
207 public:
208 using DuplicateMap = std::map<const Object*, ref_ptr<Object>>;
209 using iterator = DuplicateMap::iterator;
210 using key_type = DuplicateMap::key_type;
211 using mapped_type = DuplicateMap::mapped_type;
212
213 DuplicateMap duplicates;
214
215 inline iterator find(const key_type& key) { return duplicates.find(key); }
216 inline iterator begin() { return duplicates.begin(); }
217 inline iterator end() { return duplicates.end(); }
218 std::size_t size() const { return duplicates.size(); }
219 inline mapped_type& operator[](const Object* object) { return duplicates[object]; }
220
221 bool contains(const Object* object) const { return duplicates.count(object) != 0; }
222 void insert(const Object* first, ref_ptr<Object> second = {}) { duplicates[first] = second; }
223 void clear() { duplicates.clear(); }
224
225 void reset()
226 {
227 for (auto itr = duplicates.begin(); itr != duplicates.end(); ++itr)
228 {
229 itr->second.reset();
230 }
231 }
232 };
233
234 template<class T>
236 {
237 if (ptr && duplicate)
238 {
239 if (auto itr = duplicate->find(ptr); itr != duplicate->end())
240 {
241 if (!itr->second) itr->second = ptr->clone(*this);
242 if (itr->second) return itr->second.template cast<T>();
243
244 warn("Unable to clone ", ptr);
245 }
246 }
247 return ptr;
248 }
249
250 template<class C>
251 inline C CopyOp::operator()(const C& src) const
252 {
253 if (!duplicate) return src;
254
255 C dest;
256 dest.reserve(src.size());
257 for (auto& ptr : src)
258 {
259 dest.push_back(operator()(ptr));
260 }
261 return dest;
262 }
263
264} // namespace vsg
Definition Auxiliary.h:26
Definition ConstVisitor.h:172
Definition Object.h:42
ref_ptr< T > operator()(ref_ptr< T > ptr) const
copy/clone pointer
Definition Object.h:235
Definition Object.h:206
Definition Object.h:60
void setObject(const std::string &key, ref_ptr< Object > object)
assign an Object associated with key
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:149
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:163
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...
void setValue(const std::string &key, const char *value)
specialization of setValue to handle passing C strings
Definition Object.h:128
Object * getObject(const std::string &key)
get Object pointer associated with key, return nullptr if no object associated with key has been assi...
virtual ref_ptr< Object > clone(const CopyOp &copyop={}) const
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:159
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,...
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...
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:145
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...
void removeObject(const std::string &key)
remove meta object or value associated with key
virtual const std::type_info & type_info() const noexcept
return the std::type_info of this Object
Definition Object.h:85
Definition Visitor.h:172
Definition ref_ptr.h:22