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"
52 template<
typename Type>
59 template<
typename Type>
74 std::size_t count = 0;
75 for (
auto& pair : this->data())
77 count += pair.second.erase(
id);
94 template<
typename List>
97 insertPropertyTypes<List>();
100 template<
typename List>
103 insertPropertyTypes<List>();
108 std::size_t count = 0;
109 auto& map = this->data();
110 for (
auto& pair : map)
117 template<
typename Type>
120 return dynamic_cast<PropertiesBase&
>(this->get<Type>()).eraseId(
id);
126 template<
typename Type>
127 void insertPropertyType()
129 std::string key = smtk::common::typeName<Type>();
130 auto it = data().find(key);
131 if (it == data().end())
137 template<
typename Tuple>
138 void insertPropertyTypes()
140 Properties::insertPropertyTypes<0, Tuple>();
144 template<std::
size_t I,
typename Tuple>
145 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type insertPropertyTypes()
147 this->insertPropertyType<typename std::tuple_element<I, Tuple>::type>();
148 Properties::insertPropertyTypes<I + 1, Tuple>();
151 template<std::
size_t I,
typename Tuple>
152 inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type insertPropertyTypes()
165 template<
typename Type>
168 using IndexedType = std::unordered_map<smtk::common::UUID, Type>;
175 , m_properties(properties)
183 if (!m_properties.contains(key))
187 const std::unordered_map<smtk::common::UUID, Type>& data = get(key);
188 return (data.find(m_id) != data.end());
192 const Type&
at(
const std::string& key)
const {
return get(key).at(m_id); }
197 using PropertyDataMap =
198 std::unordered_map<std::string, std::unordered_map<smtk::common::UUID, Type>>;
199 const PropertyDataMap& data = m_properties.data();
201 data.begin(), data.end(), [
this](
const typename PropertyDataMap::value_type& pair) {
202 return pair.second.find(m_id) == pair.second.end();
206 std::set<std::string> keys()
const
208 std::set<std::string> keys;
209 for (
auto& pair : m_properties.data())
211 if (pair.second.find(m_id) != pair.second.end())
213 keys.insert(pair.first);
220 const std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
const
222 return m_properties.at(key);
226 const detail::PropertiesOfType<IndexedType>& m_properties;
232 template<
typename Type>
235 using IndexedType = std::unordered_map<smtk::common::UUID, Type>;
240 , m_properties(properties)
248 if (!m_properties.contains(key))
252 const std::unordered_map<smtk::common::UUID, Type>& data = get(key);
253 return (data.find(m_id) != data.end());
257 bool insert(
const std::string& key,
const Type& value)
259 return get(key).insert(std::make_pair(m_id, value)).second;
263 bool emplace(
const std::string& key, Type&& value)
265 return get(key).emplace(std::make_pair(m_id, std::move(value))).second;
271 get(key).erase(m_id);
272 if (get(key).
empty())
274 m_properties.erase(key);
279 Type&
operator[](
const std::string& key) {
return get(key)[m_id]; }
282 Type&
at(
const std::string& key) {
return get(key).at(m_id); }
285 const Type&
at(
const std::string& key)
const {
return get(key).at(m_id); }
290 for (
auto& pair : m_properties.data())
292 if (pair.second.find(m_id) != pair.second.end())
305 std::size_t count = m_properties.eraseId(m_id);
309 std::set<std::string> keys()
const
311 std::set<std::string> keys;
312 for (
auto& pair : m_properties.data())
314 if (pair.second.find(m_id) != pair.second.end())
316 keys.insert(pair.first);
323 const std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
const
325 return m_properties.at(key);
327 std::unordered_map<smtk::common::UUID, Type>& get(
const std::string& key)
329 if (!m_properties.contains(key))
331 m_properties.emplace(key,
typename detail::PropertiesOfType<IndexedType>::mapped_type());
333 return m_properties.at(key);
337 detail::PropertiesOfType<IndexedType>& m_properties;
349 template<
typename Type>
350 using Indexed = std::unordered_map<smtk::common::UUID, Type>;
353 template<
typename Type>
356 return get<Type>().contains(key);
360 template<
typename Type>
361 bool insert(
const std::string& key,
const Type& value)
363 return get<Type>().insert(key, value);
367 template<
typename Type>
368 bool emplace(
const std::string& key, Type&& value)
370 return get<Type>().emplace(key, std::forward<Type>(value));
374 template<
typename Type>
377 return get<Type>().erase(key);
381 template<
typename Type>
382 Type&
at(
const std::string& key)
384 return get<Type>().at(key);
388 template<
typename Type>
389 const Type&
at(
const std::string& key)
const
391 return get<Type>().at(key);
395 template<
typename Type>
404 template<
typename Type>
410 properties().get<Indexed<Type>>()));
414 virtual std::size_t clear() = 0;
421 struct EraseProperties
423 template<
typename Data>
424 void operator()(Data propertiesOfType,
const smtk::common::UUID& uid, std::size_t& count)
426 std::cout <<
"Erase " << uid <<
" from " << propertiesOfType.keys().size() <<
"\n";
427 count += propertiesOfType.clear();
437 template<
typename Tuple,
typename Functor,
typename... Args>
438 void invoke(Args&&... args)
const
440 smtk::resource::Properties::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
443 template<
typename Tuple,
typename Functor,
typename... Args>
444 void invoke(Args&&... args)
446 smtk::resource::Properties::invokeFunctors<0, Tuple, Functor>(std::forward<Args>(args)...);
451 template<
typename Entry,
typename Functor,
typename... Args>
452 void invokeFunctor(Args&&... args)
const
455 f(std::forward<Args>(args)...);
459 template<
typename Entry,
typename Functor,
typename... Args>
460 void invokeFunctor(Args&&... args)
463 f(std::forward<Args>(args)...);
467 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
468 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
469 Args&&... args)
const
471 this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
473 this->
template get<typename std::tuple_element<I, Tuple>::type>(),
475 std::forward<Args>(args)...);
476 smtk::resource::Properties::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
480 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
481 inline typename std::enable_if<I != std::tuple_size<Tuple>::value>::type invokeFunctors(
484 this->invokeFunctor<typename std::tuple_element<I, Tuple>::type, Functor>(
486 this->
template get<typename std::tuple_element<I, Tuple>::type>(),
488 std::forward<Args>(args)...);
489 smtk::resource::Properties::invokeFunctors<I + 1, Tuple, Functor>(std::forward<Args>(args)...);
493 template<std::size_t I,
typename Tuple,
typename Functor,
typename... Args>
494 inline typename std::enable_if<I == std::tuple_size<Tuple>::value>::type invokeFunctors(
503 template<
typename PropertyTypeTuple>
506 std::size_t count = 0;
508 this->invoke<PropertyTypeTuple, EraseProperties>(uid, count);
534 Indexed<std::string>,
535 Indexed<smtk::string::Token>,
536 Indexed<std::set<smtk::string::Token>>,
537 Indexed<std::set<int>>,
538 Indexed<std::vector<bool>>,
539 Indexed<std::vector<int>>,
540 Indexed<std::vector<long>>,
541 Indexed<std::vector<double>>,
542 Indexed<std::vector<std::string>>,
543 Indexed<smtk::resource::properties::CoordinateFrame>,
544 Indexed<std::map<std::string, smtk::resource::properties::CoordinateFrame>>>
548 const ResourcePropertiesData& data()
const {
return m_data; }
553 template<
typename Type>
554 void insertPropertyType()
556 m_data.insertPropertyType<Indexed<Type>>();
562 std::size_t count = this->clearInternal<PropertyTypes>(this->
id());
573 Resource* m_resource;
574 ResourcePropertiesData m_data;
586 std::size_t count = this->clearInternal<ResourceProperties::PropertyTypes>(this->
id());