merge working. added some noexcept cases
This commit is contained in:
parent
23982922d4
commit
9f78b64731
|
@ -36,7 +36,7 @@ void ConveyorEventStorage::setParent(ConveyorStorage *p) {
|
||||||
if (/*!parent && */ p && !isArmed() && queued() > 0) {
|
if (/*!parent && */ p && !isArmed() && queued() > 0) {
|
||||||
assert(!parent);
|
assert(!parent);
|
||||||
if (p->space() > 0) {
|
if (p->space() > 0) {
|
||||||
armNext();
|
armLater();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ void ConvertConveyorNodeBase::getResult(ErrorOrValue &err_or_val) {
|
||||||
getImpl(err_or_val);
|
getImpl(err_or_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttachConveyorNodeBase::getResult(ErrorOrValue &err_or_val) {
|
void AttachConveyorNodeBase::getResult(ErrorOrValue &err_or_val) noexcept {
|
||||||
if (child) {
|
if (child) {
|
||||||
child->getResult(err_or_val);
|
child->getResult(err_or_val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -574,23 +574,13 @@ public:
|
||||||
// Event
|
// Event
|
||||||
void fire() override;
|
void fire() override;
|
||||||
// ConveyorNode
|
// ConveyorNode
|
||||||
void getResult(ErrorOrValue &eov) override;
|
void getResult(ErrorOrValue &eov) noexcept override;
|
||||||
|
|
||||||
// ConveyorStorage
|
// ConveyorStorage
|
||||||
size_t space() const override { return max_store - storage.size(); }
|
size_t space() const override;
|
||||||
size_t queued() const override { return storage.size(); }
|
size_t queued() const override;
|
||||||
|
|
||||||
void childHasFired() override {
|
|
||||||
if (child && storage.size() < max_store) {
|
|
||||||
ErrorOr<T> eov;
|
|
||||||
child->getResult(eov);
|
|
||||||
storage.push(std::move(eov));
|
|
||||||
if (!isArmed()) {
|
|
||||||
armLater();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void childHasFired() override;
|
||||||
void parentHasFired() override;
|
void parentHasFired() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -603,7 +593,7 @@ public:
|
||||||
|
|
||||||
virtual ~AttachConveyorNodeBase() = default;
|
virtual ~AttachConveyorNodeBase() = default;
|
||||||
|
|
||||||
void getResult(ErrorOrValue &err_or_val) override;
|
void getResult(ErrorOrValue &err_or_val) noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
|
@ -856,8 +846,6 @@ public:
|
||||||
public:
|
public:
|
||||||
void attach(Conveyor<T> conv);
|
void attach(Conveyor<T> conv);
|
||||||
|
|
||||||
void notifyNextAppendage();
|
|
||||||
|
|
||||||
void governingNodeDestroyed();
|
void governingNodeDestroyed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
// Template inlining
|
// Template inlining
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
namespace gin {
|
namespace gin {
|
||||||
|
|
||||||
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) {
|
template <typename Func> ConveyorResult<Func, void> execLater(Func &&func) {
|
||||||
|
@ -86,7 +89,10 @@ std::pair<Conveyor<T>, MergeConveyor<T>> Conveyor<T>::merge() {
|
||||||
|
|
||||||
MergeConveyor<T> node_ref{data};
|
MergeConveyor<T> node_ref{data};
|
||||||
|
|
||||||
return std::make_pair(Conveyor<T>{std::move(merge_node), storage},
|
ConveyorStorage *merge_storage =
|
||||||
|
static_cast<ConveyorStorage *>(merge_node.get());
|
||||||
|
|
||||||
|
return std::make_pair(Conveyor<T>{std::move(merge_node), merge_storage},
|
||||||
std::move(node_ref));
|
std::move(node_ref));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,12 +195,38 @@ template <typename T> void QueueBufferConveyorNode<T>::fire() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void QueueBufferConveyorNode<T>::getResult(ErrorOrValue &eov) {
|
void QueueBufferConveyorNode<T>::getResult(ErrorOrValue &eov) noexcept {
|
||||||
ErrorOr<T> &err_or_val = eov.as<T>();
|
ErrorOr<T> &err_or_val = eov.as<T>();
|
||||||
err_or_val = std::move(storage.front());
|
err_or_val = std::move(storage.front());
|
||||||
storage.pop();
|
storage.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T> size_t QueueBufferConveyorNode<T>::space() const {
|
||||||
|
return max_store - storage.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> size_t QueueBufferConveyorNode<T>::queued() const {
|
||||||
|
return storage.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> void QueueBufferConveyorNode<T>::childHasFired() {
|
||||||
|
if (child && storage.size() < max_store) {
|
||||||
|
ErrorOr<T> eov;
|
||||||
|
child->getResult(eov);
|
||||||
|
|
||||||
|
if (eov.isError()) {
|
||||||
|
if (eov.error().isCritical()) {
|
||||||
|
child_storage = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.push(std::move(eov));
|
||||||
|
if (!isArmed()) {
|
||||||
|
armLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() {
|
template <typename T> void QueueBufferConveyorNode<T>::parentHasFired() {
|
||||||
GIN_ASSERT(parent) { return; }
|
GIN_ASSERT(parent) { return; }
|
||||||
|
|
||||||
|
@ -238,6 +270,7 @@ template <typename T> void ImmediateConveyorNode<T>::parentHasFired() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void ImmediateConveyorNode<T>::fire() {
|
template <typename T> void ImmediateConveyorNode<T>::fire() {
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent->childHasFired();
|
parent->childHasFired();
|
||||||
if (queued() > 0 && parent->space() > 0) {
|
if (queued() > 0 && parent->space() > 0) {
|
||||||
|
@ -280,10 +313,23 @@ template <typename T> void MergeConveyorNode<T>::getResult(ErrorOrValue &eov) {
|
||||||
next_appendage = std::min(appendages.size(), next_appendage);
|
next_appendage = std::min(appendages.size(), next_appendage);
|
||||||
|
|
||||||
for (size_t i = next_appendage; i < appendages.size(); ++i) {
|
for (size_t i = next_appendage; i < appendages.size(); ++i) {
|
||||||
if (appendages[i]->queued()) {
|
if (appendages[i]->queued() > 0) {
|
||||||
err_or_val = std::move(appendages
|
err_or_val = std::move(appendages[i]->error_or_value.value());
|
||||||
|
appendages[i]->error_or_value = std::nullopt;
|
||||||
|
next_appendage = i + 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (size_t i = 0; i < next_appendage; ++i) {
|
||||||
|
if (appendages[i]->queued() > 0) {
|
||||||
|
err_or_val = std::move(appendages[i]->error_or_value.value());
|
||||||
|
appendages[i]->error_or_value = std::nullopt;
|
||||||
|
next_appendage = i + 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err_or_val = criticalError("No value in Merge Appendages");
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void MergeConveyorNode<T>::fire() {
|
template <typename T> void MergeConveyorNode<T>::fire() {
|
||||||
|
@ -291,21 +337,25 @@ template <typename T> void MergeConveyorNode<T>::fire() {
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
parent->childHasFired();
|
parent->childHasFired();
|
||||||
}
|
|
||||||
|
|
||||||
if (queued() > 0 && parent->space() > 0) {
|
if (queued() > 0 && parent->space() > 0) {
|
||||||
armLater();
|
armLater();
|
||||||
} else {
|
}
|
||||||
/// @unimplemented search for arm which has remaining elements
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> size_t MergeConveyorNode<T>::space() const {
|
template <typename T> size_t MergeConveyorNode<T>::space() const { return 0; }
|
||||||
return error_or_value.has_value() ? 0 : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> size_t MergeConveyorNode<T>::queued() const {
|
template <typename T> size_t MergeConveyorNode<T>::queued() const {
|
||||||
return error_or_value.has_value() ? 1 : 0;
|
GIN_ASSERT(data) { return 0; }
|
||||||
|
|
||||||
|
size_t queue_count = 0;
|
||||||
|
|
||||||
|
for (auto &iter : data->appendages) {
|
||||||
|
queue_count += iter->queued();
|
||||||
|
}
|
||||||
|
|
||||||
|
return queue_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void MergeConveyorNode<T>::childHasFired() {
|
template <typename T> void MergeConveyorNode<T>::childHasFired() {
|
||||||
|
@ -344,14 +394,14 @@ template <typename T> size_t MergeConveyorNode<T>::Appendage::queued() const {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) {
|
void MergeConveyorNode<T>::Appendage::getAppendageResult(ErrorOrValue &eov) {
|
||||||
ErrorOr<FixVoid<T>> &eov = eov.as<FixVoid<T>>();
|
ErrorOr<FixVoid<T>> &err_or_val = eov.as<FixVoid<T>>();
|
||||||
|
|
||||||
GIN_ASSERT(queued() > 0) {
|
GIN_ASSERT(queued() > 0) {
|
||||||
eov = criticalError("No element queued in Merge Appendage Node");
|
err_or_val = criticalError("No element queued in Merge Appendage Node");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
eov = std::move(error_or_value.value());
|
err_or_val = std::move(error_or_value.value());
|
||||||
error_or_value = std::nullopt;
|
error_or_value = std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,26 +446,6 @@ void MergeConveyorNodeData<T>::attach(Conveyor<T> conveyor) {
|
||||||
appendages.push_back(std::move(merge_node_appendage));
|
appendages.push_back(std::move(merge_node_appendage));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void MergeConveyorNodeData<T>::notifyNextAppendage() {
|
|
||||||
next_appendage = std::min(next_appendage, appendages.size());
|
|
||||||
|
|
||||||
for (size_t i = next_appendage; i < appendages.size(); ++i) {
|
|
||||||
if (appendages[i]->childStorageHasElementQueued()) {
|
|
||||||
appendages[i]->parentHasFired();
|
|
||||||
next_appendage = i + 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < next_appendage; ++i) {
|
|
||||||
if (appendages[i]->childStorageHasElementQueued()) {
|
|
||||||
appendages[i]->parentHasFired();
|
|
||||||
next_appendage = i + 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> void MergeConveyorNodeData<T>::governingNodeDestroyed() {
|
template <typename T> void MergeConveyorNodeData<T>::governingNodeDestroyed() {
|
||||||
appendages.clear();
|
appendages.clear();
|
||||||
merger = nullptr;
|
merger = nullptr;
|
||||||
|
|
|
@ -209,11 +209,13 @@ GIN_TEST("Async Merge"){
|
||||||
|
|
||||||
cam.second.attach(Conveyor<int>{11});
|
cam.second.attach(Conveyor<int>{11});
|
||||||
|
|
||||||
|
cam.second.attach(Conveyor<int>{14});
|
||||||
|
|
||||||
size_t elements_passed = 0;
|
size_t elements_passed = 0;
|
||||||
bool wrong_value = false;
|
bool wrong_value = false;
|
||||||
|
|
||||||
auto sink = cam.first.then([&elements_passed, &wrong_value](int foo){
|
auto sink = cam.first.then([&elements_passed, &wrong_value](int foo){
|
||||||
if(foo == 10 || foo == 11){
|
if(foo == 10 || foo == 11 || 14){
|
||||||
++elements_passed;
|
++elements_passed;
|
||||||
}else{
|
}else{
|
||||||
wrong_value = true;
|
wrong_value = true;
|
||||||
|
@ -222,7 +224,7 @@ GIN_TEST("Async Merge"){
|
||||||
|
|
||||||
wait_scope.poll();
|
wait_scope.poll();
|
||||||
|
|
||||||
GIN_EXPECT(!wrong_value, "Expected values 10 or 11");
|
GIN_EXPECT(!wrong_value, std::string{"Expected values 10 or 11"});
|
||||||
GIN_EXPECT(elements_passed == 2, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
|
GIN_EXPECT(elements_passed == 3, std::string{"Expected 2 passed elements, got only "} + std::to_string(elements_passed));
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue