node helper functions refactoring

This commit is contained in:
2020-02-05 07:09:08 +07:00
parent 8858716359
commit 137ca0335b
7 changed files with 451 additions and 493 deletions

View File

@@ -125,16 +125,6 @@ namespace e2d
node_iptr next_sibling() noexcept;
const_node_iptr next_sibling() const noexcept;
template < typename F >
void for_each_child(F&& f);
template < typename F >
void for_each_child(F&& f) const;
template < typename F >
void for_each_child_reversed(F&& f);
template < typename F >
void for_each_child_reversed(F&& f) const;
protected:
node() = default;
node(gobject owner);
@@ -161,76 +151,114 @@ namespace e2d
namespace e2d::nodes
{
template < typename Iter >
std::size_t extract_nodes(const node_iptr& root, Iter iter);
template < typename Iter >
std::size_t extract_nodes(const const_node_iptr& root, Iter iter);
class options final {
public:
options() = default;
template < typename Iter >
std::size_t extract_nodes_reversed(const node_iptr& root, Iter iter);
template < typename Iter >
std::size_t extract_nodes_reversed(const const_node_iptr& root, Iter iter);
options& reversed(bool value) noexcept;
options& recursive(bool value) noexcept;
options& include_root(bool value) noexcept;
template < typename Iter >
std::size_t extract_parents(const node_iptr& root, Iter iter);
template < typename Iter >
std::size_t extract_parents(const const_node_iptr& root, Iter iter);
template < typename Iter >
std::size_t extract_parents_reversed(const node_iptr& root, Iter iter);
template < typename Iter >
std::size_t extract_parents_reversed(const const_node_iptr& root, Iter iter);
[[nodiscard]] bool reversed() const noexcept;
[[nodiscard]] bool recursive() const noexcept;
[[nodiscard]] bool include_root() const noexcept;
private:
enum flag_masks : u8 {
fm_reversed = 1u << 0,
fm_recursive = 1u << 1,
fm_include_root = 1u << 2,
};
private:
std::underlying_type_t<flag_masks> flags_{};
};
}
namespace e2d::nodes
{
vector<node_iptr> extract_nodes(const node_iptr& root);
vector<const_node_iptr> extract_nodes(const const_node_iptr& root);
template < typename Node, typename F >
bool for_each_child(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
vector<node_iptr> extract_nodes_reversed(const node_iptr& root);
vector<const_node_iptr> extract_nodes_reversed(const const_node_iptr& root);
vector<node_iptr> extract_parents(const node_iptr& root);
vector<const_node_iptr> extract_parents(const const_node_iptr& root);
vector<node_iptr> extract_parents_reversed(const node_iptr& root);
vector<const_node_iptr> extract_parents_reversed(const const_node_iptr& root);
template < typename Node, typename F >
bool for_each_parent(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
}
namespace e2d::nodes
{
template < typename F >
void for_extracted_nodes(const node_iptr& root, F&& f);
template < typename F >
void for_extracted_nodes(const const_node_iptr& root, F&& f);
template < typename Node, typename Iter >
std::size_t extract_parents(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts = options());
template < typename F >
void for_extracted_nodes_reversed(const node_iptr& root, F&& f);
template < typename F >
void for_extracted_nodes_reversed(const const_node_iptr& root, F&& f);
template < typename F >
void for_extracted_parents(const node_iptr& parents, F&& f);
template < typename F >
void for_extracted_parents(const const_node_iptr& parents, F&& f);
template < typename F >
void for_extracted_parents_reversed(const node_iptr& parents, F&& f);
template < typename F >
void for_extracted_parents_reversed(const const_node_iptr& parents, F&& f);
template < typename Node, typename Iter >
std::size_t extract_children(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts = options());
}
namespace e2d::nodes
{
template < typename Component >
gcomponent<Component> get_component_in_parent(const const_node_iptr& root);
template < typename Component, typename Iter >
std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter);
template < typename Node, typename F >
bool for_extracted_parents(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
template < typename Component >
gcomponent<Component> get_component_in_children(const const_node_iptr& root);
template < typename Component, typename Iter >
std::size_t get_components_in_children(const const_node_iptr& root, Iter iter);
template < typename Node, typename F >
bool for_extracted_children(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
}
namespace e2d::nodes
{
template < typename Component, typename Node, typename Iter >
std::size_t extract_components_from_parents(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts = options());
template < typename Component, typename Node, typename Iter >
std::size_t extract_components_from_children(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts = options());
}
namespace e2d::nodes
{
template < typename Component, typename Node, typename F >
bool for_extracted_components_from_parents(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
template < typename Component, typename Node, typename F >
bool for_extracted_components_from_children(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts = options());
}
namespace e2d::nodes
{
template < typename Component, typename Node >
gcomponent<Component> find_component_from_parents(
const intrusive_ptr<Node>& root,
const options& opts = options());
template < typename Component, typename Node >
gcomponent<Component> find_component_from_children(
const intrusive_ptr<Node>& root,
const options& opts = options());
}
#include "node.inl"

View File

@@ -8,388 +8,327 @@
#include "node.hpp"
namespace e2d
namespace e2d::nodes::impl
{
template < typename F >
void node::for_each_child(F&& f) {
for ( auto iter = children_.begin(); iter != children_.end(); ++iter ) {
f(node_iptr(&*iter));
}
}
template < typename F >
void node::for_each_child(F&& f) const {
for ( auto iter = children_.begin(); iter != children_.end(); ++iter ) {
f(const_node_iptr(&*iter));
}
}
template < typename F >
void node::for_each_child_reversed(F&& f) {
for ( auto iter = children_.rbegin(); iter != children_.rend(); ++iter ) {
f(node_iptr(&*iter));
}
}
template < typename F >
void node::for_each_child_reversed(F&& f) const {
for ( auto iter = children_.rbegin(); iter != children_.rend(); ++iter ) {
f(const_node_iptr(&*iter));
template < typename F, typename... Args >
bool invoke_with_force_bool(F&& f, Args&&... args) {
if constexpr ( std::is_invocable_r_v<bool, F, Args...> ) {
return std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
} else {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
return true;
}
}
}
namespace e2d::nodes
{
template < typename Iter >
std::size_t extract_nodes(const node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
++count;
iter++ = root;
root->for_each_child([&iter, &count](const node_iptr& child){
count += extract_nodes(child, iter);
});
}
return count;
}
template < typename Iter >
std::size_t extract_nodes(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
++count;
iter++ = root;
root->for_each_child([&iter, &count](const const_node_iptr& child){
count += extract_nodes(child, iter);
});
}
return count;
}
template < typename Iter >
std::size_t extract_nodes_reversed(const node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
root->for_each_child_reversed([&iter, &count](const node_iptr& child){
count += extract_nodes_reversed(child, iter);
});
++count;
iter++ = root;
}
return count;
}
template < typename Iter >
std::size_t extract_nodes_reversed(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
root->for_each_child_reversed([&iter, &count](const const_node_iptr& child){
count += extract_nodes_reversed(child, iter);
});
++count;
iter++ = root;
}
return count;
}
}
namespace e2d::nodes
{
template < typename Iter >
std::size_t extract_parents(const node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
++count;
iter++ = root;
count += extract_parents(root->parent(), iter);
}
return count;
}
template < typename Iter >
std::size_t extract_parents(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
++count;
iter++ = root;
count += extract_parents(root->parent(), iter);
}
return count;
}
template < typename Iter >
std::size_t extract_parents_reversed(const node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
count += extract_parents(root->parent(), iter);
++count;
iter++ = root;
}
return count;
}
template < typename Iter >
std::size_t extract_parents_reversed(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( root ) {
count += extract_parents(root->parent(), iter);
++count;
iter++ = root;
}
return count;
}
}
namespace e2d::nodes
{
template < typename F >
void for_extracted_nodes(const node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<node_iptr> nodes;
const std::size_t begin_index = nodes.size();
E2D_DEFER([begin_index](){
nodes.erase(
nodes.begin() + begin_index,
nodes.end());
});
extract_nodes(
root,
std::back_inserter(nodes));
const std::size_t end_index = nodes.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(nodes[i]);
}
}
template < typename F >
void for_extracted_nodes(const const_node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<const_node_iptr> nodes;
const std::size_t begin_index = nodes.size();
E2D_DEFER([begin_index](){
nodes.erase(
nodes.begin() + begin_index,
nodes.end());
});
extract_nodes(
root,
std::back_inserter(nodes));
const std::size_t end_index = nodes.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(nodes[i]);
}
}
template < typename F >
void for_extracted_nodes_reversed(const node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<node_iptr> nodes;
const std::size_t begin_index = nodes.size();
E2D_DEFER([begin_index](){
nodes.erase(
nodes.begin() + begin_index,
nodes.end());
});
extract_nodes_reversed(
root,
std::back_inserter(nodes));
const std::size_t end_index = nodes.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(nodes[i]);
}
}
template < typename F >
void for_extracted_nodes_reversed(const const_node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<const_node_iptr> nodes;
const std::size_t begin_index = nodes.size();
E2D_DEFER([begin_index](){
nodes.erase(
nodes.begin() + begin_index,
nodes.end());
});
extract_nodes_reversed(
root,
std::back_inserter(nodes));
const std::size_t end_index = nodes.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(nodes[i]);
}
}
}
namespace e2d::nodes
{
template < typename F >
void for_extracted_parents(const node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<node_iptr> parents;
const std::size_t begin_index = parents.size();
E2D_DEFER([begin_index](){
parents.erase(
parents.begin() + begin_index,
parents.end());
});
extract_parents(
root,
std::back_inserter(parents));
const std::size_t end_index = parents.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(parents[i]);
}
}
template < typename F >
void for_extracted_parents(const const_node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<const_node_iptr> parents;
const std::size_t begin_index = parents.size();
E2D_DEFER([begin_index](){
parents.erase(
parents.begin() + begin_index,
parents.end());
});
extract_parents(
root,
std::back_inserter(parents));
const std::size_t end_index = parents.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(parents[i]);
}
}
template < typename F >
void for_extracted_parents_reversed(const node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<node_iptr> parents;
const std::size_t begin_index = parents.size();
E2D_DEFER([begin_index](){
parents.erase(
parents.begin() + begin_index,
parents.end());
});
extract_parents_reversed(
root,
std::back_inserter(parents));
const std::size_t end_index = parents.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(parents[i]);
}
}
template < typename F >
void for_extracted_parents_reversed(const const_node_iptr& root, F&& f) {
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<const_node_iptr> parents;
const std::size_t begin_index = parents.size();
E2D_DEFER([begin_index](){
parents.erase(
parents.begin() + begin_index,
parents.end());
});
extract_parents_reversed(
root,
std::back_inserter(parents));
const std::size_t end_index = parents.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
f(parents[i]);
}
}
}
namespace e2d::nodes
{
template < typename Component >
gcomponent<Component> get_component_in_parent(const const_node_iptr& root) {
template < typename Node, typename F >
bool for_each_child(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
if ( !root ) {
return {};
return true;
}
if ( auto component = root->owner().component<Component>() ) {
return component;
}
if ( opts.reversed() ) {
for ( auto child = root->last_child(); child; child = child->prev_sibling() ) {
if ( opts.recursive() && !for_each_child(child, f, options(opts).include_root(false)) ) {
return false;
}
return get_component_in_parent<Component>(root->parent());
}
if ( !impl::invoke_with_force_bool(f, child) ) {
return false;
}
}
template < typename Component, typename Iter >
std::size_t get_components_in_parent(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) {
return false;
}
} else {
if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) {
return false;
}
if ( !root ) {
return count;
}
for ( auto child = root->first_child(); child; child = child->next_sibling() ) {
if ( !impl::invoke_with_force_bool(f, child) ) {
return false;
}
if ( auto component = root->owner().component<Component>() ) {
++count;
iter++ = component;
}
return count + get_components_in_parent<Component>(root->parent(), iter);
}
template < typename Component >
gcomponent<Component> get_component_in_children(const const_node_iptr& root) {
if ( !root ) {
return {};
}
if ( auto component = root->owner().component<Component>() ) {
return component;
}
for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) {
if ( auto component = get_component_in_children<Component>(child) ) {
return component;
if ( opts.recursive() && !for_each_child(child, f, options(opts).include_root(false)) ) {
return false;
}
}
}
return {};
return true;
}
template < typename Component, typename Iter >
std::size_t get_components_in_children(const const_node_iptr& root, Iter iter) {
std::size_t count{0u};
template < typename Node, typename F >
bool for_each_parent(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
if ( !root ) {
return count;
return true;
}
if ( auto component = root->owner().component<Component>() ) {
if ( opts.reversed() ) {
if ( root->has_parent() ) {
if ( opts.recursive() && !for_each_parent(root->parent(), f, options(opts).include_root(false)) ) {
return false;
}
if ( !impl::invoke_with_force_bool(f, root->parent()) ) {
return false;
}
}
if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) {
return false;
}
} else {
if ( opts.include_root() && !impl::invoke_with_force_bool(f, root) ) {
return false;
}
if ( root->has_parent() ) {
if ( !impl::invoke_with_force_bool(f, root->parent()) ) {
return false;
}
if ( opts.recursive() && !for_each_parent(root->parent(), f, options(opts).include_root(false)) ) {
return false;
}
}
}
return true;
}
}
namespace e2d::nodes
{
template < typename Node, typename Iter >
std::size_t extract_parents(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts)
{
std::size_t count{0u};
for_each_parent(root, [&count, &iter](const auto& parent){
++count;
iter++ = component;
}
for ( const_node_iptr child = root->first_child(); child; child = child->next_sibling() ) {
count += get_components_in_children<Component>(child, iter);
}
iter++ = parent;
}, opts);
return count;
}
template < typename Node, typename Iter >
std::size_t extract_children(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts)
{
std::size_t count{0u};
for_each_child(root, [&count, &iter](const auto& child){
++count;
iter++ = child;
}, opts);
return count;
}
}
namespace e2d::nodes
{
template < typename Node, typename F >
bool for_extracted_parents(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<intrusive_ptr<Node>> parents;
const std::size_t begin_index = parents.size();
E2D_DEFER([begin_index](){
parents.erase(
parents.begin() + begin_index,
parents.end());
});
extract_parents(
root,
std::back_inserter(parents),
opts);
const std::size_t end_index = parents.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
if ( !impl::invoke_with_force_bool(f, parents[i]) ) {
return false;
}
}
return true;
}
template < typename Node, typename F >
bool for_extracted_children(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<intrusive_ptr<Node>> children;
const std::size_t begin_index = children.size();
E2D_DEFER([begin_index](){
children.erase(
children.begin() + begin_index,
children.end());
});
extract_children(
root,
std::back_inserter(children),
opts);
const std::size_t end_index = children.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
if ( !impl::invoke_with_force_bool(f, children[i]) ) {
return false;
}
}
return true;
}
}
namespace e2d::nodes
{
template < typename Component, typename Node, typename Iter >
std::size_t extract_components_from_parents(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts)
{
std::size_t count{0u};
for_each_parent(root, [&count, &iter](const auto& parent){
if ( auto component = parent->owner().template component<Component>() ) {
++count;
iter++ = component;
}
}, opts);
return count;
}
template < typename Component, typename Node, typename Iter >
std::size_t extract_components_from_children(
const intrusive_ptr<Node>& root,
Iter iter,
const options& opts)
{
std::size_t count{0u};
for_each_child(root, [&count, &iter](const auto& child){
if ( auto component = child->owner().template component<Component>() ) {
++count;
iter++ = component;
}
}, opts);
return count;
}
}
namespace e2d::nodes
{
template < typename Component, typename Node, typename F >
bool for_extracted_components_from_parents(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<gcomponent<Component>> components;
const std::size_t begin_index = components.size();
E2D_DEFER([begin_index](){
components.erase(
components.begin() + begin_index,
components.end());
});
extract_components_from_parents<Component>(
root,
std::back_inserter(components),
opts);
const std::size_t end_index = components.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
if ( !impl::invoke_with_force_bool(f, components[i]) ) {
return false;
}
}
return true;
}
template < typename Component, typename Node, typename F >
bool for_extracted_components_from_children(
const intrusive_ptr<Node>& root,
F&& f,
const options& opts)
{
//TODO(BlackMat): replace it to frame allocator
static thread_local vector<gcomponent<Component>> components;
const std::size_t begin_index = components.size();
E2D_DEFER([begin_index](){
components.erase(
components.begin() + begin_index,
components.end());
});
extract_components_from_children<Component>(
root,
std::back_inserter(components),
opts);
const std::size_t end_index = components.size();
for ( std::size_t i = begin_index; i < end_index; ++i ) {
if ( !impl::invoke_with_force_bool(f, components[i]) ) {
return false;
}
}
return true;
}
}
namespace e2d::nodes
{
template < typename Component, typename Node >
gcomponent<Component> find_component_from_parents(
const intrusive_ptr<Node>& root,
const options& opts)
{
gcomponent<Component> component;
for_each_parent(root, [&component](const auto& child){
return !(component = child->owner().template component<Component>());
}, opts);
return component;
}
template < typename Component, typename Node >
gcomponent<Component> find_component_from_children(
const intrusive_ptr<Node>& root,
const options& opts)
{
gcomponent<Component> component;
for_each_child(root, [&component](const auto& child){
return !(component = child->owner().template component<Component>());
}, opts);
return component;
}
}

View File

@@ -5,7 +5,6 @@
******************************************************************************/
#include <enduro2d/high/node.hpp>
#include <enduro2d/high/world.hpp>
namespace e2d
{
@@ -446,54 +445,36 @@ namespace e2d
namespace e2d::nodes
{
vector<node_iptr> extract_nodes(const node_iptr& root) {
vector<node_iptr> nodes;
extract_nodes(root, std::back_inserter(nodes));
return nodes;
options& options::reversed(bool value) noexcept {
if ( value != reversed() ) {
math::flip_flags_inplace(flags_, fm_reversed);
}
return *this;
}
vector<const_node_iptr> extract_nodes(const const_node_iptr& root) {
vector<const_node_iptr> nodes;
extract_nodes(root, std::back_inserter(nodes));
return nodes;
options& options::recursive(bool value) noexcept {
if ( value != recursive() ) {
math::flip_flags_inplace(flags_, fm_recursive);
}
return *this;
}
vector<node_iptr> extract_nodes_reversed(const node_iptr& root) {
vector<node_iptr> nodes;
extract_nodes_reversed(root, std::back_inserter(nodes));
return nodes;
options& options::include_root(bool value) noexcept {
if ( value != include_root() ) {
math::flip_flags_inplace(flags_, fm_include_root);
}
return *this;
}
vector<const_node_iptr> extract_nodes_reversed(const const_node_iptr& root) {
vector<const_node_iptr> nodes;
extract_nodes_reversed(root, std::back_inserter(nodes));
return nodes;
}
}
namespace e2d::nodes
{
vector<node_iptr> extract_parents(const node_iptr& child) {
vector<node_iptr> parents;
extract_parents(child, std::back_inserter(parents));
return parents;
}
vector<const_node_iptr> extract_parents(const const_node_iptr& child) {
vector<const_node_iptr> parents;
extract_parents(child, std::back_inserter(parents));
return parents;
}
vector<node_iptr> extract_parents_reversed(const node_iptr& child) {
vector<node_iptr> parents;
extract_parents_reversed(child, std::back_inserter(parents));
return parents;
}
vector<const_node_iptr> extract_parents_reversed(const const_node_iptr& child) {
vector<const_node_iptr> parents;
extract_parents_reversed(child, std::back_inserter(parents));
return parents;
bool options::reversed() const noexcept {
return math::check_any_flags(flags_, fm_reversed);
}
bool options::recursive() const noexcept {
return math::check_any_flags(flags_, fm_recursive);
}
bool options::include_root() const noexcept {
return math::check_any_flags(flags_, fm_include_root);
}
}

View File

@@ -30,9 +30,9 @@ namespace
const scene&,
const actor& scn_a)
{
nodes::for_extracted_nodes(scn_a.node(), [&ctx](const const_node_iptr& node){
nodes::for_extracted_children(scn_a.node(), [&ctx](const const_node_iptr& node){
ctx.draw(node);
});
}, nodes::options().recursive(true).include_root(true));
};
ecsex::for_extracted_sorted_components<scene, actor>(

View File

@@ -103,7 +103,7 @@ namespace
}
if ( tree_node_opened ) {
root->for_each_child([&e, &i, &w](const node_iptr& child){
nodes::for_each_child(root, [&e, &i, &w](const node_iptr& child){
show_tree_for_node(e, i, w, child);
});
}

View File

@@ -142,32 +142,36 @@ namespace
}
void shutdown_instance(gobject& inst) noexcept {
if ( gcomponent<actor> inst_a{inst}; inst_a ) {
nodes::for_extracted_nodes(inst_a->node(), [](const node_iptr& node){
if ( gcomponent<behaviour> inst_b{node->owner()}; inst_b ) {
behaviours::call_meta_method(
*inst_b,
"on_shutdown",
node->owner());
}
});
gcomponent<actor> inst_a = inst.component<actor>();
if ( !inst_a ) {
return;
}
nodes::for_extracted_components_from_children<behaviour>(
inst_a->node(),
[](gcomponent<behaviour>& inst_b){
behaviours::call_meta_method(
*inst_b,
"on_shutdown",
inst_b.owner());
}, nodes::options().recursive(true).include_root(true));
}
void start_instance(gobject& inst) {
if ( gcomponent<actor> inst_a{inst}; inst_a ) {
nodes::for_extracted_nodes(inst_a->node(), [&inst](const node_iptr& node){
if ( gcomponent<behaviour> inst_b{node->owner()}; inst_b ) {
const auto result = behaviours::call_meta_method(
*inst_b,
"on_start",
node->owner());
if ( result == behaviours::call_result::failed ) {
inst.component<disabled<behaviour>>().assign();
}
}
});
gcomponent<actor> inst_a = inst.component<actor>();
if ( !inst_a ) {
return;
}
nodes::for_extracted_components_from_children<behaviour>(
inst_a->node(),
[&inst](gcomponent<behaviour>& inst_b){
const auto result = behaviours::call_meta_method(
*inst_b,
"on_start",
inst_b.owner());
if ( result == behaviours::call_result::failed ) {
inst.component<disabled<behaviour>>().assign();
}
}, nodes::options().recursive(true).include_root(true));
}
}

View File

@@ -595,7 +595,7 @@ TEST_CASE("node") {
node::create(p)};
{
std::size_t count = 0;
p->for_each_child([&ns, &count](const node_iptr& n){
nodes::for_each_child(p, [&ns, &count](const node_iptr& n){
REQUIRE(ns[count++] == n);
});
REQUIRE(count == 3);
@@ -603,7 +603,7 @@ TEST_CASE("node") {
{
const_node_iptr cp = p;
std::size_t count = 0;
cp->for_each_child([&ns, &count](const const_node_iptr& n){
nodes::for_each_child(cp, [&ns, &count](const const_node_iptr& n){
REQUIRE(ns[count++] == n);
});
REQUIRE(count == 3);
@@ -617,13 +617,19 @@ TEST_CASE("node") {
const vector<node_iptr> ns{p, c1, c2, c3};
{
vector<node_iptr> ns2;
REQUIRE(4u == nodes::extract_nodes(p, std::back_inserter(ns2)));
REQUIRE(4u == nodes::extract_children(
p,
std::back_inserter(ns2),
nodes::options().recursive(true).include_root(true)));
REQUIRE(ns == ns2);
}
{
const_node_iptr cp = p;
vector<const_node_iptr> ns2;
REQUIRE(4u == nodes::extract_nodes(cp, std::back_inserter(ns2)));
REQUIRE(4u == nodes::extract_children(
cp,
std::back_inserter(ns2),
nodes::options().recursive(true).include_root(true)));
REQUIRE(ns.size() == ns2.size());
for ( std::size_t i = 0; i < ns.size(); ++i ) {
REQUIRE(ns[i] == ns2[i]);