SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Manager.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 
11 #ifndef smtk_resource_Manager_h
12 #define smtk_resource_Manager_h
13 
14 #include "smtk/CoreExports.h"
15 #include "smtk/PublicPointerDefs.h"
16 #include "smtk/SharedFromThis.h"
17 #include "smtk/SystemConfig.h"
18 
19 #include "smtk/common/Processing.h"
20 #include "smtk/common/TypeName.h"
21 #include "smtk/common/UUID.h"
22 
23 #include "smtk/resource/Container.h"
24 #include "smtk/resource/Lock.h"
25 #include "smtk/resource/Metadata.h"
26 #include "smtk/resource/MetadataContainer.h"
27 #include "smtk/resource/Observer.h"
28 #include "smtk/resource/Resource.h"
29 
30 #include <functional>
31 #include <string>
32 #include <typeinfo>
33 #include <unordered_map>
34 
35 namespace smtk
36 {
37 namespace resource
38 {
39 class GarbageCollector;
40 class Manager;
41 using GarbageCollectorPtr = std::shared_ptr<GarbageCollector>;
42 
47 class SMTKCORE_EXPORT Manager : smtkEnableSharedPtr(Manager)
48 {
49 public:
52 
55 
56  virtual ~Manager();
57 
60  template<typename ResourceType>
61  bool registerResource(
62  const std::function<
63  ResourcePtr(const std::string&, const std::shared_ptr<smtk::common::Managers>&)>& read =
64  nullptr,
65  const std::function<bool(const ResourcePtr&, const std::shared_ptr<smtk::common::Managers>&)>&
66  write = nullptr,
67  const std::function<
68  ResourcePtr(const smtk::common::UUID&, const std::shared_ptr<smtk::common::Managers>&)>&
69  create = nullptr);
70 
72  bool registerResource(Metadata&&);
73 
75  template<typename ResourceType>
76  bool unregisterResource();
77 
79  bool unregisterResource(const std::string&);
80 
82  bool unregisterResource(const Resource::Index&);
83 
85  template<typename ResourceType>
86  bool registered() const;
87 
89  bool registered(const std::string&) const;
90 
92  bool registered(const Resource::Index&) const;
93 
96  void clear();
97 
99  ResourcePtr create(const std::string&, const std::shared_ptr<smtk::common::Managers>& = nullptr);
100 
102  ResourcePtr create(
103  const Resource::Index&,
104  const std::shared_ptr<smtk::common::Managers>& = nullptr);
105 
107  template<typename ResourceType>
108  smtk::shared_ptr<ResourceType> create(const std::shared_ptr<smtk::common::Managers>& = nullptr);
109 
111  ResourcePtr create(
112  const std::string&,
113  const smtk::common::UUID&,
114  const std::shared_ptr<smtk::common::Managers>& = nullptr);
115 
117  ResourcePtr create(
118  const Resource::Index&,
119  const smtk::common::UUID&,
120  const std::shared_ptr<smtk::common::Managers>& = nullptr);
121 
123  template<typename ResourceType>
124  smtk::shared_ptr<ResourceType> create(
125  const smtk::common::UUID&,
126  const std::shared_ptr<smtk::common::Managers>& = nullptr);
127 
130  ResourcePtr get(const smtk::common::UUID& id);
131  ConstResourcePtr get(const smtk::common::UUID& id) const;
132 
135  template<typename ResourceType>
136  smtk::shared_ptr<ResourceType> get(const smtk::common::UUID&);
137  template<typename ResourceType>
138  smtk::shared_ptr<const ResourceType> get(const smtk::common::UUID&) const;
139 
142  ResourcePtr get(const std::string& url);
143  ConstResourcePtr get(const std::string& url) const;
144 
147  template<typename ResourceType>
148  smtk::shared_ptr<ResourceType> get(const std::string& url);
149  template<typename ResourceType>
150  smtk::shared_ptr<const ResourceType> get(const std::string& url) const;
151 
153  std::set<ResourcePtr> find(const std::string& typeName);
154 
160  std::set<ResourcePtr> find(const Resource::Index& typeIndex, bool strict = false);
161 
163  template<typename ResourceType>
164  std::set<smtk::shared_ptr<ResourceType>> find();
165 
167  ResourcePtr read(
168  const std::string&,
169  const std::string&,
170  const std::shared_ptr<smtk::common::Managers>& = nullptr);
171 
173  ResourcePtr read(
174  const Resource::Index&,
175  const std::string&,
176  const std::shared_ptr<smtk::common::Managers>& = nullptr);
177 
179  template<typename ResourceType>
180  smtk::shared_ptr<ResourceType> read(
181  const std::string&,
182  const std::shared_ptr<smtk::common::Managers>& = nullptr);
183 
186  bool write(const ResourcePtr&, const std::shared_ptr<smtk::common::Managers>& = nullptr);
187 
190  bool write(
191  const ResourcePtr&,
192  const std::string&,
193  const std::shared_ptr<smtk::common::Managers>& = nullptr);
194 
198  bool add(const Resource::Index&, const ResourcePtr&);
199 
202  template<typename ResourceType>
203  bool add(const smtk::shared_ptr<ResourceType>&);
204 
206  bool add(const ResourcePtr&);
207 
211  bool remove(const ResourcePtr&);
212 
217  bool addLegacyReader(const std::string&, const std::function<ResourcePtr(const std::string&)>&);
218 
224  void reviseId(const Resource::SetId& source, const Resource::SetId& destination);
225 
231  void reviseLocation(
232  const smtk::common::UUID& uid,
233  const Resource::SetLocation& source,
234  const Resource::SetLocation& destination);
235 
245  smtk::common::Termination visit(const ResourceVisitor& visitor) const;
246 
248  bool empty() const
249  {
250  ScopedLockGuard guard(m_lock, LockType::Read);
251  return m_resources.empty();
252  }
253 
258  std::size_t size() const
259  {
260  ScopedLockGuard guard(m_lock, LockType::Read);
261  return m_resources.size();
262  }
263 
277  PersistentObjectPtr search(const smtk::common::UUID& uid) const;
278 
280  MetadataContainer& metadata() { return m_metadata; }
281 
286  Observers& observers() { return m_observers; }
287  const Observers& observers() const { return m_observers; }
288 
290  Metadata::Observers& metadataObservers() { return m_metadataObservers; }
291  const Metadata::Observers& metadataObservers() const { return m_metadataObservers; }
292 
294  GarbageCollectorPtr garbageCollector() { return m_garbageCollector; }
295 
296 private:
297  Manager();
298 
301  Container m_resources;
302 
304  MetadataContainer m_metadata;
305 
307  Observers m_observers;
308 
310  Metadata::Observers m_metadataObservers;
311 
313  std::map<std::string, std::function<ResourcePtr(const std::string&)>> m_legacyReaders;
314 
316  GarbageCollectorPtr m_garbageCollector;
317 
319  mutable Lock m_lock;
320 };
321 
322 template<typename ResourceType>
324 {
325  return this->unregisterResource(std::type_index(typeid(ResourceType)).hash_code());
326 }
327 
328 template<typename ResourceType>
330 {
331  return this->registered(std::type_index(typeid(ResourceType)).hash_code());
332 }
333 
334 template<typename ResourceType>
335 smtk::shared_ptr<ResourceType> Manager::create(
336  const std::shared_ptr<smtk::common::Managers>& managers)
337 {
338  return smtk::static_pointer_cast<ResourceType>(
339  this->create(std::type_index(typeid(ResourceType)).hash_code(), managers));
340 }
341 
342 template<typename ResourceType>
343 smtk::shared_ptr<ResourceType> Manager::create(
344  const smtk::common::UUID& id,
345  const std::shared_ptr<smtk::common::Managers>& managers)
346 {
347  return smtk::static_pointer_cast<ResourceType>(
348  this->create(std::type_index(typeid(ResourceType)).hash_code(), id, managers));
349 }
350 
351 template<typename ResourceType>
352 smtk::shared_ptr<ResourceType> Manager::get(const smtk::common::UUID& id)
353 {
354  return smtk::static_pointer_cast<ResourceType>(this->get(id));
355 }
356 
357 template<typename ResourceType>
358 smtk::shared_ptr<const ResourceType> Manager::get(const smtk::common::UUID& id) const
359 {
360  return smtk::static_pointer_cast<const ResourceType>(this->get(id));
361 }
362 
363 template<typename ResourceType>
364 smtk::shared_ptr<ResourceType> Manager::get(const std::string& url)
365 {
366  return smtk::static_pointer_cast<ResourceType>(this->get(url));
367 }
368 
369 template<typename ResourceType>
370 smtk::shared_ptr<const ResourceType> Manager::get(const std::string& url) const
371 {
372  return smtk::static_pointer_cast<const ResourceType>(this->get(url));
373 }
374 
375 template<typename ResourceType>
376 std::set<smtk::shared_ptr<ResourceType>> Manager::find()
377 {
378  Resource::Index index(typeid(ResourceType).hash_code());
379  std::set<Resource::Index> validIndices;
380  for (const auto& metadatum : m_metadata)
381  {
382  if (metadatum.m_parentIndices.find(index) != metadatum.m_parentIndices.end())
383  {
384  validIndices.insert(metadatum.index());
385  }
386  }
387 
388  std::set<smtk::shared_ptr<ResourceType>> values;
389 
390  {
391  ScopedLockGuard guard(m_lock, LockType::Read);
392  typedef Container::index<IndexTag>::type ResourcesByIndex;
393  ResourcesByIndex& resources = m_resources.get<IndexTag>();
394  for (const auto& idx : validIndices)
395  {
396  auto resourceItRange = resources.equal_range(idx);
397  for (auto& it = resourceItRange.first; it != resourceItRange.second; ++it)
398  {
399  values.insert(smtk::static_pointer_cast<ResourceType>(*it));
400  }
401  }
402  }
403 
404  return values;
405 }
406 
407 template<typename ResourceType>
408 smtk::shared_ptr<ResourceType> Manager::read(
409  const std::string& url,
410  const std::shared_ptr<smtk::common::Managers>& managers)
411 {
412  return smtk::static_pointer_cast<ResourceType>(
413  this->read(std::type_index(typeid(ResourceType)).hash_code(), url, managers));
414 }
415 
416 template<typename ResourceType>
417 bool Manager::add(const smtk::shared_ptr<ResourceType>& resource)
418 {
419  return this->add(std::type_index(typeid(ResourceType)).hash_code(), resource);
420 }
421 
422 namespace detail
423 {
424 // For Resources that are derived from other Resources, we need a means to
425 // extract the Indices for both the Resource and its parent Resources. This
426 // information is subsequently used for retrieving derived Resources from
427 // queries made for parent Resources. We accomplish this by requiring that
428 // derived Resources define a ParentResource that relates to its parent
429 // resource. The chain of derived Resources is then recursively iterated, and
430 // each parent Resource::Index is added to the Resource Metadata's associated
431 // indices.
432 
433 // A compile-time test to check whether or not a class has a ParentResource
434 // defined.
435 template<typename T>
437 {
438  class No
439  {
440  };
441  class Yes
442  {
443  No no[2];
444  };
445 
446  template<typename C>
447  static Yes Test(typename C::ParentResource*);
448  template<typename C>
449  static No Test(...);
450 
451 public:
452  enum
453  {
454  value = sizeof(Test<T>(nullptr)) == sizeof(Yes)
455  };
456 };
457 
458 // The signature for our index generator has two template parameters.
459 template<typename ResourceType, bool derived_resource>
461 
462 // This partial template specialization deals with the case where
463 // <ResourceType> is not derived from another Resource. In this case, only the
464 // indices for the Resource and smtk::resource::Resource are added to the set of
465 // associated indices.
466 template<typename ResourceType>
467 struct resource_index_set_generator<ResourceType, false>
468 {
469  static std::set<Resource::Index> indices()
470  {
471  std::set<Resource::Index> indices;
472  indices.insert(typeid(ResourceType).hash_code());
473  indices.insert(smtk::resource::Resource::type_index);
474 
475  return indices;
476  }
477 };
478 
479 // This partial template specialization deals with the case where
480 // <ResourceType> is derived from another Resource. In this case, we
481 // recursively add the parent Resource's associated indices to the returned
482 // set.
483 template<typename ResourceType>
484 struct resource_index_set_generator<ResourceType, true>
485 {
486  static std::set<Resource::Index> indices()
487  {
488  std::set<Resource::Index> indices;
489  indices.insert(std::type_index(typeid(ResourceType)).hash_code());
490 
491  std::set<Resource::Index> parentIndices = resource_index_set_generator<
492  typename ResourceType::ParentResource,
494  indices.insert(parentIndices.begin(), parentIndices.end());
495 
496  return indices;
497  }
498 };
499 } // namespace detail
500 
501 template<typename ResourceType>
503  const std::function<
504  ResourcePtr(const std::string&, const std::shared_ptr<smtk::common::Managers>&)>& read,
505  const std::function<bool(const ResourcePtr&, const std::shared_ptr<smtk::common::Managers>&)>&
506  write,
507  const std::function<
508  ResourcePtr(const smtk::common::UUID&, const std::shared_ptr<smtk::common::Managers>&)>& create)
509 {
510  // For standard Resources, the metadata is comprised of the following:
511  // Type Name: either the "type_name" field or (if the former does not exist)
512  // the typeName() value
513  // Index: the hash of the type_index
514  // Parent Indices: a set of indices constructed by traversing parent resources
515  // (defined using the typedef "ParentResource")
516  // Create Functor: either a user-defined functor or the default
517  // ResourceType::create method
518  // Read Functor: either a user-defined functor or the nullptr
519  // Write Functor: either a user-defined functor or the nullptr
520 
522  smtk::common::typeName<ResourceType>(), std::type_index(typeid(ResourceType)).hash_code(),
525  (create ? create : [](const smtk::common::UUID& id, const std::shared_ptr<smtk::common::Managers>&) {
526  Resource::Ptr resource = ResourceType::create();
527  resource->setId(id);
528  return resource;
529  }),
530  (read ? read : [](const std::string&, const std::shared_ptr<smtk::common::Managers>&){ return ResourcePtr(); }),
531  (write ? write : [](const ResourcePtr&, const std::shared_ptr<smtk::common::Managers>&){ return false; })));
532 }
533 } // namespace resource
534 } // namespace smtk
535 
536 #endif // smtk_resource_Manager_h
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::resource::Metadata
Resources are registered to a resource manager at runtime with an instance of smtk::resource::Metadat...
Definition: Metadata.h:42
smtk::resource::IndexTag
Definition: Container.h:31
PublicPointerDefs.h
smtk::resource::Manager::registered
bool registered() const
Check if a resource identified by its class type is registered.
Definition: Manager.h:329
smtk::resource::Manager::empty
bool empty() const
Does the manager hold any resources?
Definition: Manager.h:248
smtk::resource::detail::is_derived_resource
Definition: Manager.h:436
smtk::resource::Manager::metadataObservers
Metadata::Observers & metadataObservers()
Return the metadata observers associated with this manager.
Definition: Manager.h:290
smtk::resource::Manager::ResourceVisitor
std::function< smtk::common::Processing(Resource &)> ResourceVisitor
The signature for visitor functions used to traverse managed resources.
Definition: Manager.h:51
smtk::resource::Manager::unregisterResource
bool unregisterResource()
Unregister a resource identified by its class type.
Definition: Manager.h:323
smtk::resource::Manager::metadata
MetadataContainer & metadata()
Return the map of metadata.
Definition: Manager.h:280
smtkTypedefs
#define smtkTypedefs(...)
Used by smtkTypeMacro()
Definition: SharedFromThis.h:21
smtk::resource::MetadataContainer
boost::multi_index_container< Metadata, indexed_by< ordered_unique< tag< NameTag >, const_mem_fun< Metadata, const std::string &, &Metadata::typeName > >, ordered_unique< tag< IndexTag >, const_mem_fun< Metadata, const smtk::resource::Resource::Index &, &Metadata::index > > > > MetadataContainer
A multi-index container for accessing resource metadata.
Definition: MetadataContainer.h:34
smtk::common::UUID
Definition: UUID.h:38
smtk::resource::Manager::size
std::size_t size() const
Return the number of resources held by the manager.
Definition: Manager.h:258
smtk::common::Observers< Observer >
smtk::resource::Manager::get
ResourcePtr get(const smtk::common::UUID &id)
Returns the resource that relates to the given uuid.
Definition: Manager.cxx:190
smtkCreateMacro
#define smtkCreateMacro(...)
Add static create() methods to a class.
Definition: SharedFromThis.h:113
smtkEnableSharedPtr
#define smtkEnableSharedPtr(...)
An abbreviation for enabling shared pointers.
Definition: SharedFromThis.h:154
smtk::common::Termination
Termination
An enumeration returned by visitors indicating whether they terminated early.
Definition: Processing.h:37
smtk::resource::detail::resource_index_set_generator
Definition: Manager.h:460
smtk::resource::Manager::add
bool add(const Resource::Index &, const ResourcePtr &)
Add a resource identified by its type index.
Definition: Manager.cxx:450
TypeName.h
Named type functions.
smtk::resource::Manager::find
std::set< smtk::shared_ptr< ResourceType > > find()
Returns a set of resources that are of the type ResourceType.
Definition: Manager.h:376
smtk::resource::Manager::garbageCollector
GarbageCollectorPtr garbageCollector()
Return a garbage collector used to clean up ephemeral objects after their use.
Definition: Manager.h:294
smtk::resource::Manager::read
ResourcePtr read(const std::string &, const std::string &, const std::shared_ptr< smtk::common::Managers > &=nullptr)
Read resource identified by its type index from file.
Definition: Manager.cxx:333
smtk::resource::Manager::observers
Observers & observers()
Return the observers associated with this manager.
Definition: Manager.h:286
smtk::resource::ScopedLockGuard
A scope-guarded utility for handling locks.
Definition: Lock.h:69
smtk::plugin::Manager
smtk::common::Singleton< detail::Manager > Manager
The Manager is a singleton interface for registering available plugins to manager instances.
Definition: Manager.h:92
smtk::common::typeName
std::string typeName()
Return the name of a class.
Definition: TypeName.h:286
smtk::resource::ConstResourcePtr
smtk::shared_ptr< const smtk::resource::Resource > ConstResourcePtr
Definition: PublicPointerDefs.h:305
smtk::resource::Resource
An abstract base class for SMTK resources.
Definition: Resource.h:59
smtk::resource::Manager::registerResource
bool registerResource(const std::function< ResourcePtr(const std::string &, const std::shared_ptr< smtk::common::Managers > &)> &read=nullptr, const std::function< bool(const ResourcePtr &, const std::shared_ptr< smtk::common::Managers > &)> &write=nullptr, const std::function< ResourcePtr(const smtk::common::UUID &, const std::shared_ptr< smtk::common::Managers > &)> &create=nullptr)
Register a resource identified by its class type, read and write operations.
Definition: Manager.h:502
smtk::resource::Manager::create
ResourcePtr create(const std::string &, const std::shared_ptr< smtk::common::Managers > &=nullptr)
Construct a resource identified by its type name.
Definition: Manager.cxx:102
smtk::resource::Lock
A read/write lock for resources.
Definition: Lock.h:42
smtk::common::Processing
Processing
An enumeration visitors use to control processing after they yield.
Definition: Processing.h:28
smtk::resource::PersistentObjectPtr
smtk::shared_ptr< smtk::resource::PersistentObject > PersistentObjectPtr
Definition: PublicPointerDefs.h:285
SharedFromThis.h
Macros for dealing with shared-pointer classes.
smtk::resource::Container
boost::multi_index_container< ResourcePtr, indexed_by< ordered_unique< tag< IdTag >, global_fun< const ResourcePtr &, const smtk::common::UUID &, &detail::id > >, ordered_non_unique< tag< IndexTag >, global_fun< const ResourcePtr &, smtk::resource::Resource::Index, &detail::index > >, ordered_non_unique< tag< NameTag >, global_fun< const ResourcePtr &, std::string, &detail::name > >, ordered_non_unique< tag< LocationTag >, global_fun< const ResourcePtr &, const std::string &, &detail::location > > > > Container
A multi-index container for accessing resources.
Definition: Container.h:82
smtk::resource::Manager
A resource Manager is responsible for tracking currently allocated resources, creating new resources ...
Definition: Manager.h:47
smtk::resource::ResourcePtr
smtk::shared_ptr< smtk::resource::Resource > ResourcePtr
Definition: PublicPointerDefs.h:295
smtk::resource::Manager::write
bool write(const ResourcePtr &, const std::shared_ptr< smtk::common::Managers > &=nullptr)
Write resource to file.
Definition: Manager.cxx:411