Skip to content

Commit f62f379

Browse files
committedNov 1, 2014
meta on_change, factory/cache now has metadata, sg.json update
1 parent b23d83c commit f62f379

File tree

6 files changed

+178
-44
lines changed

6 files changed

+178
-44
lines changed
 

‎include/kit/cache/cache.h

+19-11
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,26 @@
77
#include "../kit.h"
88
#include "icache.h"
99

10-
template<class Class, class T>
10+
template<class Class, class T, class Mutex=kit::optional_mutex<std::recursive_mutex>>
1111
class Cache:
12-
public Factory<Class, std::tuple<T, ICache*>>,
12+
public Factory<Class, std::tuple<T, ICache*>, std::string, Mutex>,
1313
public ICache,
14-
virtual public kit::mutexed<std::recursive_mutex>
14+
virtual public kit::mutexed<Mutex>
1515
{
1616
public:
1717

18+
Cache() = default;
19+
Cache(std::string fn):
20+
Factory<Class, std::tuple<T, ICache*>>(fn)
21+
{}
22+
Cache(std::shared_ptr<Meta> cfg):
23+
Factory<Class, std::tuple<T, ICache*>>(cfg)
24+
{}
25+
1826
virtual ~Cache() {}
1927

2028
virtual void optimize() override {
21-
auto l = lock();
29+
auto l = this->lock();
2230
for(auto itr = m_Resources.begin();
2331
itr != m_Resources.end();)
2432
{
@@ -30,7 +38,7 @@ class Cache:
3038
}
3139

3240
virtual std::shared_ptr<Class> cache_raw(const T& arg) {
33-
auto l = lock();
41+
auto l = this->lock();
3442
try{
3543
return m_Resources.at(arg);
3644
}catch(const std::out_of_range&){
@@ -43,7 +51,7 @@ class Cache:
4351
}
4452

4553
virtual std::shared_ptr<Class> cache(T arg) {
46-
auto l = lock();
54+
auto l = this->lock();
4755
if(m_Transformer)
4856
arg = m_Transformer(arg);
4957
return cache_raw(arg);
@@ -55,7 +63,7 @@ class Cache:
5563

5664
template<class Cast>
5765
std::shared_ptr<Cast> cache_as(T arg) {
58-
auto l = lock();
66+
auto l = this->lock();
5967
if(m_Transformer)
6068
arg = m_Transformer(arg);
6169
std::shared_ptr<Cast> p;
@@ -76,24 +84,24 @@ class Cache:
7684
}
7785

7886
virtual size_t size() const override {
79-
auto l = lock();
87+
auto l = this->lock();
8088
return m_Resources.size();
8189
}
8290
virtual bool empty() const override {
83-
auto l = lock();
91+
auto l = this->lock();
8492
return m_Resources.empty();
8593
}
8694

8795
virtual void clear() override {
88-
auto l = lock();
96+
auto l = this->lock();
8997
m_Resources.clear();
9098
}
9199

92100
T transform(const T& t){
93101
return m_Transformer(t);
94102
}
95103
void register_transformer(std::function<T(const T&)> f) {
96-
auto l = lock();
104+
auto l = this->lock();
97105
m_Transformer=f;
98106
}
99107

‎include/kit/factory/factory.h

+38-9
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@
1212
#include <limits>
1313
#include "ifactory.h"
1414
#include "../kit.h"
15+
#include "../meta/meta.h"
1516

1617
// TODO: add some way to have resolvers pass data into constructor instead
1718
// of relying on unchangable ctor parameters (hmm...)
1819
// TODO: or how about add second callback for after the ctor (?)
1920
// Let's use signals :D
2021

21-
template<class Class, class T, class ClassName=std::string>
22+
template<
23+
class Class,
24+
class T,
25+
class ClassName=std::string,
26+
class Mutex=kit::optional_mutex<std::recursive_mutex>
27+
>
2228
class Factory:
2329
public IFactory,
24-
virtual public kit::mutexed<std::recursive_mutex>
30+
virtual public kit::mutexed<Mutex>
2531
{
2632
private:
2733

@@ -44,13 +50,27 @@ class Factory:
4450

4551
std::function<unsigned(const T&)> m_Resolver;
4652
std::function<T(const T&)> m_Transformer;
53+
std::shared_ptr<MetaBase<Mutex>> m_pConfig;
4754

4855
public:
4956

57+
Factory():
58+
m_pConfig(std::make_shared<MetaBase<Mutex>>())
59+
{}
60+
Factory(std::string fn):
61+
m_pConfig(std::make_shared<MetaBase<Mutex>>(fn))
62+
{}
63+
Factory(std::shared_ptr<Meta> cfg):
64+
m_pConfig(std::make_shared<MetaBase<Mutex>>(cfg))
65+
{}
66+
67+
std::shared_ptr<MetaBase<Mutex>> config() { return m_pConfig; }
68+
std::shared_ptr<const MetaBase<Mutex>> config() const { return m_pConfig; }
69+
5070
virtual ~Factory() {}
5171

5272
bool empty() const {
53-
auto l = lock();
73+
auto l = this->lock();
5474
return m_Classes.empty();
5575
}
5676

@@ -62,7 +82,7 @@ class Factory:
6282
) {
6383
// bind subclass's make_shared() to functor and store it in m_Classes list
6484
// TODO: exceptions?
65-
auto l = lock();
85+
auto l = this->lock();
6686

6787
const size_t size = m_Classes.size();
6888
if(id == std::numeric_limits<unsigned>::max()) // don't care about class ID
@@ -92,12 +112,12 @@ class Factory:
92112
}
93113

94114
void register_resolver(std::function<unsigned(const T&)> func) {
95-
auto l = lock();
115+
auto l = this->lock();
96116
m_Resolver = func;
97117
}
98118

99119
unsigned class_id(ClassName name) const {
100-
auto l = lock();
120+
auto l = this->lock();
101121
try{
102122
return m_ClassNames.at(name);
103123
} catch(const std::out_of_range&) {}
@@ -108,14 +128,14 @@ class Factory:
108128
}
109129

110130
std::shared_ptr<Class> create(unsigned id, T args) const {
111-
auto l = lock();
131+
auto l = this->lock();
112132
if(m_Transformer)
113133
args = m_Transformer(args);
114134
return m_Classes.at(id)(args);
115135
}
116136

117137
std::shared_ptr<Class> create(T args) const {
118-
auto l = lock();
138+
auto l = this->lock();
119139
if(m_Transformer)
120140
args = m_Transformer(args);
121141
unsigned id = m_Resolver(args);
@@ -132,13 +152,22 @@ class Factory:
132152
}
133153

134154
void register_transformer(std::function<T(const T&)> f) {
135-
auto l = lock();
155+
auto l = this->lock();
136156
m_Transformer=f;
137157
}
138158

139159
T transform(const T& t){
140160
return m_Transformer(t);
141161
}
162+
163+
void share_config(std::shared_ptr<MetaBase<Mutex>> cfg){
164+
auto l = this->lock();
165+
m_pConfig = cfg;
166+
}
167+
std::shared_ptr<MetaBase<Mutex>> share_config() {
168+
auto l = this->lock();
169+
return m_pConfig;
170+
}
142171

143172
//std::vector<std::shared_ptr<Class>> create_all(
144173
// const std::vector<T>& object_list

‎include/kit/kit.h

+21-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,25 @@ namespace kit
133133
void unlock() {}
134134
};
135135

136+
template<class Mutex=std::mutex>
137+
struct optional_mutex
138+
{
139+
void lock() {
140+
if(mutex)
141+
mutex->lock();
142+
}
143+
bool try_lock() {
144+
if(mutex)
145+
return mutex->try_lock();
146+
return true;
147+
}
148+
void unlock() {
149+
if(mutex)
150+
mutex->unlock();
151+
}
152+
std::shared_ptr<Mutex> mutex = std::make_shared<Mutex>();
153+
};
154+
136155
template<class Mutex=std::mutex>
137156
class mutexed
138157
{
@@ -751,8 +770,9 @@ namespace kit
751770
template<class T>
752771
T safe_ptr(T ptr)
753772
{
754-
if(ptr == nullptr)
773+
if(ptr == nullptr){
755774
throw null_ptr_exception();
775+
}
756776
return ptr;
757777
}
758778

‎include/kit/meta/meta.h

+90-22
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,24 @@
2525
struct MetaType {
2626

2727
MetaType() = default;
28-
MetaType(MetaType&&) = default;
29-
MetaType(const MetaType&) = default;
30-
MetaType& operator=(MetaType&&) = default;
31-
MetaType& operator=(const MetaType&) = default;
28+
MetaType(MetaType&& rhs):
29+
id(rhs.id),
30+
flags(rhs.flags)
31+
{}
32+
MetaType(const MetaType& rhs):
33+
id(rhs.id),
34+
flags(rhs.flags)
35+
{}
36+
MetaType& operator=(MetaType&& rhs) {
37+
id=rhs.id;
38+
flags=rhs.flags;
39+
return *this;
40+
}
41+
MetaType& operator=(const MetaType& rhs) {
42+
id=rhs.id;
43+
flags=rhs.flags;
44+
return *this;
45+
}
3246

3347
template<class T>
3448
MetaType(T val) {
@@ -113,16 +127,41 @@ struct MetaType {
113127

114128
struct MetaElement
115129
{
130+
MetaElement() = default;
116131
MetaElement(MetaType type, const std::string& key, boost::any&& value):
117132
type(type),
118133
key(key),
119134
value(value)
120135
{}
121-
122-
MetaElement(const MetaElement& e) = default;
123-
MetaElement(MetaElement&& e) = default;
124-
MetaElement& operator=(const MetaElement& e) = default;
125-
136+
MetaElement(const MetaElement& rhs):
137+
type(rhs.type),
138+
key(rhs.key),
139+
value(rhs.value),
140+
flags(rhs.flags)
141+
{}
142+
MetaElement(MetaElement&& rhs):
143+
type(rhs.type),
144+
key(rhs.key),
145+
value(std::move(rhs.value)),
146+
flags(rhs.flags)
147+
{}
148+
MetaElement& operator=(const MetaElement& rhs)
149+
{
150+
type = rhs.type;
151+
key = rhs.key;
152+
value = rhs.value;
153+
flags = rhs.flags;
154+
return *this;
155+
}
156+
MetaElement& operator=(MetaElement&& rhs)
157+
{
158+
type = rhs.type;
159+
key = rhs.key;
160+
value = std::move(rhs.value);
161+
flags = rhs.flags;
162+
return *this;
163+
}
164+
126165
template<class Mutex>
127166
Json::Value serialize_json(unsigned flags = 0) const;
128167

@@ -134,7 +173,6 @@ struct MetaElement
134173
std::runtime_error("null pointer exception")
135174
{}
136175
};
137-
138176

139177
//template<class Mutex>
140178
//void deserialize_json(const Json::Value&);
@@ -148,23 +186,18 @@ struct MetaElement
148186
//{}
149187
// type data (reflection)
150188

151-
/*
152-
* Deduced type id
153-
*/
154-
MetaType type; // null
155-
156189
void nullify() {
157190
type.id = MetaType::ID::EMPTY;
158191
value = boost::any();
192+
on_change.disconnect_all_slots();
159193
}
160194

161195
explicit operator bool() const {
162196
return !value.empty();
163197
}
164198

165199
void trigger() {
166-
//if(change)
167-
// (*change)();
200+
on_change();
168201
}
169202

170203
// may throw bad_any_cast
@@ -173,6 +206,12 @@ struct MetaElement
173206
return boost::any_cast<T>(value);
174207
}
175208

209+
210+
/*
211+
* Deduced type id
212+
*/
213+
MetaType type; // null
214+
176215
/*
177216
* Key (if any)
178217
* Do not modify the key without modifying Meta's m_Key
@@ -192,7 +231,7 @@ struct MetaElement
192231
unsigned flags = DEFAULT_FLAGS;
193232

194233
// value change listeners
195-
//std::shared_ptr<boost::signals2::signal<void()>> on_change;
234+
boost::signals2::signal<void()> on_change;
196235
};
197236

198237
enum class MetaFormat : unsigned {
@@ -351,7 +390,9 @@ class MetaBase:
351390
MetaBase(MetaFormat fmt, const std::string& data);
352391

353392
MetaBase(MetaBase&&)= delete;
354-
MetaBase(const MetaBase&)= delete;
393+
394+
MetaBase(const MetaBase&) = delete;
395+
explicit MetaBase(const std::shared_ptr<MetaBase<Mutex>>& rhs);
355396
MetaBase& operator=(const MetaBase&) = delete;
356397
MetaBase& operator=(MetaBase&&) = delete;
357398

@@ -864,8 +905,19 @@ class MetaBase:
864905
if((itr = m_Keys.find(key)) != m_Keys.end()) {
865906
// TODO: if dynamic typing is off, check type compatibility
866907
auto& e = m_Elements[itr->second];
867-
e.type = MetaType(val); // overwrite type just in case
868-
e.value = val;
908+
if(e.type.id != MetaType(val).id)
909+
{
910+
// type changed
911+
e.type = MetaType(val);
912+
e.value = val;
913+
e.on_change.disconnect_all_slots();
914+
}
915+
else
916+
{
917+
e.value = val;
918+
e.trigger();
919+
}
920+
//
869921
// TODO: trigger change listener?... or maybe only for sync()?
870922
return itr->second;
871923
}
@@ -916,15 +968,29 @@ class MetaBase:
916968
T&& val
917969
){
918970
// Should really check type compatibility here...
971+
auto l = this->lock();
919972

920973
try{
921-
m_Elements.at(offset).value = val;
974+
auto& e = m_Elements.at(offset);
975+
if(e.value != val) {
976+
e.value = val;
977+
e.trigger();
978+
}
922979
}catch(...){
923980
return false;
924981
}
925982
return true;
926983
}
927984

985+
boost::signals2::connection on_change(
986+
const std::string& key,
987+
const boost::signals2::signal<void()>::slot_type& slot
988+
){
989+
auto l = this->lock();
990+
auto& e = m_Elements.at(index(key));
991+
return e.on_change.connect(slot);
992+
}
993+
928994
/*
929995
* Creates property with key and optional value (default is blank)
930996
* Returns the id used to refer to the property
@@ -976,9 +1042,11 @@ class MetaBase:
9761042
//}
9771043

9781044
void callbacks(bool enabled) {
1045+
auto l = this->lock();
9791046
m_bCallbacks = enabled;
9801047
}
9811048
bool callbacks() {
1049+
auto l = this->lock();
9821050
return m_bCallbacks;
9831051
}
9841052

‎include/kit/meta/meta.inl

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ MetaBase<Mutex> :: MetaBase(MetaFormat fmt, const std::string& data)
1717
deserialize(fmt, data);
1818
}
1919

20+
template<class Mutex>
21+
MetaBase<Mutex> :: MetaBase(const std::shared_ptr<MetaBase<Mutex>>& rhs)
22+
{
23+
clear();
24+
merge(rhs);
25+
}
26+
2027
template<class Mutex>
2128
void MetaBase<Mutex> :: from_args(std::vector<std::string> args)
2229
{

‎sg.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
"env": {
44
"CXX": "clang++"
55
},
6-
"makefile_params": "CXX='clang++'"
6+
"makefile_params": [
7+
"CXX='clang++'"
8+
]
79
},
810

911
"dependencies": {

0 commit comments

Comments
 (0)
Please sign in to comment.