-
Notifications
You must be signed in to change notification settings - Fork 1
/
component.hpp
117 lines (96 loc) · 2.9 KB
/
component.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* component.hpp -- data model for entity components
*
* Ryan McDougall
*/
#ifndef COMPONENT_H_
#define COMPONENT_H_
namespace Scaffold
{
namespace Model
{
class PropertyBase : public Tagged
{
public:
PropertyBase (const Tag &t) : Tagged (t) {}
public:
Subscription <void(PropertyBase*)> on_access;
Subscription <void(PropertyBase*)> on_change;
};
template <typename T>
class Property : public PropertyBase
{
public:
Property (const Tag &t, T def = T())
: PropertyBase (t), default_ (def)
{
reset();
}
virtual ~Property ()
{
}
public:
operator T ()
{
return get();
}
Property operator= (const T &v)
{
set (v);
return *this;
}
public:
T get ()
{
on_access (this);
on_value_access (prop_);
return prop_;
}
void set (const T &v)
{
prop_ = v;
on_access (this);
on_change (this);
on_value_access (prop_);
on_value_change (prop_);
}
void reset ()
{
set (default_);
}
public:
Subscription <void(T)> on_value_access;
Subscription <void(T)> on_value_change;
private:
T prop_;
T default_;
};
class Component : public Tagged
{
public:
typedef std::vector <Component *> List;
typedef std::map <Tag, Component *> Map;
Component (const Tag &t)
: Tagged (t)
{}
void observe (PropertyBase &prop)
{
using namespace std::tr1::placeholders;
prop.on_access += bind (&Component::property_access_, this, _1);
prop.on_change += bind (&Component::property_change_, this, _1);
}
public:
Subscription <void(Component*)> on_access;
Subscription <void(Component*)> on_change;
protected:
void property_access_ (PropertyBase *prop)
{
on_access (this);
}
void property_change_ (PropertyBase *prop)
{
on_change (this);
}
};
}
}
#endif //COMPONENT_H_