vsg  1.1.0
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  virtual void accept(Visitor& visitor);
80  virtual void traverse(Visitor&) {}
81 
82  virtual void accept(ConstVisitor& visitor) const;
83  virtual void traverse(ConstVisitor&) const {}
84 
85  virtual void accept(RecordTraversal& visitor) const;
86  virtual void traverse(RecordTraversal&) const {}
87 
88  virtual void read(Input& input);
89  virtual void write(Output& output) const;
90 
91  // ref counting methods
92  inline void ref() const noexcept { _referenceCount.fetch_add(1, std::memory_order_relaxed); }
93  inline void unref() const noexcept
94  {
95  if (_referenceCount.fetch_sub(1, std::memory_order_seq_cst) <= 1) _attemptDelete();
96  }
97  inline void unref_nodelete() const noexcept { _referenceCount.fetch_sub(1, std::memory_order_seq_cst); }
98  inline unsigned int referenceCount() const noexcept { return _referenceCount.load(); }
99 
102  template<typename T>
103  void setValue(const std::string& key, const T& value);
104 
106  void setValue(const std::string& key, const char* value) { setValue(key, value ? std::string(value) : std::string()); }
107 
109  template<typename T>
110  bool getValue(const std::string& key, T& value) const;
111 
113  void setObject(const std::string& key, ref_ptr<Object> object);
114 
116  Object* getObject(const std::string& key);
117 
119  const Object* getObject(const std::string& key) const;
120 
122  template<class T>
123  T* getObject(const std::string& key) { return dynamic_cast<T*>(getObject(key)); }
124 
126  template<class T>
127  const T* getObject(const std::string& key) const { return dynamic_cast<const T*>(getObject(key)); }
128 
130  ref_ptr<Object> getRefObject(const std::string& key);
131 
133  ref_ptr<const Object> getRefObject(const std::string& key) const;
134 
136  template<class T>
137  ref_ptr<T> getRefObject(const std::string& key) { return getRefObject(key).cast<T>(); }
138 
140  template<class T>
141  const ref_ptr<const T> getRefObject(const std::string& key) const { return getRefObject(key).cast<const T>(); }
142 
144  void removeObject(const std::string& key);
145 
146  // Auxiliary object access methods, the optional Auxiliary is used to store meta data
147  Auxiliary* getOrCreateAuxiliary();
148  Auxiliary* getAuxiliary() { return _auxiliary; }
149  const Auxiliary* getAuxiliary() const { return _auxiliary; }
150 
151  protected:
152  virtual ~Object();
153 
154  virtual void _attemptDelete() const;
155  void setAuxiliary(Auxiliary* auxiliary);
156 
157  private:
158  friend class Auxiliary;
159 
160  mutable std::atomic_uint _referenceCount;
161 
162  Auxiliary* _auxiliary;
163  };
164 
165  template<class T, class R>
166  T* cast(const ref_ptr<R>& object)
167  {
168  return object ? object->template cast<T>() : nullptr;
169  }
170 
171  template<class T, class R>
172  T* cast(R* object)
173  {
174  return object ? object->template cast<T>() : nullptr;
175  }
176 
177  template<>
178  constexpr bool has_read_write<Object>() { return true; }
179 
180  using RefObjectPath = std::vector<ref_ptr<Object>>;
181  using ObjectPath = std::vector<Object*>;
182 
183 } // namespace vsg
Definition: Auxiliary.h:26
Definition: ConstVisitor.h:147
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:127
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:141
void setValue(const std::string &key, const char *value)
specialization of setValue to handle passing C strings
Definition: Object.h:106
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:137
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:123
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,...
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:147
Definition: ref_ptr.h:22