blob: 1ec5b810fcff2d52be2215a8006c986f76e373d6 [file]
#include "rive/dependency_sorter.hpp"
#include "rive/component.hpp"
#include <algorithm>
using namespace rive;
void DependencySorter::sort(Component* root, std::vector<Component*>& order)
{
order.clear();
visit(root, order);
// visit() appends in finish order; the caller wants its reverse. See the
// note in visit() on why this is not an insert at begin().
std::reverse(order.begin(), order.end());
}
void DependencySorter::sort(std::vector<Component*> roots,
std::vector<Component*>& order)
{
order.clear();
for (auto root : roots)
{
visit(root, order);
}
std::reverse(order.begin(), order.end());
}
bool DependencySorter::visit(Component* component,
std::vector<Component*>& order)
{
if (m_Perm.find(component) != m_Perm.end())
{
return true;
}
if (m_Temp.find(component) != m_Temp.end())
{
fprintf(stderr, "Dependency cycle!\n");
return false;
}
m_Temp.emplace(component);
// By reference: dependents() returns `const std::vector<U*>&`, and a plain
// `auto` strips the reference, deep-copying the vector for every component
// visited.
const auto& dependents = component->dependents();
for (auto dependent : dependents)
{
if (!visit(dependent, order))
{
return false;
}
}
m_Perm.emplace(component);
// Append and let sort() reverse once, rather than inserting at the front
// per component: insert(begin()) shifts the whole vector every time, making
// this O(n^2) in the component count. The Dart port already does it this
// way -- see the same note in dependency_sorter.dart.
order.push_back(component);
return true;
}