diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/identity.cpp | 11 | ||||
| -rw-r--r-- | src/state.cpp | 127 | ||||
| -rw-r--r-- | src/state.h | 32 | 
4 files changed, 171 insertions, 0 deletions
| diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 64c14b5..b97293c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ add_library(erebos  	network  	pubkey  	service +	state  	storage  	time  	uuid diff --git a/src/identity.cpp b/src/identity.cpp index 2396b9f..7364a8b 100644 --- a/src/identity.cpp +++ b/src/identity.cpp @@ -11,6 +11,8 @@ using std::nullopt;  using std::runtime_error;  using std::set; +const UUID Identity::sharedTypeId { "0c6c1fe0-f2d7-4891-926b-c332449f7871" }; +  Identity::Identity(const Priv * p): p(p) {}  Identity::Identity(shared_ptr<const Priv> && p): p(std::move(p)) {} @@ -32,6 +34,15 @@ optional<Identity> Identity::load(const vector<Ref> & refs)  	return nullopt;  } +vector<Ref> Identity::store(const Storage & st) const +{ +	vector<Ref> res; +	res.reserve(p->data.size()); +	for (const auto & x : p->data) +		res.push_back(x.store(st)); +	return res; +} +  optional<string> Identity::name() const  {  	return p->name.get(); diff --git a/src/state.cpp b/src/state.cpp new file mode 100644 index 0000000..8790dfc --- /dev/null +++ b/src/state.cpp @@ -0,0 +1,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))); +} diff --git a/src/state.h b/src/state.h new file mode 100644 index 0000000..d2c89fc --- /dev/null +++ b/src/state.h @@ -0,0 +1,32 @@ +#pragma once + +#include <erebos/state.h> + +#include "pubkey.h" + +using std::optional; +using std::vector; + +namespace erebos { + +struct LocalState::Priv +{ +	optional<Identity> identity; +	vector<Stored<struct SharedState>> shared; +}; + +struct SharedState +{ +	explicit SharedState(vector<Stored<SharedState>> prev, +			UUID type, vector<Ref> value): +		prev(prev), type(type), value(value) {} +	explicit SharedState(const Ref &); +	static SharedState load(const Ref & ref) { return SharedState(ref); } +	Ref store(const Storage &) const; + +	vector<Stored<SharedState>> prev; +	UUID type; +	vector<Ref> value; +}; + +} |