Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions include/reactive/Deferrer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <memory>
#include <queue>
#include <vector>

namespace Reactive
Expand All @@ -13,10 +14,21 @@ namespace Reactive
Deferrer();
~Deferrer();

static void add(std::shared_ptr<Deferrable> pending);
static void add(const std::shared_ptr<Deferrable>& pending);

private:
std::vector<std::weak_ptr<Deferrable>> m_pending;
using tDepth = int;
using tPendingEntry = std::pair<tDepth, std::weak_ptr<Deferrable>>;

struct Comperator
{
bool operator()(const tPendingEntry& lhs, const tPendingEntry& rhs) const
{
return lhs.first > rhs.first;
}
};

std::priority_queue<tPendingEntry, std::vector<tPendingEntry>, Comperator> m_pending;

friend struct DeferrerTester;
};
Expand Down
25 changes: 19 additions & 6 deletions src/ComputationsImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,24 @@ namespace Reactive

Computation *ComputationsImpl::getLowest(Computation *lowestSoFar) const
{
for(auto it = m_pending.begin(); it != m_pending.end(); it++)
if(!lowestSoFar)
lowestSoFar = it->get();
else if((*it)->getDepth() < lowestSoFar->getDepth())
lowestSoFar = it->get();
return lowestSoFar;
if(m_pending.empty())
{
return lowestSoFar;
}

if(!lowestSoFar)
{
return m_pending.front().get();
}

Computation *lowest = m_pending.front().get();
for(const auto &comp : m_pending)
{
if(comp->getDepth() < lowest->getDepth())
{
lowest = comp.get();
}
}
return lowest;
}
}
30 changes: 7 additions & 23 deletions src/Deferrer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#include <algorithm>
#include <chrono>
#include <iostream>

namespace Reactive
{
Expand All @@ -23,39 +22,24 @@ namespace Reactive
if(tl_deferrer == this)
{
tl_deferrer = nullptr;

auto cp = std::move(m_pending);

while(true)
while(!m_pending.empty())
{
std::pair<Deferrable *, Computation *> lowestDepth = { nullptr, nullptr };

for(auto &w : cp)
{
if(auto s = w.lock())
{
auto newLowestDepth = s->getLowest(lowestDepth.second);

if(newLowestDepth != lowestDepth.second)
lowestDepth = { s.get(), newLowestDepth };
}
}
auto [depth, weak_ptr] = m_pending.top();
m_pending.pop();

if(lowestDepth.first && lowestDepth.second)
if(const auto s = weak_ptr.lock())
{
lowestDepth.first->doDeferred(lowestDepth.second);
s->doDeferred(s->getLowest(nullptr));
}
else
break;
}
}
}

void Deferrer::add(std::shared_ptr<Deferrable> pending)
void Deferrer::add(const std::shared_ptr<Deferrable> &pending)
{
if(!tl_deferrer)
pending->doDeferred(pending->getLowest(nullptr));
else
tl_deferrer->m_pending.push_back(pending);
tl_deferrer->m_pending.push(tPendingEntry { pending->getLowest(nullptr)->getDepth(), pending });
}
}
38 changes: 35 additions & 3 deletions tests/ReactiveTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,48 @@

using namespace Reactive;

namespace std
{
template <> struct hash<std::weak_ptr<Deferrable>>
{
size_t operator()(const std::weak_ptr<Deferrable> &w) const noexcept
{
return std::hash<void *>()(w.lock().get());
}
};

}

namespace Reactive
{
struct DeferrerTester
{
static bool areElementsInPendingUnique(Deferrer &p)
{
for(auto &c : p.m_pending)
if(std::count_if(p.m_pending.begin(), p.m_pending.end(), [&](auto &a) { return a.lock() == c.lock(); }) > 1)
return false;
using tWeak = std::weak_ptr<Deferrable>;

struct Equal
{
bool operator()(const tWeak &a, const tWeak &b) const
{
return a.lock().get() == b.lock().get();
}
};

std::unordered_set<tWeak, std::hash<tWeak>, Equal> seen {};

auto tempQueue = p.m_pending;
while(!tempQueue.empty())
{
auto w = tempQueue.top().second;
tempQueue.pop();

if(seen.contains(w))
{
return false;
}
seen.insert(w);
}
return true;
}
};
Expand Down
Loading