Compare commits
8 Commits
f2099f7628
...
9210dec86d
Author | SHA1 | Date | |
---|---|---|---|
9210dec86d | |||
efe922f835 | |||
d7c4364255 | |||
cafeb62c9d | |||
25a5b7d2b8 | |||
23cf7c4e9b | |||
0d0c57c508 | |||
692e1511aa |
@ -30,8 +30,9 @@ target_sources(nf7_core
|
||||
uv/file.hh
|
||||
uv/parallelism.hh
|
||||
clock.hh
|
||||
dealer.hh
|
||||
logger.hh
|
||||
mutex.hh
|
||||
meta_env.hh
|
||||
version.hh
|
||||
)
|
||||
|
||||
@ -50,6 +51,7 @@ target_sources(nf7_core_test
|
||||
uv/file_test.cc
|
||||
uv/parallelism_test.cc
|
||||
clock_test.cc
|
||||
meta_env_test.cc
|
||||
)
|
||||
target_link_libraries(nf7_core_test
|
||||
PRIVATE
|
||||
|
52
core/dealer.hh
Normal file
52
core/dealer.hh
Normal file
@ -0,0 +1,52 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "iface/subsys/dealer.hh"
|
||||
|
||||
|
||||
namespace nf7::core {
|
||||
|
||||
template <typename T>
|
||||
class Maker : public subsys::Maker<T> {
|
||||
public:
|
||||
using subsys::Maker<T>::Maker;
|
||||
using subsys::Maker<T>::Notify;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Taker : public subsys::Taker<T>, public Observer<T>::Target {
|
||||
public:
|
||||
using subsys::Taker<T>::Taker;
|
||||
|
||||
void Take(T&& v) noexcept override {
|
||||
Observer<T>::Target::Notify(std::move(v));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class NullMaker final : public subsys::Maker<T> {
|
||||
public:
|
||||
static inline const auto kInstance = std::make_shared<NullMaker<T>>();
|
||||
|
||||
public:
|
||||
NullMaker() noexcept : subsys::Maker<T>("nf7::core::NullMaker") { }
|
||||
|
||||
private:
|
||||
using subsys::Maker<T>::Notify;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class NullTaker final : public subsys::Taker<T> {
|
||||
public:
|
||||
static inline const auto kInstance = std::make_shared<NullTaker<T>>();
|
||||
|
||||
public:
|
||||
NullTaker() noexcept : subsys::Taker<T>("nf7::core::NullTaker") { }
|
||||
|
||||
void Take(T&&) noexcept override { }
|
||||
};
|
||||
|
||||
} // namespace nf7::core
|
@ -11,13 +11,7 @@ namespace nf7::core {
|
||||
|
||||
class NullLogger : public subsys::Logger {
|
||||
public:
|
||||
static const std::shared_ptr<NullLogger>& instance()
|
||||
try {
|
||||
static const auto kInstance = std::make_shared<NullLogger>();
|
||||
return kInstance;
|
||||
} catch (const std::bad_alloc&) {
|
||||
throw MemoryException {};
|
||||
}
|
||||
static inline const auto kInstance = std::make_shared<NullLogger>();
|
||||
|
||||
public:
|
||||
NullLogger() noexcept : subsys::Logger("nf7::core::NullLogger") { }
|
||||
|
@ -60,7 +60,19 @@ class Lambda::Thread : public luajit::Thread {
|
||||
};
|
||||
|
||||
|
||||
void Lambda::Main(const nf7::Value& v) noexcept {
|
||||
Lambda::Lambda(nf7::Env& env,
|
||||
const std::shared_ptr<Value>& func,
|
||||
const std::shared_ptr<subsys::Maker<IO>>& maker)
|
||||
: nf7::Lambda(), Observer<IO>(*maker),
|
||||
clock_(env.GetOr<subsys::Clock>()),
|
||||
concurrency_(env.Get<subsys::Concurrency>()),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)),
|
||||
maker_(maker),
|
||||
taker_(env.GetOr<subsys::Taker<IO>>(NullTaker<IO>::kInstance)),
|
||||
lua_(env.Get<luajit::Context>()),
|
||||
func_(func) { }
|
||||
|
||||
void Lambda::Notify(const IO& v) noexcept {
|
||||
lua_->Exec([this, self = shared_from_this(), v](auto& lua) {
|
||||
recvq_.push_back(v);
|
||||
++recv_count_;
|
||||
@ -134,8 +146,9 @@ void Lambda::PushLuaContextObject(TaskContext& lua) noexcept {
|
||||
lua_pushcfunction(*lua, [](auto L) {
|
||||
const auto la = self(L);
|
||||
const auto v = (TaskContext {la->lua_, L}).CheckValue(2);
|
||||
la->concurrency_->Exec(
|
||||
[la, v](auto&) { la->emitter()->Emit(nf7::Value {v}); });
|
||||
la->concurrency_->Exec([la, v = v](auto&) mutable {
|
||||
la->taker_->Take(std::move(v));
|
||||
});
|
||||
return 1;
|
||||
});
|
||||
lua_setfield(*lua, -2, "send");
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "iface/subsys/clock.hh"
|
||||
#include "iface/subsys/concurrency.hh"
|
||||
#include "iface/subsys/dealer.hh"
|
||||
#include "iface/subsys/logger.hh"
|
||||
#include "iface/env.hh"
|
||||
#include "iface/lambda.hh"
|
||||
@ -16,38 +17,47 @@
|
||||
#include "core/luajit/context.hh"
|
||||
#include "core/luajit/thread.hh"
|
||||
#include "core/logger.hh"
|
||||
#include "core/dealer.hh"
|
||||
|
||||
namespace nf7::core::luajit {
|
||||
|
||||
class Lambda :
|
||||
public nf7::LambdaBase,
|
||||
public std::enable_shared_from_this<Lambda> {
|
||||
public:
|
||||
explicit Lambda(nf7::Env& env, const std::shared_ptr<luajit::Value>& func)
|
||||
: LambdaBase(),
|
||||
clock_(env.GetOr<subsys::Clock>()),
|
||||
concurrency_(env.Get<subsys::Concurrency>()),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::instance())),
|
||||
lua_(env.Get<luajit::Context>()),
|
||||
func_(func) { }
|
||||
|
||||
uint64_t exitCount() const noexcept { return exit_count_; }
|
||||
uint64_t abortCount() const noexcept { return abort_count_; }
|
||||
|
||||
public nf7::Lambda,
|
||||
public std::enable_shared_from_this<Lambda>,
|
||||
private Observer<nf7::Value> {
|
||||
private:
|
||||
class Thread;
|
||||
|
||||
private:
|
||||
void Main(const nf7::Value& v) noexcept override;
|
||||
using IO = nf7::Value;
|
||||
|
||||
public:
|
||||
Lambda(nf7::Env& env, const std::shared_ptr<Value>& func)
|
||||
: Lambda(
|
||||
env, func,
|
||||
env.GetOr<subsys::Maker<IO>>(NullMaker<IO>::kInstance)) { }
|
||||
|
||||
private:
|
||||
Lambda(nf7::Env&,
|
||||
const std::shared_ptr<Value>&,
|
||||
const std::shared_ptr<subsys::Maker<IO>>&);
|
||||
|
||||
private:
|
||||
void Notify(const IO&) noexcept override;
|
||||
void Resume(TaskContext&) noexcept;
|
||||
void PushLuaContextObject(TaskContext&) noexcept;
|
||||
|
||||
public:
|
||||
uint64_t exitCount() const noexcept { return exit_count_; }
|
||||
uint64_t abortCount() const noexcept { return abort_count_; }
|
||||
|
||||
private:
|
||||
const std::shared_ptr<subsys::Clock> clock_;
|
||||
const std::shared_ptr<subsys::Concurrency> concurrency_;
|
||||
const std::shared_ptr<subsys::Logger> logger_;
|
||||
|
||||
const std::shared_ptr<subsys::Maker<IO>> maker_;
|
||||
const std::shared_ptr<subsys::Taker<IO>> taker_;
|
||||
|
||||
const std::shared_ptr<Context> lua_;
|
||||
const std::shared_ptr<Value> func_;
|
||||
|
||||
@ -57,7 +67,7 @@ class Lambda :
|
||||
std::atomic<uint64_t> exit_count_ = 0;
|
||||
std::atomic<uint64_t> abort_count_ = 0;
|
||||
|
||||
std::deque<nf7::Value> recvq_;
|
||||
std::deque<IO> recvq_;
|
||||
uint64_t recv_count_ = 0;
|
||||
bool awaiting_value_ = false;
|
||||
};
|
||||
|
@ -7,9 +7,11 @@
|
||||
#include <vector>
|
||||
|
||||
#include "iface/subsys/clock.hh"
|
||||
#include "iface/subsys/dealer.hh"
|
||||
|
||||
#include "core/luajit/context.hh"
|
||||
#include "core/clock.hh"
|
||||
#include "core/dealer.hh"
|
||||
|
||||
#include "iface/common/observer_test.hh"
|
||||
#include "iface/subsys/logger_test.hh"
|
||||
@ -22,10 +24,15 @@ using namespace std::literals;
|
||||
namespace {
|
||||
class LuaJIT_Lambda : public nf7::core::luajit::test::ContextFixture {
|
||||
public:
|
||||
using ContextFixture::ContextFixture;
|
||||
LuaJIT_Lambda()
|
||||
: maker_(std::make_shared<nf7::core::Maker<nf7::Value>>("mock maker")),
|
||||
taker_(std::make_shared<nf7::core::Taker<nf7::Value>>("mock taker")) {
|
||||
Install<nf7::subsys::Maker<nf7::Value>>(maker_);
|
||||
Install<nf7::subsys::Taker<nf7::Value>>(taker_);
|
||||
}
|
||||
|
||||
std::shared_ptr<nf7::core::luajit::Value> Compile(
|
||||
const char* script) noexcept {
|
||||
const char* script) {
|
||||
auto lua = env().Get<nf7::core::luajit::Context>();
|
||||
|
||||
std::shared_ptr<nf7::core::luajit::Value> func;
|
||||
@ -48,24 +55,27 @@ class LuaJIT_Lambda : public nf7::core::luajit::test::ContextFixture {
|
||||
|
||||
auto func = Compile(script);
|
||||
|
||||
auto sut = std::make_shared<nf7::core::luajit::Lambda>(*env, func);
|
||||
for (const auto& v : in) {
|
||||
sut->taker()->Take(v);
|
||||
}
|
||||
|
||||
::testing::StrictMock<
|
||||
nf7::test::ObserverMock<nf7::Value>> obs {*sut->maker()};
|
||||
|
||||
nf7::test::ObserverMock<nf7::Value>> obs {*taker_};
|
||||
::testing::Sequence seq;
|
||||
for (const auto& v : out) {
|
||||
EXPECT_CALL(obs, NotifyWithMove(nf7::Value {v}))
|
||||
.InSequence(seq);
|
||||
}
|
||||
|
||||
auto sut = std::make_shared<nf7::core::luajit::Lambda>(*env, func);
|
||||
for (const auto& v : in) {
|
||||
maker_->Notify({v});
|
||||
}
|
||||
|
||||
ConsumeTasks();
|
||||
EXPECT_EQ(sut->exitCount(), expectExit);
|
||||
EXPECT_EQ(sut->abortCount(), expectAbort);
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::shared_ptr<nf7::core::Maker<nf7::Value>> maker_;
|
||||
const std::shared_ptr<nf7::core::Taker<nf7::Value>> taker_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
@ -101,12 +111,12 @@ TEST_P(LuaJIT_Lambda, CtxMultiRecvWithDelay) {
|
||||
"nf7:assert(\"integer\" == ctx:recv():type())");
|
||||
|
||||
auto sut = std::make_shared<nf7::core::luajit::Lambda>(env(), func);
|
||||
sut->taker()->Take(nf7::Value::Null {});
|
||||
maker_->Notify(nf7::Value::Null {});
|
||||
ConsumeTasks();
|
||||
EXPECT_EQ(sut->exitCount(), 0);
|
||||
EXPECT_EQ(sut->abortCount(), 0);
|
||||
|
||||
sut->taker()->Take(nf7::Value::Integer {});
|
||||
maker_->Notify(nf7::Value::Integer {});
|
||||
ConsumeTasks();
|
||||
EXPECT_EQ(sut->exitCount(), 1);
|
||||
EXPECT_EQ(sut->abortCount(), 0);
|
||||
|
91
core/meta_env.hh
Normal file
91
core/meta_env.hh
Normal file
@ -0,0 +1,91 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "iface/subsys/meta_env.hh"
|
||||
|
||||
namespace nf7::core {
|
||||
|
||||
class NullMetaEnv : public subsys::MetaEnv {
|
||||
public:
|
||||
static inline const auto kInstance = std::make_shared<NullMetaEnv>();
|
||||
|
||||
public:
|
||||
NullMetaEnv() noexcept : subsys::MetaEnv("nf7::core::NullMetaEnv") { }
|
||||
|
||||
public:
|
||||
Env* FindOr(std::string_view) const noexcept override { return nullptr; }
|
||||
std::optional<Pair> FindOr(uint64_t) const noexcept override { return std::nullopt; }
|
||||
std::vector<Pair> FetchAll() const override { return {}; }
|
||||
std::shared_ptr<subsys::MetaEnv> parent() const noexcept override { return nullptr; }
|
||||
};
|
||||
|
||||
class MetaEnv : public subsys::MetaEnv {
|
||||
public:
|
||||
using SharedPair = std::pair<std::string, std::shared_ptr<Env>>;
|
||||
|
||||
private:
|
||||
static std::vector<SharedPair>&& Sort(std::vector<SharedPair>&& v) noexcept {
|
||||
std::sort(v.begin(), v.end(),
|
||||
[](const auto& a, const auto& b) { return a.first < b.first; });
|
||||
return v;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit MetaEnv(std::vector<SharedPair>&& children,
|
||||
const std::weak_ptr<subsys::MetaEnv>& parent = {}) noexcept
|
||||
: subsys::MetaEnv("nf7::core::MetaEnv"),
|
||||
children_(Sort(std::move(children))),
|
||||
parent_(parent) {
|
||||
assert(std::all_of(children_.begin(), children_.end(),
|
||||
[](auto& x) { return x.second; }));
|
||||
}
|
||||
|
||||
public:
|
||||
Env* FindOr(std::string_view name) const noexcept override {
|
||||
const auto itr = std::lower_bound(
|
||||
children_.cbegin(), children_.cend(), name,
|
||||
[](const auto& a, const auto& b) { return a.first < b; });
|
||||
if (children_.cend() == itr || itr->first != name) {
|
||||
return nullptr;
|
||||
}
|
||||
return itr->second.get();
|
||||
}
|
||||
std::optional<Pair> FindOr(uint64_t index) const noexcept override {
|
||||
if (index >= children_.size()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const auto& child = children_[index];
|
||||
return Pair {child.first, *child.second};
|
||||
}
|
||||
|
||||
std::vector<Pair> FetchAll() const override
|
||||
try {
|
||||
std::vector<Pair> ret;
|
||||
ret.reserve(children_.size());
|
||||
for (const auto& child : children_) {
|
||||
ret.emplace_back(child.first, *child.second);
|
||||
}
|
||||
return ret;
|
||||
} catch (const std::bad_alloc&) {
|
||||
throw MemoryException {};
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<subsys::MetaEnv> parent() const noexcept override {
|
||||
return parent_.lock();
|
||||
}
|
||||
|
||||
private:
|
||||
const std::vector<SharedPair> children_;
|
||||
const std::weak_ptr<subsys::MetaEnv> parent_;
|
||||
};
|
||||
|
||||
} // namespace nf7::core
|
74
core/meta_env_test.cc
Normal file
74
core/meta_env_test.cc
Normal file
@ -0,0 +1,74 @@
|
||||
// No copyright
|
||||
#include "core/meta_env.hh"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "iface/env.hh"
|
||||
|
||||
|
||||
static inline std::shared_ptr<nf7::Env> MakeEmptyEnv() {
|
||||
return std::make_shared<nf7::SimpleEnv>(nf7::SimpleEnv::FactoryMap {});
|
||||
}
|
||||
static inline bool MatchPair(const std::optional<nf7::subsys::MetaEnv::Pair>& a,
|
||||
const nf7::subsys::MetaEnv::Pair& b) {
|
||||
return a && a->first == b.first && &a->second == &b.second;
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FindOrByName) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_EQ(sut.FindOr(""), nullptr);
|
||||
EXPECT_EQ(sut.FindOr("a"), a.get());
|
||||
EXPECT_EQ(sut.FindOr("b"), b.get());
|
||||
EXPECT_EQ(sut.FindOr("c"), c.get());
|
||||
EXPECT_EQ(sut.FindOr("d"), nullptr);
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FindOrByIndex) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(0), {"a", *a}));
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(1), {"b", *b}));
|
||||
EXPECT_TRUE(MatchPair(sut.FindOr(2), {"c", *c}));
|
||||
EXPECT_EQ(sut.FindOr(3), std::nullopt);
|
||||
}
|
||||
|
||||
TEST(MetaEnv, FetchAll) {
|
||||
const auto a = MakeEmptyEnv();
|
||||
const auto b = MakeEmptyEnv();
|
||||
const auto c = MakeEmptyEnv();
|
||||
|
||||
nf7::core::MetaEnv sut {
|
||||
{
|
||||
{"b", b},
|
||||
{"c", c},
|
||||
{"a", a},
|
||||
},
|
||||
};
|
||||
|
||||
const auto all = sut.FetchAll();
|
||||
EXPECT_EQ(all.size(), 3);
|
||||
EXPECT_TRUE(MatchPair(all[0], {"a", *a}));
|
||||
EXPECT_TRUE(MatchPair(all[1], {"b", *b}));
|
||||
EXPECT_TRUE(MatchPair(all[2], {"c", *c}));
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include "iface/common/mutex.hh"
|
||||
#include "iface/data/wrap.hh"
|
||||
|
||||
namespace nf7::core {
|
||||
|
||||
class Mutex : public data::Wrap<nf7::Mutex> {
|
||||
public:
|
||||
Mutex() : Wrap("nf7::core::Mutex", mtx_) { }
|
||||
|
||||
private:
|
||||
nf7::Mutex mtx_;
|
||||
};
|
||||
|
||||
} // namespace nf7::core
|
@ -55,7 +55,7 @@ void Concurrency::Push(SyncTask&& task) noexcept {
|
||||
|
||||
Concurrency::Impl::Impl(Env& env)
|
||||
: clock_(env.Get<subsys::Clock>()),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::instance())) {
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)) {
|
||||
}
|
||||
|
||||
std::chrono::milliseconds Concurrency::Impl::Consume() noexcept {
|
||||
|
@ -29,7 +29,7 @@ class Context : public subsys::Interface {
|
||||
protected:
|
||||
Context(const char* name, Env& env)
|
||||
: subsys::Interface(name),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::instance())),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)),
|
||||
loop_(MakeLoop()) { }
|
||||
|
||||
public:
|
||||
|
@ -52,11 +52,11 @@ std::shared_ptr<File> File::Make(
|
||||
File::File(Env& env,
|
||||
std::string_view path,
|
||||
uvw::file_req::file_open_flags open_flags)
|
||||
try : data::FiniteBuffer("nf7::core::uv::File::Finite"),
|
||||
data::ResizableBuffer("nf7::core::uv::File::Resizable"),
|
||||
data::ReadableBuffer("nf7::core::uv::File::Readable"),
|
||||
data::WritableBuffer("nf7::core::uv::File::Writable"),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::instance())),
|
||||
try : subsys::FiniteBuffer("nf7::core::uv::File::Finite"),
|
||||
subsys::ResizableBuffer("nf7::core::uv::File::Resizable"),
|
||||
subsys::ReadableBuffer("nf7::core::uv::File::Readable"),
|
||||
subsys::WritableBuffer("nf7::core::uv::File::Writable"),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)),
|
||||
delete_(env.Get<Context>()->Make<uvw::async_handle>()),
|
||||
path_(path),
|
||||
open_flags_(open_flags),
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "iface/common/future.hh"
|
||||
#include "iface/common/mutex.hh"
|
||||
#include "iface/common/void.hh"
|
||||
#include "iface/data/buffer.hh"
|
||||
#include "iface/subsys/buffer.hh"
|
||||
#include "iface/subsys/logger.hh"
|
||||
#include "iface/env.hh"
|
||||
|
||||
@ -23,10 +23,10 @@ namespace nf7::core::uv {
|
||||
|
||||
class File :
|
||||
public std::enable_shared_from_this<File>,
|
||||
public data::FiniteBuffer,
|
||||
public data::ResizableBuffer,
|
||||
public data::ReadableBuffer,
|
||||
public data::WritableBuffer {
|
||||
public subsys::FiniteBuffer,
|
||||
public subsys::ResizableBuffer,
|
||||
public subsys::ReadableBuffer,
|
||||
public subsys::WritableBuffer {
|
||||
private:
|
||||
class Finite;
|
||||
class Resizable;
|
||||
@ -34,7 +34,7 @@ class File :
|
||||
class Writable;
|
||||
|
||||
public:
|
||||
using ReadResult = data::ReadableBuffer::Result;
|
||||
using ReadResult = subsys::ReadableBuffer::Result;
|
||||
|
||||
public:
|
||||
static std::shared_ptr<File> Make(
|
||||
@ -69,10 +69,10 @@ class File :
|
||||
Future<Void> Resize(uint64_t n) noexcept override { return Truncate(n); }
|
||||
|
||||
public:
|
||||
std::shared_ptr<data::FiniteBuffer> MakeFinite();
|
||||
std::shared_ptr<data::ResizableBuffer> MakeResizable();
|
||||
std::shared_ptr<data::ReadableBuffer> MakeReadable();
|
||||
std::shared_ptr<data::WritableBuffer> MakeWritable();
|
||||
std::shared_ptr<subsys::FiniteBuffer> MakeFinite();
|
||||
std::shared_ptr<subsys::ResizableBuffer> MakeResizable();
|
||||
std::shared_ptr<subsys::ReadableBuffer> MakeReadable();
|
||||
std::shared_ptr<subsys::WritableBuffer> MakeWritable();
|
||||
|
||||
private:
|
||||
const std::shared_ptr<subsys::Logger> logger_;
|
||||
|
@ -27,7 +27,7 @@ Parallelism::Parallelism(Env& env)
|
||||
|
||||
Parallelism::Impl::Impl(Env& env)
|
||||
: clock_(env.Get<subsys::Clock>()),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::instance())),
|
||||
logger_(env.GetOr<subsys::Logger>(NullLogger::kInstance)),
|
||||
ctx_(env.Get<Context>()) { }
|
||||
|
||||
void Parallelism::Impl::Consume() noexcept {
|
||||
|
@ -11,7 +11,6 @@ target_sources(nf7_iface
|
||||
version.cc
|
||||
PUBLIC
|
||||
common/container.hh
|
||||
common/dealer.hh
|
||||
common/exception.hh
|
||||
common/future.hh
|
||||
common/leak_detector.hh
|
||||
@ -23,16 +22,14 @@ target_sources(nf7_iface
|
||||
common/task_context.hh
|
||||
common/value.hh
|
||||
common/void.hh
|
||||
data/buffer.hh
|
||||
data/interface.hh
|
||||
data/wrap.hh
|
||||
subsys/concurrency.hh
|
||||
subsys/database.hh
|
||||
subsys/dealer.hh
|
||||
subsys/interface.hh
|
||||
subsys/logger.hh
|
||||
subsys/meta_env.hh
|
||||
subsys/parallelism.hh
|
||||
env.hh
|
||||
file.hh
|
||||
lambda.hh
|
||||
version.hh
|
||||
)
|
||||
@ -41,7 +38,6 @@ add_executable(nf7_iface_test)
|
||||
target_sources(nf7_iface_test
|
||||
PRIVATE
|
||||
common/container_test.cc
|
||||
common/dealer_test.cc
|
||||
common/exception_test.cc
|
||||
common/future_test.cc
|
||||
common/leak_detector_test.cc
|
||||
@ -53,8 +49,6 @@ target_sources(nf7_iface_test
|
||||
common/value_test.cc
|
||||
subsys/logger_test.hh
|
||||
env_test.hh
|
||||
lambda_test.cc
|
||||
lambda_test.hh
|
||||
)
|
||||
target_link_libraries(nf7_iface_test
|
||||
PRIVATE
|
||||
|
@ -1,55 +0,0 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "iface/common/observer.hh"
|
||||
|
||||
|
||||
namespace nf7 {
|
||||
|
||||
class DealerMeta { };
|
||||
|
||||
template <typename T>
|
||||
class Dealer {
|
||||
public:
|
||||
explicit Dealer(const DealerMeta& meta = {}) noexcept : meta_(meta) { }
|
||||
virtual ~Dealer() = default;
|
||||
|
||||
Dealer(const Dealer&) = default;
|
||||
Dealer(Dealer&&) = default;
|
||||
Dealer& operator=(const Dealer&) = default;
|
||||
Dealer& operator=(Dealer&&) = default;
|
||||
|
||||
const DealerMeta& meta() const noexcept { return meta_; }
|
||||
|
||||
private:
|
||||
const DealerMeta& meta_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Maker : public Dealer<T>, public Observer<T>::Target {
|
||||
public:
|
||||
explicit Maker(const DealerMeta& meta = {}) noexcept : Dealer<T>(meta) { }
|
||||
|
||||
protected:
|
||||
void Emit(T&& v) noexcept { Observer<T>::Target::Notify(std::move(v)); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Emitter : public Maker<T> {
|
||||
public:
|
||||
explicit Emitter(const DealerMeta& meta = {}) noexcept : Maker<T>(meta) { }
|
||||
using Maker<T>::Emit;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Taker : public Dealer<T>, public Observer<T>::Target {
|
||||
public:
|
||||
explicit Taker(const DealerMeta& meta = {}) noexcept : Dealer<T>(meta) { }
|
||||
|
||||
void Take(const T& v) noexcept { Observer<T>::Target::Notify(v); }
|
||||
};
|
||||
|
||||
} // namespace nf7
|
@ -1,16 +0,0 @@
|
||||
// No copyright
|
||||
#include "iface/common/dealer.hh"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "iface/common/observer_test.hh"
|
||||
|
||||
|
||||
TEST(Emitter, Emit) {
|
||||
nf7::Emitter<int32_t> sut {};
|
||||
nf7::test::ObserverMock<int32_t> obs {sut};
|
||||
|
||||
EXPECT_CALL(obs, NotifyWithMove(int32_t {777})).Times(1);
|
||||
|
||||
sut.Emit(int32_t {777});
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
namespace nf7::data {
|
||||
|
||||
class Interface {
|
||||
public:
|
||||
Interface() = delete;
|
||||
explicit Interface(const char* name) : name_(name) { }
|
||||
virtual ~Interface() = default;
|
||||
|
||||
Interface(const Interface&) = delete;
|
||||
Interface(Interface&&) = delete;
|
||||
Interface& operator=(const Interface&) = delete;
|
||||
Interface& operator=(Interface&&) = delete;
|
||||
|
||||
const char* name() const noexcept { return name_; }
|
||||
|
||||
private:
|
||||
const char* name_;
|
||||
};
|
||||
|
||||
} // namespace nf7::data
|
@ -1,11 +0,0 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include "iface/common/container.hh"
|
||||
#include "iface/data/interface.hh"
|
||||
|
||||
namespace nf7 {
|
||||
|
||||
using File = Container<data::Interface>;
|
||||
|
||||
} // namespace nf7
|
@ -5,7 +5,6 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "iface/common/dealer.hh"
|
||||
#include "iface/common/leak_detector.hh"
|
||||
#include "iface/common/exception.hh"
|
||||
#include "iface/common/observer.hh"
|
||||
@ -15,50 +14,13 @@ namespace nf7 {
|
||||
|
||||
class Lambda : private LeakDetector<Lambda> {
|
||||
public:
|
||||
Lambda() = delete;
|
||||
Lambda(const std::shared_ptr<Taker<Value>>& taker,
|
||||
const std::shared_ptr<Maker<Value>>& maker) noexcept
|
||||
: taker_(std::move(taker)), maker_(maker) { }
|
||||
Lambda() = default;
|
||||
virtual ~Lambda() = default;
|
||||
|
||||
Lambda(const Lambda&) = delete;
|
||||
Lambda(Lambda&&) = delete;
|
||||
Lambda& operator=(const Lambda&) = delete;
|
||||
Lambda& operator=(Lambda&&) = delete;
|
||||
|
||||
const std::shared_ptr<Taker<Value>>& taker() const noexcept { return taker_; }
|
||||
const std::shared_ptr<Maker<Value>>& maker() const noexcept { return maker_; }
|
||||
|
||||
private:
|
||||
const std::shared_ptr<Taker<Value>> taker_;
|
||||
const std::shared_ptr<Maker<Value>> maker_;
|
||||
};
|
||||
|
||||
class LambdaBase : public Lambda, private Observer<Value> {
|
||||
public:
|
||||
LambdaBase(DealerMeta&& takerMeta = {}, DealerMeta&& makerMeta = {})
|
||||
try : LambdaBase(std::make_shared<Taker<Value>>(std::move(takerMeta)),
|
||||
std::make_shared<Emitter<Value>>(std::move(makerMeta))) {
|
||||
} catch (const std::bad_alloc&) {
|
||||
throw MemoryException {};
|
||||
}
|
||||
|
||||
private:
|
||||
LambdaBase(const std::shared_ptr<Taker<Value>>& taker,
|
||||
const std::shared_ptr<Emitter<Value>>& maker)
|
||||
: Lambda(taker, maker), Observer<Value>(*taker), emitter_(maker) { }
|
||||
|
||||
protected:
|
||||
virtual void Main(const Value&) noexcept = 0;
|
||||
|
||||
const std::shared_ptr<Emitter<Value>>& emitter() const noexcept {
|
||||
return emitter_;
|
||||
}
|
||||
|
||||
private:
|
||||
void Notify(const Value& v) noexcept override { Main(v); }
|
||||
|
||||
const std::shared_ptr<Emitter<Value>> emitter_;
|
||||
};
|
||||
|
||||
} // namespace nf7
|
||||
|
@ -1,15 +0,0 @@
|
||||
// No copyright
|
||||
#include "iface/lambda.hh"
|
||||
#include "iface/lambda_test.hh"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
TEST(LambdaBase, TakeAndRun) {
|
||||
nf7::test::LambdaBaseMock sut;
|
||||
|
||||
EXPECT_CALL(sut, Main);
|
||||
|
||||
sut.taker()->Take(nf7::Value::Null {});
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include "iface/lambda.hh"
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
#include "iface/common/dealer.hh"
|
||||
#include "iface/common/value.hh"
|
||||
|
||||
|
||||
namespace nf7::test {
|
||||
|
||||
class LambdaBaseMock : public LambdaBase {
|
||||
public:
|
||||
using LambdaBase::LambdaBase;
|
||||
|
||||
MOCK_METHOD(void, Main, (const Value&), (noexcept));
|
||||
|
||||
using LambdaBase::emitter;
|
||||
};
|
||||
|
||||
} // namespace nf7::test
|
@ -6,9 +6,9 @@
|
||||
|
||||
#include "iface/common/future.hh"
|
||||
#include "iface/common/void.hh"
|
||||
#include "iface/data/interface.hh"
|
||||
#include "iface/subsys/interface.hh"
|
||||
|
||||
namespace nf7::data {
|
||||
namespace nf7::subsys {
|
||||
|
||||
class FiniteBuffer : public Interface {
|
||||
public:
|
||||
@ -54,4 +54,5 @@ class WritableBuffer : public Interface {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace nf7::data
|
||||
} // namespace nf7::subsys
|
||||
|
27
iface/subsys/dealer.hh
Normal file
27
iface/subsys/dealer.hh
Normal file
@ -0,0 +1,27 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include "iface/common/observer.hh"
|
||||
#include "iface/subsys/interface.hh"
|
||||
|
||||
|
||||
namespace nf7::subsys {
|
||||
|
||||
template <typename T>
|
||||
class Maker : public Interface, public Observer<T>::Target {
|
||||
public:
|
||||
using Interface::Interface;
|
||||
|
||||
protected:
|
||||
using Observer<T>::Target::Notify;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Taker : public Interface {
|
||||
public:
|
||||
using Interface::Interface;
|
||||
|
||||
virtual void Take(T&&) noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace nf7::subsys
|
42
iface/subsys/meta_env.hh
Normal file
42
iface/subsys/meta_env.hh
Normal file
@ -0,0 +1,42 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "iface/common/exception.hh"
|
||||
#include "iface/env.hh"
|
||||
|
||||
|
||||
namespace nf7::subsys {
|
||||
|
||||
class MetaEnv : public Interface {
|
||||
public:
|
||||
using Pair = std::pair<std::string, Env&>;
|
||||
|
||||
public:
|
||||
using Interface::Interface;
|
||||
|
||||
public:
|
||||
virtual Env* FindOr(std::string_view) const noexcept = 0;
|
||||
virtual std::optional<Pair> FindOr(uint64_t) const noexcept = 0;
|
||||
virtual std::vector<Pair> FetchAll() const = 0;
|
||||
|
||||
public:
|
||||
Env& Find(std::string_view key) const {
|
||||
auto ret = FindOr(key);
|
||||
return ret? *ret: throw Exception {"missing file"};
|
||||
}
|
||||
Pair Find(uint64_t idx) const {
|
||||
auto ret = FindOr(idx);
|
||||
return ret? *ret: throw Exception {"missing file"};
|
||||
}
|
||||
|
||||
public:
|
||||
virtual std::shared_ptr<MetaEnv> parent() const noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace nf7::subsys
|
@ -1,14 +1,14 @@
|
||||
// No copyright
|
||||
#pragma once
|
||||
|
||||
#include "iface/data/interface.hh"
|
||||
#include "iface/subsys/interface.hh"
|
||||
|
||||
namespace nf7::data {
|
||||
namespace nf7::subsys {
|
||||
|
||||
template <typename T>
|
||||
class Wrap : public Interface {
|
||||
class Wrapper : public Interface {
|
||||
protected:
|
||||
Wrap(const char* name, T& data) noexcept
|
||||
Wrapper(const char* name, T& data) noexcept
|
||||
: Interface(name), data_(data) { }
|
||||
|
||||
public:
|
||||
@ -18,4 +18,4 @@ class Wrap : public Interface {
|
||||
T& data_;
|
||||
};
|
||||
|
||||
} // namespace nf7::data
|
||||
} // namespace nf7::subsys
|
Loading…
x
Reference in New Issue
Block a user