diff --git a/src/core/include/scene/unit.hpp b/src/core/include/scene/unit.hpp index 8cb5439..289c0bd 100644 --- a/src/core/include/scene/unit.hpp +++ b/src/core/include/scene/unit.hpp @@ -57,28 +57,25 @@ namespace gkit::scene { protected: // control workflow handler friend Application; - friend class iterator; - friend class const_iterator; - /** * @brief The call the @ref _ready() of the unit and the children. * @note It will be called when the unit is ready. * It always will be called when the call @ref gkit::application::run - * and an unit become the child of another Unit instance by calling + * and an unit become the child of another Unit instance by calling * @ref add_child if the unit is active. - * - * It will call the @ref _ready() of the children of the unit + * + * It will call the @ref _ready() of the children of the unit * in the forward order of valid indexes and call this one. */ auto ready_handler() noexcept -> void; /** * @brief The call the @ref _process() of the unit and the children. - * @note It will be called before the frame begin. And call the @ref _process() + * @note It will be called before the frame begin. And call the @ref _process() * of the children of the unit(the called order is same as @ref ready_handler) - * + * * Before call the @ref _process(), it will call the @ref update_index_cache() - * to make sure the index cache is valid. After call @ref _process() for its children + * to make sure the index cache is valid. After call @ref _process() for its children * and itself, it will call the @ref drop_children() to drop the children whose * @ref ready_to_drop is true. */ @@ -151,7 +148,7 @@ namespace gkit::scene { * @param index The index of the child. * @param func The callable method, which return type is not void. * @param args The arguments of the callable method. - * @return the callable method's return value. + * @return the callable method's return value. * If the index is out of range, return std::nullopt. */ template @@ -185,7 +182,7 @@ namespace gkit::scene { /** * @brief Get the available child pointer. * @param index The index of the child. - * @return std::optional + * @return std::optional * If the index is valid, return the pointer to the child, otherwise return std::nullopt. */ auto get_available_child(uint32_t index) noexcept -> std::optional; @@ -210,143 +207,7 @@ namespace gkit::scene { private: std::atomic process_enabled = true; // process enabled flag - std::atomic ready_to_drop = false; // drop flag(mark as dead) - - public: - // iterator - class iterator { - public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = Unit; - using difference_type = std::ptrdiff_t; - using pointer = Unit*; - using reference = Unit&; - - public: - iterator(Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {} - reference operator*() const { - auto child_opt = m_owner->get_available_child(static_cast(m_pos)); - return **child_opt; - } - pointer operator->() const { - auto child_opt = m_owner->get_available_child(static_cast(m_pos)); - return *child_opt; - } - iterator &operator++() { - ++m_pos; - return *this; - } - iterator operator++(int) { - iterator tmp = *this; - ++(*this); - return tmp; - } - iterator &operator--() { - --m_pos; - return *this; - } - iterator operator--(int) { - iterator tmp = *this; - --(*this); - return tmp; - } - bool operator==(const iterator& other) const { return m_owner == other.m_owner && m_pos == other.m_pos; } - bool operator!=(const iterator& other) const { return !(*this == other); } - - private: - Unit* m_owner; - size_t m_pos; - friend class Unit; - }; - - iterator begin() { - update_index_cache(); - return iterator(this, 0); - } - - iterator end() { - update_index_cache(); - return iterator(this, active_index_cache.size()); - } - - public: - // Next, we are going to write the const implementation of the iterator. - class const_iterator { - public: - using iterator_category = std::bidirectional_iterator_tag; - using value_type = const Unit; - using difference_type = std::ptrdiff_t; - using pointer = const Unit*; - using reference = const Unit&; - - const_iterator(const Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {} - - reference operator*() const { - auto child_opt = const_cast(m_owner)->get_available_child(static_cast(m_pos)); - return **child_opt; - } - - pointer operator->() const { - auto child_opt = const_cast(m_owner)->get_available_child(static_cast(m_pos)); - return *child_opt; - } - - const_iterator &operator++() { - ++m_pos; - return *this; - } - const_iterator operator++(int) { - const_iterator tmp = *this; - ++(*this); - return tmp; - } - const_iterator &operator--() { - --m_pos; - return *this; - } - const_iterator operator--(int) { - const_iterator tmp = *this; - --(*this); - return tmp; - } - - bool operator==(const const_iterator& other) const { - return m_owner == other.m_owner && m_pos == other.m_pos; - } - bool operator!=(const const_iterator& other) const { return !(*this == other); } - - private: - const Unit* m_owner; - size_t m_pos; - }; - - const_iterator begin() const { - const_cast(this)->update_index_cache(); - return const_iterator(this, 0); - } - - const_iterator end() const { - const_cast(this)->update_index_cache(); - return const_iterator(this, active_index_cache.size()); - } - - const_iterator cbegin() const { return begin(); } - const_iterator cend() const { return end(); } - - public: - // This is a reverse iterator, implemented using std::reverse_iterator. - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - reverse_iterator rbegin() { return reverse_iterator(end()); } - reverse_iterator rend() { return reverse_iterator(begin()); } - - const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - - const_reverse_iterator crbegin() const { return rbegin(); } - const_reverse_iterator crend() const { return rend(); } - + std::atomic ready_to_drop = false; // drop flag(mark as dead) }; // class Unit template @@ -355,7 +216,7 @@ namespace gkit::scene { try { auto ptr = std::unique_ptr(new T(name)); return ptr; - } catch (...) { + } catch(...) { return nullptr; } } diff --git a/test/core/scene/test_unit_iterator.cpp b/test/core/scene/test_unit_iterator.cpp deleted file mode 100644 index a3cd065..0000000 --- a/test/core/scene/test_unit_iterator.cpp +++ /dev/null @@ -1,120 +0,0 @@ -#include "scene/unit.hpp" -#include -#include -#include -#include -#include -#include -#include -#include - -using gkit::scene::Unit; - -#define TEST(cond, msg) do { \ - if (!(cond)) { \ - std::cerr << "FAIL: " << msg << " (" << __FILE__ << ":" << __LINE__ << ")" << std::endl; \ - return false; \ - } else { \ - std::cout << "PASS: " << msg << std::endl; \ - } \ -} while(0) - - -class TestUnit : public Unit { -public: - // using Unit::Unit; - using Unit::ready_handler; - using Unit::process_handler; - using Unit::exit_handler; - using Unit::parent; - - static auto create(std::string name = "") { - return Unit::create(std::move(name)); - } - - int ready_calls = 0; - int process_calls = 0; - int physics_calls = 0; - int exit_calls = 0; - std::string name_storage; - - // 自定义构造函数 - TestUnit(const std::string& name) : Unit(name), name_storage(name) {} - - void _ready() override { - ready_calls++; - std::cout << "TestUnit[" << name_storage << "] _ready()\n"; - } - void _process() override { - process_calls++; - std::cout << "TestUnit[" << name_storage << "] _process()\n"; - } - void _physics_process() override { - physics_calls++; - } - void _exit() override { - exit_calls++; - std::cout << "TestUnit[" << name_storage << "] _exit()\n"; - } -}; - -// ==================== test ==================== - -bool test_iterator() { - std::cout << "\n=== test_iterator ===\n"; - auto parent = TestUnit::create("parent"); - std::vector children; - for (int i = 0; i < 5; ++i) { - auto child = TestUnit::create("child" + std::to_string(i)); - children.push_back(child.get()); - parent->add_child(std::move(child)); - } - parent->process_handler(); - - int idx = 0; - for (auto& u : *parent) { - TEST(&u == children[idx], "iterator order matches addition"); - idx++; - } - TEST(idx == 5, "iterated all 5 children"); - - idx = 4; - for (auto it = parent->rbegin(); it != parent->rend(); ++it) { - TEST(&(*it) == children[idx], "reverse iterator order"); - idx--; - } - TEST(idx == -1, "reverse iterated all"); - - auto it = parent->begin(); - ++it; - TEST(&(*it) == children[1], "pre-increment"); - it++; - TEST(&(*it) == children[2], "post-increment"); - --it; - TEST(&(*it) == children[1], "pre-decrement"); - it--; - TEST(&(*it) == children[0], "post-decrement"); - - const auto& const_parent = *parent; - idx = 0; - for (auto& u : const_parent) { - TEST(&u == children[idx], "const iterator works"); - idx++; - } - return true; -} - -// ==================== main function ==================== -int main() { - bool all_passed = true; - // 仅运行迭代器测试 - all_passed &= test_iterator(); - - if (all_passed) { - std::cout << "\nAll tests passed!\n"; - return 0; - } else { - std::cerr << "\nSome tests failed.\n"; - return 1; - } -} \ No newline at end of file