mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-15 00:11:55 +07:00
node: swap_children and swap_children_at functions
This commit is contained in:
@@ -108,6 +108,17 @@ namespace e2d
|
||||
bool remove_child(
|
||||
const node_iptr& child) noexcept;
|
||||
|
||||
node_iptr remove_child_at(
|
||||
std::size_t index) noexcept;
|
||||
|
||||
bool swap_children(
|
||||
const node_iptr& child_l,
|
||||
const node_iptr& child_r) noexcept;
|
||||
|
||||
bool swap_children_at(
|
||||
std::size_t child_l,
|
||||
std::size_t child_r) noexcept;
|
||||
|
||||
bool send_backward() noexcept;
|
||||
bool bring_to_back() noexcept;
|
||||
|
||||
@@ -131,8 +142,6 @@ namespace e2d
|
||||
|
||||
std::pair<std::size_t, bool> child_index(
|
||||
const const_node_iptr& child) const noexcept;
|
||||
|
||||
node_iptr remove_child_at(std::size_t index) noexcept;
|
||||
protected:
|
||||
node() = default;
|
||||
node(gobject owner);
|
||||
|
||||
@@ -273,6 +273,8 @@ namespace e2d
|
||||
|
||||
static iterator iterator_to(T& v) noexcept;
|
||||
static const_iterator iterator_to(const T& v) noexcept;
|
||||
|
||||
static void iterator_swap(iterator l, iterator r) noexcept;
|
||||
private:
|
||||
using node_t = intrusive_list_hook<Tag>;
|
||||
using node_ptr = typename node_t::node_ptr;
|
||||
@@ -496,4 +498,10 @@ namespace e2d
|
||||
E2D_ASSERT(node.is_linked());
|
||||
return const_iterator(&node);
|
||||
}
|
||||
|
||||
template < typename T, typename Tag >
|
||||
void intrusive_list<T,Tag>::iterator_swap(iterator l, iterator r) noexcept {
|
||||
E2D_ASSERT(l.node()->is_linked() && r.node()->is_linked());
|
||||
intrusive_list_hook<Tag>::swap_nodes(l.node(), r.node());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +124,23 @@ function node.add_sibling_after(self, sibling) end
|
||||
---@return boolean
|
||||
function node.remove_child(self, child) end
|
||||
|
||||
---@param self node
|
||||
---@param index integer
|
||||
---@return node
|
||||
function node.remove_child_at(self, index) end
|
||||
|
||||
---@param self node
|
||||
---@param child_l node
|
||||
---@param child_r node
|
||||
---@return boolean
|
||||
function node.swap_children(self, child_l, child_r) end
|
||||
|
||||
---@param self node
|
||||
---@param child_l integer
|
||||
---@param child_r integer
|
||||
---@return boolean
|
||||
function node.swap_children_at(self, child_l, child_r) end
|
||||
|
||||
---@param self node
|
||||
---@return boolean
|
||||
function node.send_backward(self) end
|
||||
@@ -150,10 +167,5 @@ function node.child_at(self, index) end
|
||||
---@return integer, boolean
|
||||
function node.child_index(self, child) end
|
||||
|
||||
---@param self node
|
||||
---@param index integer
|
||||
---@return node
|
||||
function node.remove_child_at(self, index) end
|
||||
|
||||
---@type node
|
||||
_G.node = _G.node or node
|
||||
|
||||
@@ -115,6 +115,22 @@ namespace e2d::bindings::high
|
||||
return n.remove_child(c);
|
||||
},
|
||||
|
||||
"remove_child_at", [](node& n, i32 index) -> node_iptr {
|
||||
return index >= 0
|
||||
? n.remove_child_at(math::numeric_cast<std::size_t>(index))
|
||||
: node_iptr();
|
||||
},
|
||||
|
||||
"swap_children", [](node& n, const node_iptr& cl, const node_iptr& cr) -> bool {
|
||||
return n.swap_children(cl, cr);
|
||||
},
|
||||
|
||||
"swap_children_at", [](node& n, i32 cl, i32 cr) -> bool {
|
||||
return cl >= 0 && cr >= 0
|
||||
? n.swap_children_at(math::numeric_cast<std::size_t>(cl), math::numeric_cast<std::size_t>(cr))
|
||||
: false;
|
||||
},
|
||||
|
||||
"send_backward", [](node& n) -> bool {
|
||||
return n.send_backward();
|
||||
},
|
||||
@@ -151,12 +167,6 @@ namespace e2d::bindings::high
|
||||
|
||||
"child_index", [](node& n, const node_iptr& c) -> std::pair<std::size_t, bool> {
|
||||
return n.child_index(c);
|
||||
},
|
||||
|
||||
"remove_child_at", [](node& n, i32 index) -> node_iptr {
|
||||
return index >= 0
|
||||
? n.remove_child_at(math::numeric_cast<std::size_t>(index))
|
||||
: node_iptr();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ namespace e2d
|
||||
bool node::add_child_to_back(
|
||||
const node_iptr& child) noexcept
|
||||
{
|
||||
if ( !child ) {
|
||||
if ( !child || child == this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace e2d
|
||||
bool node::add_child_to_front(
|
||||
const node_iptr& child) noexcept
|
||||
{
|
||||
if ( !child ) {
|
||||
if ( !child || child == this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -319,6 +319,41 @@ namespace e2d
|
||||
return true;
|
||||
}
|
||||
|
||||
node_iptr node::remove_child_at(std::size_t index) noexcept {
|
||||
node_iptr child = child_at(index);
|
||||
return remove_child(child)
|
||||
? child
|
||||
: node_iptr();
|
||||
}
|
||||
|
||||
bool node::swap_children(
|
||||
const node_iptr& child_l,
|
||||
const node_iptr& child_r) noexcept
|
||||
{
|
||||
if ( !child_l || !child_r ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( child_l->parent_ != this || child_r->parent_ != this ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node_children::iterator_swap(
|
||||
node_children::iterator_to(*child_l),
|
||||
node_children::iterator_to(*child_r));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool node::swap_children_at(
|
||||
std::size_t child_l,
|
||||
std::size_t child_r) noexcept
|
||||
{
|
||||
return swap_children(
|
||||
child_at(child_l),
|
||||
child_at(child_r));
|
||||
}
|
||||
|
||||
bool node::send_backward() noexcept {
|
||||
node_iptr prev = prev_sibling();
|
||||
return prev
|
||||
@@ -444,13 +479,6 @@ namespace e2d
|
||||
|
||||
return {math::numeric_cast<std::size_t>(distance), true};
|
||||
}
|
||||
|
||||
node_iptr node::remove_child_at(std::size_t index) noexcept {
|
||||
node_iptr child = child_at(index);
|
||||
return remove_child(child)
|
||||
? child
|
||||
: node_iptr();
|
||||
}
|
||||
}
|
||||
|
||||
namespace e2d
|
||||
|
||||
@@ -317,6 +317,33 @@ TEST_CASE("node") {
|
||||
REQUIRE_FALSE(n->bring_to_back());
|
||||
}
|
||||
}
|
||||
SECTION("swap_children") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
auto p2 = node::create();
|
||||
auto n4 = node::create(p2);
|
||||
|
||||
auto n5 = node::create();
|
||||
|
||||
REQUIRE_FALSE(p->swap_children(n1, node_iptr()));
|
||||
REQUIRE_FALSE(p->swap_children(node_iptr(), n1));
|
||||
REQUIRE_FALSE(p->swap_children(n1, p2));
|
||||
REQUIRE_FALSE(p->swap_children(n1, n4));
|
||||
REQUIRE_FALSE(p->swap_children(n1, n5));
|
||||
|
||||
REQUIRE(p->swap_children(n1, n1)); // n1 n2 n3
|
||||
REQUIRE(p->swap_children(n1, n2)); // n2 n1 n3
|
||||
REQUIRE(p->swap_children(n2, n3)); // n3 n1 n2
|
||||
REQUIRE(p->swap_children(n2, n1)); // n3 n2 n1
|
||||
|
||||
REQUIRE(p->child_at(0u) == n3);
|
||||
REQUIRE(p->child_at(1u) == n2);
|
||||
REQUIRE(p->child_at(2u) == n1);
|
||||
}
|
||||
SECTION("send_forward/bring_to_front") {
|
||||
{
|
||||
auto p = node::create();
|
||||
@@ -513,6 +540,25 @@ TEST_CASE("node") {
|
||||
REQUIRE_FALSE(n3->has_parent());
|
||||
REQUIRE(p->child_count() == 0u);
|
||||
}
|
||||
SECTION("swap_children_at") {
|
||||
auto p = node::create();
|
||||
|
||||
auto n1 = node::create(p);
|
||||
auto n2 = node::create(p);
|
||||
auto n3 = node::create(p);
|
||||
|
||||
REQUIRE_FALSE(p->swap_children_at(0u, 3u));
|
||||
REQUIRE_FALSE(p->swap_children_at(3u, 0u));
|
||||
|
||||
REQUIRE(p->swap_children_at(0, 0)); // n1 n2 n3
|
||||
REQUIRE(p->swap_children_at(0, 1)); // n2 n1 n3
|
||||
REQUIRE(p->swap_children_at(0, 2)); // n3 n1 n2
|
||||
REQUIRE(p->swap_children_at(2, 1)); // n3 n2 n1
|
||||
|
||||
REQUIRE(p->child_at(0u) == n3);
|
||||
REQUIRE(p->child_at(1u) == n2);
|
||||
REQUIRE(p->child_at(2u) == n1);
|
||||
}
|
||||
SECTION("add_child_to_back/add_child_to_front") {
|
||||
auto p = node::create();
|
||||
auto n1 = node::create();
|
||||
@@ -523,6 +569,7 @@ TEST_CASE("node") {
|
||||
REQUIRE(p->add_child_to_back(n1));
|
||||
REQUIRE(p->add_child_to_back(n2));
|
||||
REQUIRE(p->add_child_to_back(n3)); // n3 n2 n1
|
||||
REQUIRE_FALSE(p->add_child_to_back(p));
|
||||
REQUIRE_FALSE(p->add_child_to_back(nullptr));
|
||||
|
||||
REQUIRE(n1->prev_sibling() == n2);
|
||||
@@ -558,6 +605,7 @@ TEST_CASE("node") {
|
||||
REQUIRE(p->add_child_to_front(n1));
|
||||
REQUIRE(p->add_child_to_front(n2));
|
||||
REQUIRE(p->add_child_to_front(n3)); // n1 n2 n3
|
||||
REQUIRE_FALSE(p->add_child_to_front(p));
|
||||
REQUIRE_FALSE(p->add_child_to_front(nullptr));
|
||||
|
||||
REQUIRE(n1->next_sibling() == n2);
|
||||
|
||||
Reference in New Issue
Block a user