Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion src/core/include/scene/unit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,87 @@ namespace gkit::scene {

private:
std::atomic<bool> process_enabled = true; // process enabled flag
std::atomic<bool> ready_to_drop = false; // drop flag(mark as dead)
std::atomic<bool> 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);
auto operator*() -> reference const;
auto operator->() -> pointer const;
auto operator++() -> iterator&;
auto operator++(int) -> iterator;
auto operator--() -> iterator&;
auto operator--(int) -> iterator;
auto operator==(const iterator& other) const -> bool;
auto operator!=(const iterator& other) const -> bool;

private:
Unit* m_owner;
size_t m_pos;
friend class Unit;
};

// Why this part didn't use auto, because it need to have a const_iterator use
// but auto could not allow two same function but with different return
// but begin() and end() need those two return
// So I will not change it
auto begin() -> iterator;
auto end() -> iterator;

Comment on lines +239 to +245
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style

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);
auto operator*() -> reference const;
auto operator->() -> pointer const;
auto operator++() -> const_iterator&;
auto operator++(int) -> const_iterator;
auto operator--() -> const_iterator&;
auto operator--(int) -> const_iterator;
auto operator==(const const_iterator& other) const -> bool;
auto operator!=(const const_iterator& other) const -> bool;

private:
const Unit* m_owner;
size_t m_pos;
};

auto begin() const -> const_iterator;
auto end() const -> const_iterator;

auto cbegin() const -> const_iterator;
auto cend() const -> const_iterator;

public:
// This is a reverse iterator, implemented using std::reverse_iterator.
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;

auto rbegin() -> reverse_iterator;
auto rend() -> reverse_iterator;

auto rbegin() const -> const_reverse_iterator;
auto rend() const -> const_reverse_iterator;

auto crbegin() const -> const_reverse_iterator;
auto crend() const -> const_reverse_iterator;

}; // class Unit

template <IsUnitExtend T>
Expand Down
98 changes: 98 additions & 0 deletions src/core/scene/unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,101 @@ auto gkit::scene::Unit::get_parent<gkit::scene::Unit>() noexcept -> std::optiona
if (parent == nullptr) return std::nullopt;
return std::ref(*parent);
}


// iterator part use
gkit::scene::Unit::iterator::iterator(Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {}
auto gkit::scene::Unit::iterator::operator*() -> reference const {
auto child_opt = m_owner->get_available_child(static_cast<uint32_t>(m_pos));
return **child_opt;
}
auto gkit::scene::Unit::iterator::operator->() -> pointer const {
auto child_opt = m_owner->get_available_child(static_cast<uint32_t>(m_pos));
return *child_opt;
}
auto gkit::scene::Unit::iterator::operator++() -> iterator& {
++m_pos;
return *this;
}
auto gkit::scene::Unit::iterator::operator++(int) -> iterator {
iterator tmp = *this;
++(*this);
return tmp;
}
auto gkit::scene::Unit::iterator::operator--() -> iterator& {
--m_pos;
return *this;
}
auto gkit::scene::Unit::iterator::operator--(int) -> iterator {
iterator tmp = *this;
--(*this);
return tmp;
}
auto gkit::scene::Unit::iterator::operator==(const iterator& other) const -> bool { return m_owner == other.m_owner && m_pos == other.m_pos; }
auto gkit::scene::Unit::iterator::operator!=(const iterator& other) const -> bool { return !(*this == other); }

auto gkit::scene::Unit::begin() -> iterator{
return iterator(this, 0);
}

auto gkit::scene::Unit::end() -> iterator{
return iterator(this, active_index_cache.size());
}

// now is const_iterator use
gkit::scene::Unit::const_iterator::const_iterator(const Unit* owner, size_t pos) : m_owner(owner), m_pos(pos) {}

auto gkit::scene::Unit::const_iterator::operator*() -> reference const {
auto child_opt = const_cast<Unit*>(m_owner)->get_available_child(static_cast<uint32_t>(m_pos));
return **child_opt;
}

auto gkit::scene::Unit::const_iterator::operator->() -> pointer const {
auto child_opt = const_cast<Unit*>(m_owner)->get_available_child(static_cast<uint32_t>(m_pos));
return *child_opt;
}

auto gkit::scene::Unit::const_iterator::operator++() -> const_iterator& {
++m_pos;
return *this;
}
auto gkit::scene::Unit::const_iterator::operator++(int) -> const_iterator {
const_iterator tmp = *this;
++(*this);
return tmp;
}
auto gkit::scene::Unit::const_iterator::operator--() -> const_iterator& {
--m_pos;
return *this;
}
auto gkit::scene::Unit::const_iterator::operator--(int) -> const_iterator {
const_iterator tmp = *this;
--(*this);
return tmp;
}

auto gkit::scene::Unit::const_iterator::operator==(const const_iterator& other) const -> bool { return m_owner == other.m_owner && m_pos == other.m_pos; }
auto gkit::scene::Unit::const_iterator::operator!=(const const_iterator& other) const -> bool { return !(*this == other); }

auto gkit::scene::Unit::begin() const -> const_iterator {
const_cast<Unit*>(this);
return const_iterator(this, 0);
}

auto gkit::scene::Unit::end() const -> const_iterator {
const_cast<Unit*>(this);
return const_iterator(this, active_index_cache.size());
}

auto gkit::scene::Unit::cbegin() const -> const_iterator { return begin(); }
auto gkit::scene::Unit::cend() const -> const_iterator { return end(); }

// This is a reverse iterator, implemented using std::reverse_iterator.
using reverse_iterator = std::reverse_iterator<gkit::scene::Unit::iterator>;
using const_reverse_iterator = std::reverse_iterator<gkit::scene::Unit::const_iterator>;
auto gkit::scene::Unit::rbegin() -> reverse_iterator { return reverse_iterator(end()); }
auto gkit::scene::Unit::rend() -> reverse_iterator { return reverse_iterator(begin()); }
auto gkit::scene::Unit::rbegin() const -> const_reverse_iterator { return const_reverse_iterator(end()); }
auto gkit::scene::Unit::rend() const -> const_reverse_iterator { return const_reverse_iterator(begin()); }
auto gkit::scene::Unit::crbegin() const -> const_reverse_iterator { return rbegin(); }
auto gkit::scene::Unit::crend() const -> const_reverse_iterator { return rend(); }