replace cereal -> yas

This commit is contained in:
falsycat 2022-05-22 11:55:57 +09:00
parent 0c9efa5479
commit cb1a0e627c
5 changed files with 143 additions and 88 deletions

View File

@ -41,10 +41,11 @@ target_sources(nf7
nf7.hh
common/queue.hh
common/type_info.hh
common/yas.hh
)
target_link_libraries(nf7
PRIVATE
cereal::cereal
glew
glfw
imgui
@ -53,4 +54,5 @@ target_link_libraries(nf7
linalg.h
luajit
source_location
yas
)

52
common/yas.hh Normal file
View File

@ -0,0 +1,52 @@
#pragma once
#include <string>
#include <yas/serialize.hpp>
#include <yas/types/std/string.hpp>
namespace yas::detail {
template <size_t F>
struct serializer<
type_prop::not_a_fundamental,
ser_case::use_internal_serializer,
F,
std::unique_ptr<nf7::File>> {
public:
template <typename Archive>
static Archive& save(Archive& ar, const std::unique_ptr<nf7::File>& f) {
ar(std::string(f->type().name()));
f->Serialize(ar);
return ar;
}
template <typename Archive>
static Archive& load(Archive& ar, std::unique_ptr<nf7::File>& f) {
std::string name;
ar(name);
f = nf7::File::registry(name).Deserialize(nf7::Env::Peek(), ar);
return ar;
}
};
template <size_t F>
struct serializer<
type_prop::not_a_fundamental,
ser_case::use_internal_serializer,
F,
nf7::File::Path> {
public:
template <typename Archive>
static Archive& save(Archive& ar, const nf7::File::Path& p) {
p.Serialize(ar);
return ar;
}
template <typename Archive>
static Archive& load(Archive& ar, nf7::File::Path& p) {
p = {ar};
return ar;
}
};
} // namespace detail

90
nf7.cc
View File

@ -3,9 +3,10 @@
#include <cassert>
#include <map>
#include <cereal/types/string.hpp>
#include <cereal/types/vector.hpp>
#include <imgui.h>
#include <yas/serialize.hpp>
#include <yas/types/std/string.hpp>
#include <yas/types/std/vector.hpp>
using namespace std::literals;
@ -13,8 +14,11 @@ using namespace std::literals;
namespace nf7 {
static std::vector<Env*> env_stack_;
// static variable in function ensures that entity is initialized before using
static inline auto& registry_() noexcept {
static std::map<std::string, File::TypeInfo*> registry_;
static std::map<std::string, const File::TypeInfo*> registry_;
return registry_;
}
@ -40,21 +44,6 @@ File::File(const TypeInfo& t, Env& env) noexcept : type_(&t), env_(&env) {
File::~File() noexcept {
assert(id_ == 0);
}
std::unique_ptr<File> File::Deserialize(Env& env, Deserializer& d) {
std::string type;
d(type);
const auto& reg = registry_();
auto itr = reg.find(type);
if (itr == reg.end()) {
throw DeserializeException("unknown actor type: "s+type);
}
return itr->second->Deserialize(env, d);
}
void File::Serialize(Serializer& s) const noexcept {
s(std::string(type().name()));
SerializeParam(s);
}
void File::MoveUnder(Id parent) noexcept {
if (parent) {
assert(parent_ == 0);
@ -113,46 +102,27 @@ File::TypeInfo::~TypeInfo() noexcept {
reg.erase(std::string(name_));
}
bool File::Path::ValidateTerm(std::string_view term) noexcept {
constexpr size_t kMaxTermSize = 256;
if (term.size() > kMaxTermSize) {
return false;
}
static const char kAllowedChars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789_";
if (term.find_first_not_of(kAllowedChars) != std::string_view::npos) {
return false;
}
return true;
File::Path::Path(Deserializer& ar) {
ar(terms_);
Validate();
}
File::Path File::Path::Deserialize(Deserializer& d) {
Path p;
d(p.terms_);
return p;
}
void File::Path::Serialize(Serializer& s) const noexcept {
s(terms_);
void File::Path::Serialize(Serializer& ar) const noexcept {
ar(terms_);
}
File::Path File::Path::Parse(std::string_view p) {
std::vector<std::string> ret;
Path ret;
auto st = p.begin(), itr = st;
for (; itr < p.end(); ++itr) {
if (*itr == '/') {
if (st < itr) ret.push_back(std::string {st, itr});
if (st < itr) ret.terms_.push_back(std::string {st, itr});
st = itr + 1;
}
}
if (st < itr) ret.push_back(std::string {st, itr});
if (st < itr) ret.terms_.push_back(std::string {st, itr});
for (const auto& term : ret) {
if (!ValidateTerm(term)) {
throw DeserializeException("invalid term: "+term);
}
}
return {std::move(ret)};
ret.Validate();
return ret;
}
std::string File::Path::Stringify() const noexcept {
std::string ret;
@ -161,6 +131,22 @@ std::string File::Path::Stringify() const noexcept {
}
return ret;
}
void File::Path::ValidateTerm(std::string_view term) {
constexpr size_t kMaxTermSize = 256;
if (term.size() > kMaxTermSize) {
throw Exception("too long term (must be less than 256)");
}
static const char kAllowedChars[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789_";
if (term.find_first_not_of(kAllowedChars) != std::string_view::npos) {
throw Exception("invalid char found in term");
}
}
void File::Path::Validate() const {
for (const auto& term : terms_) ValidateTerm(term);
}
Context::Context(Env& env, File::Id initiator, Context::Id parent) noexcept :
env_(&env), initiator_(initiator), id_(env_->AddContext(*this)), parent_(parent) {
@ -169,6 +155,16 @@ Context::~Context() noexcept {
env_->RemoveContext(id_);
}
void Env::Push(Env& env) noexcept {
env_stack_.push_back(&env);
}
Env& Env::Peek() noexcept {
return *env_stack_.back();
}
void Env::Pop() noexcept {
env_stack_.pop_back();
}
Env::Watcher::Watcher(Env& env) noexcept : env_(&env) {
}
Env::Watcher::~Watcher() noexcept {

53
nf7.hh
View File

@ -4,6 +4,8 @@
#include <exception>
#include <filesystem>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <span>
#include <string>
@ -12,8 +14,8 @@
#include <utility>
#include <vector>
#include <cereal/archives/binary.hpp>
#include <source_location.hh>
#include <yas/serialize.hpp>
namespace nf7 {
@ -23,8 +25,8 @@ class File;
class Context;
class Env;
using Deserializer = cereal::BinaryInputArchive;
using Serializer = cereal::BinaryOutputArchive;
using Serializer = yas::binary_oarchive<yas::file_ostream, yas::binary>;
using Deserializer = yas::binary_iarchive<yas::file_istream, yas::binary>;
class Exception {
public:
@ -62,6 +64,8 @@ class ExpiredException : public Exception {
class File {
public:
struct Event;
class TypeInfo;
class Interface;
class Path;
@ -70,19 +74,8 @@ class File {
using Id = uint64_t;
struct Event final {
public:
enum Type {
// emitted by outer
kCreate,
kRemove,
// emitted by file
kUpdate,
};
Id id;
Type type;
};
static const std::map<std::string, const TypeInfo*>& registry() noexcept;
static const TypeInfo& registry(std::string_view);
File() = delete;
File(const TypeInfo&, Env&) noexcept;
@ -92,9 +85,7 @@ class File {
File& operator=(const File&) = delete;
File& operator=(File&&) = delete;
static std::unique_ptr<File> Deserialize(Env&, Deserializer&);
void Serialize(Serializer&) const noexcept;
virtual void SerializeParam(Serializer&) const noexcept = 0;
virtual void Serialize(Serializer&) const noexcept = 0;
virtual std::unique_ptr<File> Clone(Env&) const noexcept = 0;
virtual void MoveUnder(Id) noexcept;
@ -125,6 +116,19 @@ class File {
Id id_ = 0, parent_ = 0;
};
struct File::Event final {
public:
enum Type {
// emitted by outer
kCreate,
kRemove,
// emitted by file
kUpdate,
};
Id id;
Type type;
};
class File::TypeInfo {
public:
TypeInfo() = delete;
@ -160,8 +164,6 @@ class File::Interface {
};
class File::Path final {
public:
static bool ValidateTerm(std::string_view) noexcept;
Path() = default;
Path(std::initializer_list<std::string> terms) noexcept :
terms_(terms.begin(), terms.end()) {
@ -176,11 +178,14 @@ class File::Path final {
bool operator==(const Path& p) const noexcept { return terms_ == p.terms_; }
bool operator!=(const Path& p) const noexcept { return terms_ != p.terms_; }
static Path Deserialize(Deserializer&);
Path(Deserializer&);
void Serialize(Serializer&) const noexcept;
static Path Parse(std::string_view);
std::string Stringify() const noexcept;
static void ValidateTerm(std::string_view);
void Validate() const;
std::span<const std::string> terms() const noexcept { return terms_; }
const std::string& terms(size_t i) const noexcept { return terms_[i]; }
@ -227,6 +232,10 @@ class Env {
public:
class Watcher;
static void Push(Env&) noexcept;
static Env& Peek() noexcept;
static void Pop() noexcept;
Env() = delete;
Env(const std::filesystem::path& npath) noexcept : npath_(npath) {
}

View File

@ -8,24 +8,6 @@ else()
endif()
# ---- cereal ----
# repository: https://github.com/USCiLab/cereal
# license : BSD-3
FetchContent_Declare(
cereal
URL "https://github.com/USCiLab/cereal/archive/refs/tags/v1.3.2.zip"
)
function (include_cereal)
set(BUILD_DOC OFF)
set(BUILD_SANDBOX OFF)
set(SKIP_PERFORMANCE_COMPARISON OFF)
FetchContent_MakeAvailable(cereal)
endfunction()
include_cereal()
# ---- GLEW ----
# repository: https://github.com/Perlmint/glew-cmake
# license : Modified BSD License, the Mesa 3-D License (MIT) and the Khronos License (MIT).
@ -199,3 +181,17 @@ include_luajit()
add_library(source_location INTERFACE)
target_include_directories(source_location SYSTEM INTERFACE .)
target_sources(source_location INTERFACE source_location.hh)
# ---- yas ----
# repository: https://github.com/niXman/yas
# license : Boost
FetchContent_Declare(
yas
URL "https://github.com/niXman/yas/archive/refs/tags/7.1.0.zip"
)
FetchContent_Populate(yas)
add_library(yas INTERFACE)
target_include_directories(yas SYSTEM INTERFACE "${yas_SOURCE_DIR}/include")