Honeycomb  0.1
Component-Model Framework
PropertyObject.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Object/Object.h"
7 
8 namespace honey
9 {
10 
14 
16 namespace property { namespace priv
17 {
19  template<class T> static Property<T>& create(const String& name) { return *new Property<T>(name); }
20 } }
23 class PropertyObject : public Object
25 {
26 public:
29 
31 
33  virtual ~PropertyObject() {}
34 
36 
40  {
41  assert(prop.id() != idnull, "Property must have valid id");
42  PropertyBase::Ptr ptr = &prop;
43  auto res = _propMap.insert(make_pair(prop.id(), ptr));
44  if (res.second) return;
45  res.first->second = ptr;
46  }
47 
49  void addProp(PropertyBase* prop) { assert(prop); addProp(*prop); }
50 
52  bool hasProp(const Id& id) const { return _propMap.find(id) != _propMap.end(); }
53 
55  template<class T>
56  bool hasProp(const Id& id) const
57  {
58  auto it = _propMap.find(id);
59  return it != _propMap.end() && it->second->type() == Property<T>::s_type();
60  }
61 
63  template<class T>
64  Property<T>& prop(const String& name)
65  {
66  Id id = name;
68  auto it = _propMap.find(id);
69  if (it != _propMap.end())
70  prop = it->second;
71  else
72  {
73  //Property doesn't exist, add it
74  prop = &property::priv::create<T>(name);
75  addProp(*prop);
76  }
77  assert(prop->type() == Property<T>::s_type(),
78  sout() << "Component type mismatch: "
79  << "Request: " << Property<T>::s_type() << " ; Id: " << id
80  << " ; Found: " << prop->type());
81  return static_cast<Property<T>&>(*prop);
82  }
83 
85  template<class T>
86  Property<T>& prop(const Id& id) { return prop_<T>(id); }
87  template<class T>
88  const Property<T>& prop(const Id& id) const { return prop_<T>(id); }
89 
91  PropertyBase& prop(const Id& id) { return prop_(id); }
92  const PropertyBase& prop(const Id& id) const { return prop_(id); }
93 
95  template<class T, class T_ = typename mt::removeRef<T>::type>
96  Property<T_>& prop(const String& name, T&& val) { return prop<T_>(name) = forward<T>(val); }
98  template<class T, class T_ = typename mt::removeRef<T>::type>
99  Property<T_>& prop(const Id& id, T&& val) { return prop<T_>(id) = forward<T>(val); }
100 
102  const PropertyMap& props() { return _propMap; }
103  const PropertyMapConst& props() const { return reinterpret_cast<const PropertyMapConst&>(_propMap); }
104 
107 
110  {
111  auto it = _propMap.find(id);
112  return it != _propMap.end() ? removeProp(it) : nullptr;
113  }
114 
116  void removeProps(const function<void (PropertyBase&)>& f = [](PropertyBase&){})
117  {
118  while (!_propMap.empty()) { f(*removeProp(_propMap.begin())); }
119  }
120 
121 private:
122  template<class T>
123  Property<T>& prop_(const Id& id) const
124  {
125  auto it = _propMap.find(id);
126  if (it == _propMap.end()) throw_ PropertyError() << "Property not found. Id: " << id;
127  PropertyBase* prop = it->second;
128  assert(prop->type() == Property<T>::s_type(),
129  sout() << "Component type mismatch: "
130  << "Request: " << Property<T>::s_type() << " ; Id: " << id
131  << " ; Found: " << prop->type());
132  return static_cast<Property<T>&>(*prop);
133  }
134 
135  PropertyBase& prop_(const Id& id) const
136  {
137  auto it = _propMap.find(id);
138  if (it == _propMap.end()) throw_ PropertyError() << "Property not found. Id: " << id;
139  return *it->second;
140  }
141 
143  PropertyBase::Ptr removeProp(PropertyMap::iterator it)
144  {
145  PropertyBase::Ptr prop = it->second;
146  _propMap.erase(it);
147  return prop;
148  }
149 
150  PropertyMap _propMap;
151 };
152 
154 
155 }
156 
stdutil::unordered_map< Id, PropertyBase::Ptr, SmallAllocator > PropertyMap
Definition: PropertyObject.h:27
PropertyObject()
Definition: PropertyObject.h:30
Property< T > & prop(const Id &id)
Get property with id of type T. Throws PropertyError if property doesn't exist.
Definition: PropertyObject.h:86
Combined intrusive/non-intrusive smart pointer. Can reference and share any object automatically...
Definition: SharedPtr.h:175
virtual ~PropertyObject()
Releases all contained properties.
Definition: PropertyObject.h:33
bool hasProp(const Id &id) const
Check if object contains property with id and type T.
Definition: PropertyObject.h:56
PropertyBase::Ptr removeProp(const Id &id)
Remove a single property with id. Returns property if found and removed.
Definition: PropertyObject.h:109
void removeProps(const function< void(PropertyBase &)> &f=[](PropertyBase &){})
Remove all properties. Calls functor for each removed property.
Definition: PropertyObject.h:116
std::unordered_map< Key, Value, std::hash< Key >, std::equal_to< Key >, Alloc< pair< const Key, Value >>> unordered_map
std::unordered_map with custom allocator
Definition: StdUtil.h:83
const PropertyMap & props()
Get all properties.
Definition: PropertyObject.h:102
const PropertyBase & prop(const Id &id) const
Definition: PropertyObject.h:92
PropertyBase::Ptr removeProp(PropertyBase &prop)
Remove a single property. Returns property if found and removed.
Definition: PropertyObject.h:106
Property< T_ > & prop(const Id &id, T &&val)
Assign property with id to value. Throws PropertyError if property doesn't exist. Returns assigned pr...
Definition: PropertyObject.h:99
const PropertyMapConst & props() const
Definition: PropertyObject.h:103
#define EXCEPTION(Class)
Declares methods required for every subclass of honey::Exception.
Definition: Exception.h:17
SharedPtr< PropertyBase > Ptr
Definition: Property.h:17
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
Definition: PropertyObject.h:13
const Property< T > & prop(const Id &id) const
Definition: PropertyObject.h:88
Property< T_ > & prop(const String &name, T &&val)
Assign property with name to value. Adds property if it doesn't exist. Returns assigned property...
Definition: PropertyObject.h:96
Base class for all properties.
Definition: Property.h:14
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
std::enable_if< std::is_default_constructible< Com >::value &&!std::is_abstract< Com >::value, Component & >::type create()
Called by registry to create a component. May be specialized for a component type.
Definition: Component.h:75
#define idnull
Null id.
Definition: Id.h:124
Unicode UTF-16 string class, wrapper around std::u16string.
Definition: String.h:23
Base exception class. Exceptions inherited from this class provide debug info and can be thrown polym...
Definition: Exception.h:45
stdutil::unordered_map< Id, PropertyBase::ConstPtr, SmallAllocator > PropertyMapConst
Definition: PropertyObject.h:28
void addProp(PropertyBase &prop)
Add a property reference. Any existing property with the same id will be released and replaced...
Definition: PropertyObject.h:39
#define throw_
Use in place of throw keyword to throw a honey::Exception object polymorphically and provide debug in...
Definition: Exception.h:11
const Id & id() const
Get property id.
Definition: Property.h:25
static const NameId & s_type()
Static function to get property type info.
void addProp(PropertyBase *prop)
Wrapper for pointer arg.
Definition: PropertyObject.h:49
Holds a name string and its hashed value for fast comparison ops. See String Identifier.
Definition: Id.h:25
Property< T > & prop(const String &name)
Get property with name of type T. Adds property if it doesn't exist.
Definition: PropertyObject.h:64
bool hasProp(const Id &id) const
Check if object contains property with id.
Definition: PropertyObject.h:52
Global Honeycomb namespace.
Generic property.
Definition: Property.h:37
PropertyBase & prop(const Id &id)
Get property with id. Throws PropertyError if property doesn't exist.
Definition: PropertyObject.h:91