SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
ReferenceItem.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 #ifndef smtk_attribute_ReferenceItem_h
11 #define smtk_attribute_ReferenceItem_h
12 
13 #include "smtk/attribute/Item.h"
14 
15 #include "smtk/common/UUID.h"
16 #include "smtk/resource/Lock.h"
17 
18 #include <iterator>
19 #include <vector>
20 
21 namespace smtk
22 {
23 namespace common
24 {
25 class UUID;
26 }
27 namespace attribute
28 {
29 
30 class Attribute;
31 class ReferenceItemDefinition;
32 class ValueItemDefinition;
33 
51 class SMTKCORE_EXPORT ReferenceItem : public Item
52 {
53  using PersistentObjectPtr = smtk::resource::PersistentObjectPtr;
54 
55 public:
62  class SMTKCORE_EXPORT const_iterator
63  {
64  friend class ReferenceItem;
65 
66  public:
67  typedef const_iterator self_type;
68  typedef std::random_access_iterator_tag iterator_category;
69  typedef const smtk::resource::PersistentObjectPtr value_type;
70  typedef value_type reference;
71  typedef value_type pointer;
72  typedef std::ptrdiff_t difference_type;
73 
75  const_iterator(const const_iterator& it);
76 
77  ~const_iterator();
78 
79  const_iterator& operator=(const const_iterator& it);
80 
81  const_iterator& operator++();
82  const_iterator& operator--();
83 
84  const_iterator operator++(int);
85  const_iterator operator--(int);
86 
87  const_iterator operator+(const difference_type& d) const;
88  const_iterator operator-(const difference_type& d) const;
89 
90  reference operator*() const;
91  pointer operator->() const;
92  reference operator[](const difference_type& d);
93 
94  bool isSet() const;
95 
96  friend difference_type SMTKCORE_EXPORT operator-(const const_iterator&, const const_iterator&);
97 
98  friend bool SMTKCORE_EXPORT operator<(const const_iterator& it1, const const_iterator& it2);
99  friend bool SMTKCORE_EXPORT operator>(const const_iterator& it1, const const_iterator& it2);
100  friend bool SMTKCORE_EXPORT operator<=(const const_iterator& it1, const const_iterator& it2);
101  friend bool SMTKCORE_EXPORT operator>=(const const_iterator& it1, const const_iterator& it2);
102  friend bool SMTKCORE_EXPORT operator==(const const_iterator& it1, const const_iterator& it2);
103  friend bool SMTKCORE_EXPORT operator!=(const const_iterator& it1, const const_iterator& it2);
104 
105  private:
106  struct CacheIterator;
107  std::unique_ptr<CacheIterator> m_cacheIterator;
108  };
109 
112  using Key = std::pair<smtk::common::UUID, smtk::common::UUID>;
113 
116 
118  ~ReferenceItem() override;
119 
120  ReferenceItem& operator=(const ReferenceItem&);
121 
123  Item::Type type() const override { return Item::ReferenceType; }
124 
126  std::size_t numberOfValues() const;
128  bool setNumberOfValues(std::size_t newSize);
136  bool removeInvalidValues();
137 
139  virtual std::shared_ptr<const ReferenceItemDefinition> definition() const;
141  const std::multimap<std::string, std::string>& acceptableEntries() const;
142 
144  std::size_t numberOfRequiredValues() const;
146  std::size_t maxNumberOfValues() const;
147 
149  bool contains(const smtk::resource::PersistentObjectPtr& obj) const;
150 
152  bool contains(const smtk::common::UUID& compId) const;
153 
159  void visit(std::function<bool(const PersistentObjectPtr&)> visitor) const;
160 
177  template<typename Container>
178  void as(
179  Container& result,
180  std::function<typename Container::value_type(const PersistentObjectPtr&)> converter =
181  [](const PersistentObjectPtr& obj) { return obj; }) const
182  {
183  for (auto it = this->begin(); it != this->end(); ++it)
184  {
185  if (!it.isSet())
186  {
187  continue;
188  }
189 
190  typename Container::value_type val = converter(*it);
191  if (val)
192  {
193  result.insert(result.end(), val);
194  }
195  }
196  }
197  template<typename Container>
198  Container as(
199  std::function<typename Container::value_type(const PersistentObjectPtr&)> converter =
200  [](const PersistentObjectPtr& obj) { return obj; }) const
201  {
202  Container result;
203  this->as(result, converter);
204  return result;
205  }
206 
214  Key objectKey(std::size_t i = 0) const;
215  bool setObjectKey(std::size_t i, const Key& key);
216  bool setObjectKey(std::size_t i, const Key& key, std::size_t conditional);
217 
219  PersistentObjectPtr value(std::size_t i = 0) const;
220  template<typename T>
221  typename T::Ptr valueAs(std::size_t i = 0) const
222  {
223  return std::dynamic_pointer_cast<T>(this->value(i));
224  }
225 
226  virtual bool isValueValid(std::size_t ii, const PersistentObjectPtr& entity) const;
227  bool isValueValid(const PersistentObjectPtr& entity) const
228  {
229  return this->isValueValid(0, entity);
230  }
231 
237  bool setValue(const PersistentObjectPtr& val);
242  bool setValue(std::size_t i, const PersistentObjectPtr& val);
243 
244  template<typename I>
245  bool setValues(I vbegin, I vend, typename std::iterator_traits<I>::difference_type offset = 0);
246  template<typename I>
247  bool appendValues(I vbegin, I vend);
248 
249  template<typename I, typename T>
250  bool setValuesVia(
251  I vbegin,
252  I vend,
253  const T& converter,
254  typename std::iterator_traits<I>::difference_type offset = 0);
255  template<typename I, typename T>
256  bool appendValuesVia(I vbegin, I vend, const T& converter);
257 
268  bool appendValue(const PersistentObjectPtr& val, bool allowDuplicates = true);
275  bool removeValue(std::size_t i);
277  void detachOwningResource() override;
279  void reset() override;
281  virtual std::string valueAsString() const;
288  virtual std::string valueAsString(std::size_t i) const;
298  virtual bool isSet(std::size_t i = 0) const;
300  virtual void unset(std::size_t i = 0);
302  virtual std::size_t numberOfSetValues() const;
308  using Item::assign;
309  bool assign(
310  const smtk::attribute::ConstItemPtr& sourceItem,
311  const CopyAssignmentOptions& options,
312  smtk::io::Logger& logger) override;
313 
315  bool isExtensible() const;
316 
320  const_iterator begin() const;
324  const_iterator end() const;
325 
329  std::ptrdiff_t find(const smtk::common::UUID& compId) const;
333  std::ptrdiff_t find(const PersistentObjectPtr& component) const;
334 
335  // Returns Read/Write/DoNotLock for read locking, write locking, or bypassing
336  // locks.
337  smtk::resource::LockType lockType() const;
338 
346  void visitChildren(
347  std::function<void(smtk::attribute::ItemPtr, bool)> visitor,
348  bool activeChildren = true) override;
349 
352  std::size_t numberOfChildrenItems() const { return m_childrenItems.size(); }
353 
357  const std::map<std::string, smtk::attribute::ItemPtr>& childrenItems() const
358  {
359  return m_childrenItems;
360  }
361 
364  std::size_t numberOfActiveChildrenItems() const { return m_activeChildrenItems.size(); }
368  {
369  if (static_cast<std::size_t>(i) >= m_activeChildrenItems.size())
370  {
372  return item;
373  }
374  return m_activeChildrenItems[static_cast<std::size_t>(i)];
375  }
376 
381  std::size_t currentConditional() const { return m_currentConditional; }
382 
383 protected:
384  friend class ReferenceItemDefinition;
385  friend class ValueItemDefinition;
386  friend class Definition;
387 
389  ReferenceItem(Attribute* owningAttribute, int itemPosition);
391  ReferenceItem(Item* owningItem, int myPosition, int mySubGroupPosition);
392 
394  bool setDefinition(smtk::attribute::ConstItemDefinitionPtr def) override;
395 
397  PersistentObjectPtr value(const ReferenceItem::Key& key) const;
398 
401  bool resolve() const;
402 
404  Key linkTo(const PersistentObjectPtr& val);
405 
406  bool isValidInternal(bool useCategories, const std::set<std::string>& categories) const override;
407 
408  std::vector<Key> m_keys;
414 
416  smtk::attribute::ItemPtr findInternal(const std::string& name, SearchStyle style) override;
417  smtk::attribute::ConstItemPtr findInternal(const std::string& name, SearchStyle style)
418  const override;
419 
421  void updateActiveChildrenItems();
422 
423 private:
430  template<typename I>
431  bool iteratorIsSet(const I& iterator) const;
432 
433  void assignToCache(std::size_t i, const PersistentObjectPtr& obj) const;
434  void appendToCache(const PersistentObjectPtr& obj) const;
435 
436  struct Cache;
437  mutable std::unique_ptr<Cache> m_cache;
439  std::map<std::string, smtk::attribute::ItemPtr> m_childrenItems;
441  std::vector<smtk::attribute::ItemPtr> m_activeChildrenItems;
443  std::size_t m_currentConditional;
446  std::size_t m_nextUnsetPos;
447 };
448 
449 template<>
450 SMTKCORE_EXPORT bool ReferenceItem::iteratorIsSet<ReferenceItem::const_iterator>(
451  const ReferenceItem::const_iterator& iterator) const;
452 
453 template<typename I>
454 bool ReferenceItem::setValues(
455  I vbegin,
456  I vend,
457  typename std::iterator_traits<I>::difference_type offset)
458 {
459  bool ok = false;
460  std::size_t num = std::distance(vbegin, vend) + offset;
461  if (this->setNumberOfValues(num))
462  {
463  ok = true;
464  std::size_t firstUnsetPos = -1;
465  std::size_t i = 0;
466  for (I it = vbegin; it != vend; ++it, ++i)
467  {
468  if (!iteratorIsSet(it))
469  {
470  if (firstUnsetPos > (offset + i))
471  {
472  firstUnsetPos = offset + i;
473  }
474  continue;
475  }
476 
477  if (!this->setValue(offset + i, *it))
478  {
479  // This value is also now unset
480  if (firstUnsetPos > (offset + i))
481  {
482  firstUnsetPos = offset + i;
483  }
484  ok = false;
485  break;
486  }
487  }
488  if (m_nextUnsetPos > firstUnsetPos)
489  {
490  m_nextUnsetPos = firstUnsetPos;
491  }
492  }
493  // Enable or disable the item if it is optional.
494  if (ok)
495  {
496  this->setIsEnabled(num > 0);
497  }
498  return ok;
499 }
500 
501 template<typename I>
502 bool ReferenceItem::appendValues(I vbegin, I vend)
503 {
504  return this->setValues(vbegin, vend, this->numberOfValues());
505 }
506 
507 template<typename I, typename T>
508 bool ReferenceItem::setValuesVia(
509  I vbegin,
510  I vend,
511  const T& converter,
512  typename std::iterator_traits<I>::difference_type offset)
513 {
514  bool ok = false;
515  std::size_t num = std::distance(vbegin, vend) + offset;
516  if (this->setNumberOfValues(num))
517  {
518  ok = true;
519  std::size_t i = 0;
520  std::size_t firstUnsetPos = -1;
521  for (I it = vbegin; it != vend; ++it, ++i)
522  {
523  if (!iteratorIsSet(it))
524  {
525  if (firstUnsetPos > (offset + i))
526  {
527  firstUnsetPos = offset + i;
528  }
529  continue;
530  }
531 
532  if (!this->setValue(offset + i, converter(*it)))
533  {
534  if (firstUnsetPos > (offset + i))
535  {
536  firstUnsetPos = offset + i;
537  }
538  ok = false;
539  break;
540  }
541  }
542  if (m_nextUnsetPos > firstUnsetPos)
543  {
544  m_nextUnsetPos = firstUnsetPos;
545  }
546  }
547  // Enable or disable the item if it is optional.
548  if (ok)
549  {
550  this->setIsEnabled(num > 0);
551  }
552  return ok;
553 }
554 
555 template<typename I, typename T>
556 bool ReferenceItem::appendValuesVia(I vbegin, I vend, const T& converter)
557 {
558  return this->setValuesVia(vbegin, vend, converter, this->numberOfValues());
559 }
560 
561 template<typename I>
562 bool ReferenceItem::iteratorIsSet(const I& iterator) const
563 {
564  return !!(*iterator);
565 }
566 
567 } // namespace attribute
568 } // namespace smtk
569 
570 #endif
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::attribute::Item::Type
Type
Definition: Item.h:52
smtk::attribute::Definition
Definition: Definition.h:45
smtk::attribute::SearchStyle
SearchStyle
How should searches for items be conducted?
Definition: SearchStyle.h:24
smtk::attribute::ReferenceItem::activeChildItem
smtk::attribute::ItemPtr activeChildItem(std::size_t i) const
Return the i th active child item associated with the item.
Definition: ReferenceItem.h:367
smtk::attribute::Item::setIsEnabled
void setIsEnabled(bool isEnabledValue)
Set the instance's local enabled state.
Definition: Item.h:181
smtk::attribute::Item::assign
virtual bool assign(const smtk::attribute::ConstItemPtr &sourceItem, unsigned int options)
Assigns this item to be equivalent to another.
Definition: Item.cxx:292
smtk::attribute::ReferenceItem::as
void as(Container &result, std::function< typename Container::value_type(const PersistentObjectPtr &)> converter=[](const PersistentObjectPtr &obj) { return obj;}) const
Populate a container of the given type with members of this item.
Definition: ReferenceItem.h:178
smtk::attribute::ReferenceItem::setValue
bool setValue(const PersistentObjectPtr &val)
Set the component stored with this item.
Definition: ReferenceItem.cxx:474
smtk::attribute::ReferenceItem::m_referencedAttribute
smtk::attribute::WeakAttributePtr m_referencedAttribute
In order to clean up its links when being deleted the item needs to track its referencing attribute.
Definition: ReferenceItem.h:413
smtk::attribute::ConstItemDefinitionPtr
smtk::shared_ptr< const smtk::attribute::ItemDefinition > ConstItemDefinitionPtr
Definition: PublicPointerDefs.h:475
smtk::attribute::ReferenceItem::numberOfChildrenItems
std::size_t numberOfChildrenItems() const
Return the number of all children items associated with the item.
Definition: ReferenceItem.h:352
smtk::common::UUID
Definition: UUID.h:38
smtk::io::Logger
Log messages for later presentation to a user or a file.
Definition: Logger.h:95
smtk::attribute::ReferenceItem::childrenItems
const std::map< std::string, smtk::attribute::ItemPtr > & childrenItems() const
Return the map of all children items.
Definition: ReferenceItem.h:357
smtk::attribute::ReferenceItem::currentConditional
std::size_t currentConditional() const
Return the index of the current active conditional.
Definition: ReferenceItem.h:381
smtk::attribute::ReferenceItem::setNumberOfValues
bool setNumberOfValues(std::size_t newSize)
Set the number of entities to be associated with this item (returns true if permitted).
Definition: ReferenceItem.cxx:317
smtk::attribute::ReferenceItemDefinition
A definition for attribute items that store smtk::resource::PersistentObjectPtr as values.
Definition: ReferenceItemDefinition.h:40
smtk::project::Container
boost::multi_index_container< ProjectPtr, indexed_by< ordered_unique< tag< IdTag >, global_fun< const ProjectPtr &, const smtk::common::UUID &, &smtk::project::detail::id > >, ordered_non_unique< tag< IndexTag >, global_fun< const ProjectPtr &, smtk::project::Project::Index, &smtk::project::detail::index > >, ordered_non_unique< tag< NameTag >, global_fun< const ProjectPtr &, std::string, &smtk::project::detail::name > >, ordered_non_unique< tag< LocationTag >, global_fun< const ProjectPtr &, const std::string &, &smtk::project::detail::location > > > > Container
A multi-index container for accessing projects.
Definition: Container.h:67
smtk::attribute::Item
Definition: Item.h:43
smtkTypeMacro
#define smtkTypeMacro(...)
Add typedefs to a class for identifcation.
Definition: SharedFromThis.h:51
smtk::attribute::ReferenceItem
Hold associations that link resources or components as an attribute value.
Definition: ReferenceItem.h:51
smtk::attribute::ReferenceItem::Cache
Internally, ReferenceItems cache retrieved PersistentObjects to speed up repeated calls to their cont...
Definition: ReferenceItem.cxx:37
smtk::attribute::ConstItemPtr
smtk::shared_ptr< const smtk::attribute::Item > ConstItemPtr
Definition: PublicPointerDefs.h:469
smtk::attribute::ValueItemDefinition
Definition: ValueItemDefinition.h:41
smtk::attribute::ReferenceItem::numberOfValues
std::size_t numberOfValues() const
Return the size of the item (number of entities associated with the item).
Definition: ReferenceItem.cxx:312
smtk::attribute::ReferenceItem::type
Item::Type type() const override
Indicate we are a reference to a persistent object.
Definition: ReferenceItem.h:123
smtkSuperclassMacro
#define smtkSuperclassMacro(...)
Add a typedef to the superclass of this class.
Definition: SharedFromThis.h:87
smtk::attribute::Attribute
Represent a (possibly composite) value according to a definition.
Definition: Attribute.h:49
smtk::attribute::ReferenceItem::Key
std::pair< smtk::common::UUID, smtk::common::UUID > Key
A Key is a pair of UUIDs.
Definition: ReferenceItem.h:112
smtk::attribute::ReferenceItem::numberOfActiveChildrenItems
std::size_t numberOfActiveChildrenItems() const
Return the number of active children items associated with the item.
Definition: ReferenceItem.h:364
smtk::resource::PersistentObjectPtr
smtk::shared_ptr< smtk::resource::PersistentObject > PersistentObjectPtr
Definition: PublicPointerDefs.h:285
smtk::attribute::ItemPtr
smtk::shared_ptr< smtk::attribute::Item > ItemPtr
Definition: PublicPointerDefs.h:467
smtk::attribute::ReferenceItem::const_iterator
An iterator for references held by a ReferenceItem.
Definition: ReferenceItem.h:62
smtk::attribute::ReferenceItem::const_iterator::CacheIterator
Definition: ReferenceItem.cxx:64
smtk::attribute::WeakAttributePtr
smtk::weak_ptr< smtk::attribute::Attribute > WeakAttributePtr
Definition: PublicPointerDefs.h:460