Skip to content

Commit

Permalink
Add floating tree roots
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadden committed Dec 11, 2020
1 parent ad21df9 commit d97cdf9
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/alia/flow/object_trees.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,48 @@ struct scoped_tree_children
tree_traversal<Object> old_traversal_state_;
};

// scoped_tree_root is used to activate an independent root node in the middle
// of a tree traversal.
template<class Object>
struct scoped_tree_root
{
scoped_tree_root() : traversal_(nullptr)
{
}
scoped_tree_root(
tree_traversal<Object>& traversal, tree_node<Object>& new_root)
{
begin(traversal, new_root);
}
~scoped_tree_root()
{
end();
}

void
begin(tree_traversal<Object>& traversal, tree_node<Object>& new_root)
{
traversal_ = &traversal;
old_traversal_state_ = traversal;
activate_parent_node(traversal, new_root);
}

void
end()
{
if (traversal_)
{
cap_sibling_list(*traversal_);
*traversal_ = old_traversal_state_;
traversal_ = nullptr;
}
}

private:
tree_traversal<Object>* traversal_;
tree_traversal<Object> old_traversal_state_;
};

template<class Object, class Content>
void
traverse_object_tree(
Expand Down
91 changes: 91 additions & 0 deletions unit_tests/flow/object_trees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,94 @@ TEST_CASE("piecewise containers", "[flow][object_trees]")
root.object.to_string()
== "root(bit0(bit1();bit2(bit4(););bit5(););)");
}

TEST_CASE("floating object tree root", "[flow][object_trees]")
{
clear_log();

int n = 0;

tree_node<test_object> root;
root.object.name = "root";

tree_node<test_object> floating_root;
floating_root.object.name = "floater";

auto controller = [&](test_context ctx) {
ALIA_IF(n & 1)
{
do_container(ctx, "bit0", [&](test_context ctx) {
ALIA_IF(n & 2)
{
do_object(ctx, "bit1");
}
ALIA_END

{
scoped_tree_root<test_object> floating_subtree(
get<tree_traversal_tag>(ctx), floating_root);

ALIA_IF(n & 4)
{
do_container(ctx, "bit2", [&](test_context ctx) {
ALIA_IF(n & 8)
{
do_object(ctx, "bit3");
}
ALIA_END

ALIA_IF(n & 16)
{
do_object(ctx, "bit4");
}
ALIA_END
});
}
ALIA_END
}

ALIA_IF(n & 32)
{
do_object(ctx, "bit5");
}
ALIA_END
});
}
ALIA_END

ALIA_IF(n & 64)
{
do_object(ctx, "bit6");
}
ALIA_END
};

alia::system sys;
initialize_system(sys, [&](context vanilla_ctx) {
tree_traversal<test_object> traversal;
auto ctx = detail::add_context_object<tree_traversal_tag>(
vanilla_ctx, traversal);
if (is_refresh_event(ctx))
{
traverse_object_tree(traversal, root, [&]() { controller(ctx); });
}
else
{
controller(ctx);
}
});

n = 127;
refresh_system(sys);
check_log(
"relocating bit0 into root; "
"relocating bit1 into bit0; "
"relocating bit2 into floater; "
"relocating bit3 into bit2; "
"relocating bit4 into bit2 after bit3; "
"relocating bit5 into bit0 after bit1; "
"relocating bit6 into root after bit0; ");
REQUIRE(root.object.to_string() == "root(bit0(bit1();bit5(););bit6();)");
REQUIRE(
floating_root.object.to_string() == "floater(bit2(bit3();bit4(););)");
}

0 comments on commit d97cdf9

Please sign in to comment.