vsg: include/vsg/utils/SharedObjects.h Source File

vsg 1.1.9 VulkanSceneGraph library |

Loading...
Searching...
No Matches
SharedObjects.h
1#pragma once
2
3/* <editor-fold desc="MIT License">
4
5Copyright(c) 2022 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 <vsg/core/Inherit.h>
16#include <vsg/core/compare.h>
17#include <vsg/io/stream.h>
18
19#include <map>
20#include <mutex>
21#include <ostream>
22#include <set>
23
24namespace vsg
25{
26
27 // forward declare
28 class SuitableForSharing;
29
31 class VSG_DECLSPEC SharedObjects : public Inherit<Object, SharedObjects>
32 {
33 public:
34 SharedObjects();
35
36 template<class T>
37 ref_ptr<T> shared_default();
38
39 template<class T>
40 void share(ref_ptr<T>& object);
41
42 template<class T, typename Func>
43 void share(ref_ptr<T>& object, Func init);
44
45 template<class C>
46 void share(C& container);
47
49 ref_ptr<SuitableForSharing> suitableForSharing;
50
52 std::set<Path> excludedExtensions;
53
55 virtual bool suitable(const Path& filename) const;
56
58 virtual bool contains(const Path& filename, ref_ptr<const Options> options = {}) const;
59
61 virtual void add(ref_ptr<Object> object, const Path& filename, ref_ptr<const Options> options = {});
62
64 virtual bool remove(const Path& filename, ref_ptr<const Options> options = {});
65
67 void clear();
68
69 // clear all the singularly referenced objects
70 void prune();
71
73 void report(std::ostream& out);
74
75 protected:
76 virtual ~SharedObjects();
77
78 mutable std::recursive_mutex _mutex;
79 std::map<std::type_index, ref_ptr<Object>> _defaults;
80 std::map<std::type_index, std::set<ref_ptr<Object>, DereferenceLess>> _sharedObjects;
81 };
82 VSG_type_name(vsg::SharedObjects);
83
85 class VSG_DECLSPEC LoadedObject : public Inherit<Object, LoadedObject>
86 {
87 public:
88 Path filename;
89 ref_ptr<Options> options;
90 ref_ptr<Object> object;
91 std::set<const Object*> dynamicObjects;
92
93 LoadedObject(const Path& in_filename, ref_ptr<const Options> in_options, ref_ptr<Object> in_object = {});
94
95 void traverse(Visitor& visitor) override;
96 void traverse(ConstVisitor& visitor) const override;
97
98 int compare(const Object& rhs_object) const override;
99 };
100 VSG_type_name(vsg::LoadedObject);
101
109 class VSG_DECLSPEC SuitableForSharing : public Inherit<ConstVisitor, SuitableForSharing>
110 {
111 public:
112 bool suitableForSharing = true;
113
114 void apply(const Object& object) override;
115 void apply(const PagedLOD& plod) override;
116
117 bool suitable(const Object* object)
118 {
119 suitableForSharing = true;
120 if (object) object->accept(*this);
121 return suitableForSharing;
122 }
123 };
124 VSG_type_name(vsg::SuitableForSharing);
125
126 // implementation of template method
127 template<class T>
128 ref_ptr<T> SharedObjects::shared_default()
129 {
130 std::scoped_lock<std::recursive_mutex> lock(_mutex);
131
132 auto id = std::type_index(typeid(T));
133 auto& def = _defaults[id];
134 auto def_T = def.cast<T>(); // should be able to do a static cast
135 if (!def_T)
136 {
137 def_T = T::create();
138 auto& shared_objects = _sharedObjects[id];
139 if (auto itr = shared_objects.find(def_T); itr != shared_objects.end())
140 {
141 def_T = (static_cast<T*>(itr->get()));
142 }
143 else
144 {
145 shared_objects.insert(def_T);
146 }
147
148 def = def_T;
149 }
150
151 return def_T;
152 }
153
154 // implementation of template method
155 template<class T>
156 void SharedObjects::share(ref_ptr<T>& object)
157 {
158 std::scoped_lock<std::recursive_mutex> lock(_mutex);
159
160 if (suitableForSharing && !suitableForSharing->suitable(object.get())) return;
161
162 auto id = std::type_index(typeid(T));
163 auto& shared_objects = _sharedObjects[id];
164 if (auto itr = shared_objects.find(object); itr != shared_objects.end())
165 {
166 object = ref_ptr<T>(static_cast<T*>(itr->get()));
167 return;
168 }
169
170 shared_objects.insert(object);
171 }
172
173 // implementation of template method
174 template<class T, typename Func>
175 void SharedObjects::share(ref_ptr<T>& object, Func init)
176 {
177 {
178 std::scoped_lock<std::recursive_mutex> lock(_mutex);
179
180 auto id = std::type_index(typeid(T));
181 auto& shared_objects = _sharedObjects[id];
182 if (auto itr = shared_objects.find(object); itr != shared_objects.end())
183 {
184 object = ref_ptr<T>(static_cast<T*>(itr->get()));
185 return;
186 }
187 }
188
189 init(object);
190
191 {
192 std::scoped_lock<std::recursive_mutex> lock(_mutex);
193 auto id = std::type_index(typeid(T));
194 auto& shared_objects = _sharedObjects[id];
195 if (suitableForSharing && suitableForSharing->suitable(object.get()))
196 {
197 shared_objects.insert(object);
198 }
199 }
200 }
201
202 // implementation of template method
203 template<class C>
204 void SharedObjects::share(C& container)
205 {
206 for (auto& object : container)
207 {
208 share(object);
209 }
210 }
211
212} // namespace vsg
vsg::ConstVisitor
Definition ConstVisitor.h:175
vsg::LoadedObject
Helper class for sharing of objects loaded from files.
Definition SharedObjects.h:86
vsg::LoadedObject::compare
int compare(const Object &rhs_object) const override
compare two objects, return -1 if this object is less than rhs, return 0 if it's equal,...
vsg::Object
Definition Object.h:60
vsg::PagedLOD
Definition PagedLOD.h:36
vsg::Path
Definition Path.h:34
vsg::SharedObjects
class for facilitating the sharing of instances of objects that have the same properties.
Definition SharedObjects.h:32
vsg::SharedObjects::report
void report(std::ostream &out)
write out stats of objects held, types of objects and their reference counts
vsg::SharedObjects::excludedExtensions
std::set< Path > excludedExtensions
set of lower case file extensions for file types that should not be included in this SharedObjects
Definition SharedObjects.h:52
vsg::SharedObjects::remove
virtual bool remove(const Path &filename, ref_ptr< const Options > options={})
remove entry associated with filename.
vsg::SharedObjects::suitable
virtual bool suitable(const Path &filename) const
return true if the filename is of a type suitable for inclusion in this SharedObjects
vsg::SharedObjects::clear
void clear()
clear all the internal structures leaving no Objects cached.
vsg::SharedObjects::suitableForSharing
ref_ptr< SuitableForSharing > suitableForSharing
visitor that checks a loaded object and its children for suitability for sharing in SharedObjects
Definition SharedObjects.h:49
vsg::SharedObjects::contains
virtual bool contains(const Path &filename, ref_ptr< const Options > options={}) const
check for an entry associated with filename.
vsg::SharedObjects::add
virtual void add(ref_ptr< Object > object, const Path &filename, ref_ptr< const Options > options={})
add entry that matches filename and options.
vsg::SuitableForSharing
Definition SharedObjects.h:110
vsg::Visitor
Definition Visitor.h:175
vsg::ref_ptr
Definition ref_ptr.h:22
vsg::DereferenceLess
less functor for comparing ref_ptr<Object> typically used with std::set<> etc.
Definition compare.h:107