blob: 8790dfc158bbddc25ccf076baa30c8d672e3b693 (
plain)
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
118
119
120
121
122
123
124
125
126
127
|
#include "state.h"
#include "identity.h"
using namespace erebos;
using std::make_shared;
const UUID LocalState::headTypeId { "1d7491a9-7bcb-4eaa-8f13-c8c4c4087e4e" };
LocalState::LocalState():
p(make_shared<Priv>())
{}
LocalState::LocalState(const Ref & ref):
LocalState()
{
auto rec = ref->asRecord();
if (!rec)
return;
if (auto x = rec->item("id").asRef())
p->identity = Identity::load(*x);
for (auto i : rec->items("shared"))
if (const auto & x = i.as<SharedState>())
p->shared.push_back(*x);
}
Ref LocalState::store(const Storage & st) const
{
vector<Record::Item> items;
if (p->identity)
items.emplace_back("id", *p->identity->ref());
for (const auto & x : p->shared)
items.emplace_back("shared", x);
return st.storeObject(Record(std::move(items)));
}
const optional<Identity> & LocalState::identity() const
{
return p->identity;
}
LocalState LocalState::identity(const Identity & id) const
{
LocalState ret;
ret.p->identity = id;
ret.p->shared = p->shared;
return ret;
}
vector<Ref> LocalState::lookupShared(UUID type) const
{
vector<Stored<SharedState>> found;
vector<Stored<SharedState>> process = p->shared;
while (!process.empty()) {
auto cur = std::move(process.back());
process.pop_back();
if (cur->type == type) {
found.push_back(std::move(cur));
continue;
}
for (const auto & x : cur->prev)
process.push_back(x);
}
filterAncestors(found);
vector<Ref> res;
for (const auto & s : found)
for (const auto & v : s->value)
res.push_back(v);
return res;
}
LocalState LocalState::updateShared(UUID type, const vector<Ref> & xs) const
{
const Storage * st;
if (xs.size() > 0)
st = &xs[0].storage();
else if (p->shared.size() > 0)
st = &p->shared[0].ref().storage();
else
return *this;
LocalState ret;
ret.p->identity = p->identity;
ret.p->shared.push_back(SharedState(p->shared, type, xs).store(*st));
return ret;
}
SharedState::SharedState(const Ref & ref)
{
auto rec = ref->asRecord();
if (!rec)
return;
for (auto i : rec->items("PREV"))
if (const auto & x = i.as<SharedState>())
prev.push_back(*x);
if (auto x = rec->item("type").asUUID())
type = *x;
for (auto i : rec->items("value"))
if (const auto & x = i.asRef())
value.push_back(*x);
}
Ref SharedState::store(const Storage & st) const
{
vector<Record::Item> items;
for (const auto & x : prev)
items.emplace_back("PREV", x);
items.emplace_back("type", type);
for (const auto & x : value)
items.emplace_back("value", x);
return st.storeObject(Record(std::move(items)));
}
|