11 #ifndef smtk_resource_Properties_h
12 #define smtk_resource_Properties_h
14 #include "smtk/CoreExports.h"
15 #include "smtk/common/TypeMap.h"
16 #include "smtk/common/UUID.h"
17 #include "smtk/string/Token.h"
19 #include "smtk/common/json/jsonUUID.h"
20 #include "smtk/string/json/jsonToken.h"
22 #include "smtk/resource/json/jsonPropertyCoordinateFrame.h"
23 #include "smtk/resource/properties/CoordinateFrame.h"
55 virtual bool isCopyable()
const = 0;
64 virtual std::size_t copyFrom(
71 virtual void allIds(std::set<smtk::common::UUID>& ids)
const = 0;
73 virtual void allNames(std::unordered_set<smtk::string::Token>& names)
const = 0;
75 virtual void idsWithProperty(
smtk::string::Token& propName, std::set<smtk::common::UUID>& ids)
79 template<
typename Type>
86 template<
typename Type>
102 template<
typename PropType = Type>
103 typename std::enable_if<!std::is_copy_constructible<PropType>::value,
bool>::type operator()()
108 template<
typename PropType = Type>
109 typename std::enable_if<std::is_copy_constructible<PropType>::value,
bool>::type operator()()
118 template<
typename PropType = Type>
119 typename std::enable_if<!std::is_copy_constructible<PropType>::value, std::size_t>::type
135 template<
typename PropType = Type>
136 typename std::enable_if<std::is_copy_constructible<PropType>::value, std::size_t>::type
144 std::size_t numCopied = 0;
148 if (!other || !uid || !otherId)
152 if (propertyName.
valid())
155 auto nameIt = other->data().find(propertyName.
data());
156 if (nameIt == other->data().end())
160 auto valIt = nameIt->second.find(otherId);
161 if (valIt == nameIt->second.end())
166 self->data()[nameIt->first][uid] = valIt->second;
171 for (
const auto& pair : other->data())
173 auto fromIt = pair.second.find(otherId);
174 if (fromIt != pair.second.end())
177 self->data()[pair.first][uid] = fromIt->second;
188 std::size_t count = 0;
189 for (
auto& pair : this->data())
191 count += pair.second.erase(
id);
196 bool isCopyable()
const override {
return std::is_copy_constructible<Type>::value; }
204 return Copier()(
this, otherBase, propertyName, otherId, uid);
207 void allNames(std::unordered_set<smtk::string::Token>& names)
const override
209 for (
const auto& nameToCompToValue : this->data())
211 names.insert(nameToCompToValue.first);
215 void allIds(std::set<smtk::common::UUID>& ids)
const override
217 for (
const auto& nameToCompToValue : this->data())
219 for (
const auto& compToValue : nameToCompToValue.second)
221 ids.insert(compToValue.first);
229 auto nameIt = this->data().find(propName.
data());
230 if (nameIt == this->data().end())
234 for (
const auto& compToValue : nameIt->second)
236 ids.insert(compToValue.first);
252 template<
typename List>
255 insertPropertyTypes<List>();
258 template<
typename List>
261 insertPropertyTypes<List>();
266 std::size_t count = 0;
267 auto& map = this->data();
268 for (
auto& pair : map)
275 template<
typename Type>
278 return dynamic_cast<PropertiesBase&
>(this->get<Type>()).eraseId(
id);
284 template<
typename Type>
285 void insertPropertyType()
287 std::string key = smtk::common::typeName<Type>();
288 auto it = data().find(key);
289 if (it == data().end())
295 template<
typename Tuple>
296 void insertPropertyTypes()
298 Properties::insertPropertyTypes<0, Tuple>();
302 template<std::
size_t I,
typename Tuple>
303 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type insertPropertyTypes()
305 this->insertPropertyType<typename std::tuple_element<I, Tuple>::type>();
306 Properties::insertPropertyTypes<I + 1, Tuple>();
309 template<std::
size_t I,
typename Tuple>
310 inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type insertPropertyTypes()
323 template<
typename Type>
326 using IndexedType = std::unordered_map<smtk::common::UUID, Type>;
333 , m_properties(properties)
341 if (!m_properties.contains(key))
345 const std::unordered_map<smtk::common::UUID, Type>& data = get(key);
346 return (data.find(m_id) != data.end());
350 const Type&
at(
const std::string& key)
const {
return get(key).at(m_id); }
355 using PropertyDataMap =
356 std::unordered_map<std::string, std::unordered_map<smtk::common::UUID, Type>>;
357 const PropertyDataMap& data = m_properties.data();
359 data.begin(), data.end(), [
this](
const typename PropertyDataMap::value_type& pair) {
360 return pair.second.find(m_id) == pair.second.end();
364 std::set<std::string> keys()
const
366 std::set<std::string> keys;
367 for (
auto& pair : m_properties.data())
369 if (pair.second.find(m_id) != pair.second.end())
371 keys.insert(pair.first);
378 const std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
const
380 return m_properties.at(key);
384 const detail::PropertiesOfType<IndexedType>& m_properties;
390 template<
typename Type>
393 using IndexedType = std::unordered_map<smtk::common::UUID, Type>;
398 , m_properties(properties)
406 if (!m_properties.contains(key))
410 const std::unordered_map<smtk::common::UUID, Type>& data = get(key);
411 return (data.find(m_id) != data.end());
415 bool insert(
const std::string& key,
const Type& value)
417 return get(key).insert(std::make_pair(m_id, value)).second;
421 bool emplace(
const std::string& key, Type&& value)
423 return get(key).emplace(std::make_pair(m_id, std::move(value))).second;
429 get(key).erase(m_id);
430 if (get(key).
empty())
432 m_properties.erase(key);
437 Type&
operator[](
const std::string& key) {
return get(key)[m_id]; }
440 Type&
at(
const std::string& key) {
return get(key).at(m_id); }
443 const Type&
at(
const std::string& key)
const {
return get(key).at(m_id); }
448 for (
auto& pair : m_properties.data())
450 if (pair.second.find(m_id) != pair.second.end())
463 std::size_t count = m_properties.eraseId(m_id);
467 std::set<std::string> keys()
const
469 std::set<std::string> keys;
470 for (
auto& pair : m_properties.data())
472 if (pair.second.find(m_id) != pair.second.end())
474 keys.insert(pair.first);
481 const std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
const
483 return m_properties.at(key);
485 std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
487 if (!m_properties.contains(key))
489 m_properties.emplace(key,
typename detail::PropertiesOfType<IndexedType>::mapped_type());
491 return m_properties.at(key);
495 detail::PropertiesOfType<IndexedType>& m_properties;
509 template<
typename Type>
510 using Indexed = std::unordered_map<smtk::common::UUID, Type>;
513 template<
typename Type>
516 return get<Type>().contains(key);
520 template<
typename Type>
521 bool insert(
const std::string& key,
const Type& value)
523 return get<Type>().insert(key, value);
527 template<
typename Type>
528 bool emplace(
const std::string& key, Type&& value)
530 return get<Type>().emplace(key, std::forward<Type>(value));
534 template<
typename Type>
537 return get<Type>().erase(key);
541 template<
typename Type>
542 Type&
at(
const std::string& key)
544 return get<Type>().at(key);
548 template<
typename Type>
549 const Type&
at(
const std::string& key)
const
551 return get<Type>().at(key);
555 template<
typename Type>
564 template<
typename Type>
570 properties().get<Indexed<Type>>()));
574 virtual std::size_t clear() = 0;
577 std::unordered_set<smtk::string::Token>
types()
const
579 std::unordered_set<smtk::string::Token> result;
580 const auto& tmap = this->properties().data();
581 for (
const auto& entry : tmap)
583 result.insert(entry.first);
591 std::unordered_set<smtk::string::Token> result;
592 const auto& tmap = this->properties().data();
593 auto it = tmap.find(storageType.
data());
594 if (it == tmap.end())
611 struct EraseProperties
613 template<
typename Data>
614 void operator()(Data propertiesOfType,
const smtk::common::UUID& uid, std::size_t& count)
616 std::cout <<
"Erase " << uid <<
" from " << propertiesOfType.keys().size() <<
"\n";
617 count += propertiesOfType.clear();
627 template<
typename Tuple,
typename Functor,
typename... Args>
628 void invoke(Args&&... args)
const
630 smtk::resource::Properties::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
633 template<
typename Tuple,
typename Functor,
typename... Args>
634 void invoke(Args&&... args)
636 smtk::resource::Properties::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
641 template<
typename Entry,
typename Functor,
typename... Args>
642 void invokeFunctor(Args&&... args)
const
645 f(std::forward<Args>(args)...);
649 template<
typename Entry,
typename Functor,
typename... Args>
650 void invokeFunctor(Args&&... args)
653 f(std::forward<Args>(args)...);
657 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
658 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
659 Args&&... args)
const
661 this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
663 this->
template get<typename std::tuple_element<I, Tuple>::type>(),
665 std::forward<Args>(args)...);
666 smtk::resource::Properties::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
670 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
671 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
674 this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
676 this->
template get<typename std::tuple_element<I, Tuple>::type>(),
678 std::forward<Args>(args)...);
679 smtk::resource::Properties::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
683 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
684 inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type invokeFunctors(
693 template<
typename PropertyTypeTuple>
696 std::size_t count = 0;
698 this->invoke<PropertyTypeTuple, EraseProperties>(uid, count);
724 Indexed<std::string>,
725 Indexed<smtk::string::Token>,
726 Indexed<std::set<smtk::string::Token>>,
727 Indexed<std::set<int>>,
728 Indexed<std::vector<bool>>,
729 Indexed<std::vector<int>>,
730 Indexed<std::vector<long>>,
731 Indexed<std::vector<double>>,
732 Indexed<std::vector<std::string>>,
733 Indexed<smtk::resource::properties::CoordinateFrame>,
734 Indexed<std::map<std::string, smtk::resource::properties::CoordinateFrame>>>
738 const ResourcePropertiesData& data()
const {
return m_data; }
743 template<
typename Type>
744 void insertPropertyType()
746 m_data.insertPropertyType<Indexed<Type>>();
752 std::size_t count = this->clearInternal<PropertyTypes>(this->
id());
763 Resource* m_resource;
764 ResourcePropertiesData m_data;
776 std::size_t count = this->clearInternal<ResourceProperties::PropertyTypes>(this->
id());