vsg  1.0.4
VulkanSceneGraph library
Object.h
1 #pragma once
2 
3 /* <editor-fold desc="MIT License">
4 
5 Copyright(c) 2018 Robert Osfield
6 
7 Permission 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 
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 
11 THE 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 <string>
17 #include <typeindex>
18 #include <vector>
19 
20 #include <vsg/core/Export.h>
21 #include <vsg/core/ref_ptr.h>
22 #include <vsg/core/type_name.h>
23 
24 namespace vsg
25 {
26 
27  // forward declare
28  class Auxiliary;
29  class Visitor;
30  class ConstVisitor;
31  class RecordTraversal;
32  class Input;
33  class Output;
34  class Object;
35 
36  template<typename T>
37  constexpr bool has_read_write() { return false; }
38 
39  VSG_type_name(vsg::Object);
40 
41  class VSG_DECLSPEC Object
42  {
43  public:
44  Object();
45 
46  Object(const Object&);
47  Object& operator=(const Object&);
48 
49  static ref_ptr<Object> create() { return ref_ptr<Object>(new Object); }
50 
51  static ref_ptr<Object> create_if(bool flag)
52  {
53  if (flag)
54  return ref_ptr<Object>(new Object);
55  else
56  return {};
57  }
58 
60  static void* operator new(std::size_t count);
61  static void operator delete(void* ptr);
62 
63  virtual std::size_t sizeofObject() const noexcept { return sizeof(Object); }
64  virtual const char* className() const noexcept { return type_name<Object>(); }
65 
67  virtual const std::type_info& type_info() const noexcept { return typeid(Object); }
68  virtual bool is_compatible(const std::type_info& type) const noexcept { return typeid(Object) == type; }
69 
70  template<class T>
71  T* cast() { return is_compatible(typeid(T)) ? static_cast<T*>(this) : nullptr; }
72 
73  template<class T>
74  const T* cast() const { return is_compatible(typeid(T)) ? static_cast<const T*>(this) : nullptr; }
75 
77  virtual int compare(const Object& rhs) const
78  {
79  if (this == &rhs) return 0;
80  auto this_id = std::type_index(typeid(*this));
81  auto rhs_id = std::type_index(typeid(rhs));
82  if (this_id < rhs_id) return -1;
83  if (this_id > rhs_id) return 1;
84 
85  if (_auxiliary < rhs._auxiliary) return -1;
86  if (_auxiliary > rhs._auxiliary) return 1;
87 
88  return 0;
89  }
90 
91  virtual void accept(Visitor& visitor);
92  virtual void traverse(Visitor&) {}
93 
94  virtual void accept(ConstVisitor& visitor) const;
95  virtual void traverse(ConstVisitor&) const {}
96 
97  virtual void accept(RecordTraversal& visitor) const;
98  virtual void traverse(RecordTraversal&) const {}
99 
100  virtual void read(Input& input);
101  virtual void write(Output& output) const;
102 
103  // ref counting methods
104  inline void ref() const noexcept { _referenceCount.fetch_add(1, std::memory_order_relaxed); }
105  inline void unref() const noexcept
106  {
107  if (_referenceCount.fetch_sub(1, std::memory_order_seq_cst) <= 1) _attemptDelete();
108  }
109  inline void unref_nodelete() const noexcept { _referenceCount.fetch_sub(1, std::memory_order_seq_cst); }
110  inline unsigned int referenceCount() const noexcept { return _referenceCount.load(); }
111 
114  template<typename T>
115  void setValue(const std::string& key, const T& value);
116 
118  void setValue(const std::string& key, const char* value) { setValue(key, value ? std::string(value) : std::string()); }
119 
121  template<typename T>
122  bool getValue(const std::string& key, T& value) const;
123 
125  void setObject(const std::string& key, ref_ptr<Object> object);
126 
128  Object* getObject(const std::string& key);
129 
131  const Object* getObject(const std::string& key) const;
132 
134  template<class T>
135  T* getObject(const std::string& key) { return dynamic_cast<T*>(getObject(key)); }
136 
138  template<class T>
139  const T* getObject(const std::string& key) const { return dynamic_cast<const T*>(getObject(key)); }
140 
142  ref_ptr<Object> getRefObject(const std::string& key);
143 
145  ref_ptr<const Object> getRefObject(const std::string& key) const;
146 
148  template<class T>
149  ref_ptr<T> getRefObject(const std::string& key) { return getRefObject(key).cast<T>(); }
150 
152  template<class T>
153  const ref_ptr<const T> getRefObject(const std::string& key) const { return getRefObject(key).cast<const T>(); }
154 
156  void removeObject(const std::string& key);
157 
158  // Auxiliary object access methods, the optional Auxiliary is used to store meta data
159  Auxiliary* getOrCreateAuxiliary();
160  Auxiliary* getAuxiliary() { return _auxiliary; }
161  const Auxiliary* getAuxiliary() const { return _auxiliary; }
162 
163  protected:
164  virtual ~Object();
165 
166  virtual void _attemptDelete() const;
167  void setAuxiliary(Auxiliary* auxiliary);
168 
169  private:
170  friend class Auxiliary;
171 
172  mutable std::atomic_uint _referenceCount;
173 
174  Auxiliary* _auxiliary;
175  };
176 
177  template<class T, class R>
178  T* cast(const ref_ptr<R>& object)
179  {
180  return object ? object->template cast<T>() : nullptr;
181  }
182 
183  template<class T, class R>
184  T* cast(R* object)
185  {
186  return object ? object->template cast<T>() : nullptr;
187  }
188 
189  template<>
190  constexpr bool has_read_write<Object>() { return true; }
191 
192  using RefObjectPath = std::vector<ref_ptr<Object>>;
193  using ObjectPath = std::vector<Object*>;
194 
195 } // namespace vsg
Definition: Auxiliary.h:26
Definition: Object.h:42
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:139
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...
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:153
void setValue(const std::string &key, const char *value)
specialization of setValue to handle passing c strings
Definition: Object.h:118
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:149
virtual const std::type_info & type_info() const noexcept
return the std::type_info of this Object
Definition: Object.h:67
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...
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:135
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,...
Definition: Object.h:77
void removeObject(const std::string &key)
remove meta object or value associated with key
Object * getObject(const std::string &key)
get Object pointer associated with key, return nullptr if no object associated with key has been assi...
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...
Definition: Visitor.h:140
Definition: ref_ptr.h:22