-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from AGH-Code-Industry/scene
Scenes + Hierarchies
- Loading branch information
Showing
16 changed files
with
881 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#pragma once | ||
|
||
#include <hier/ChildNode.h> | ||
#include <hier/ChildrenIterator.h> | ||
#include <hier/HierarchyIterator.h> | ||
#include <hier/HierarchyNode.h> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#pragma once | ||
|
||
#include <Ecs.h> | ||
#include <Hier.h> | ||
|
||
namespace arch { | ||
|
||
class Scene { | ||
public: | ||
|
||
/// @brief Hierarchy node class | ||
using Node = hier::HierarchyNode; | ||
|
||
/// @brief Default constructor | ||
Scene() noexcept; | ||
|
||
/// @brief Creates new entity | ||
/// @see arch::ecs::Domain::newEntity() | ||
ecs::Entity newEntity() noexcept; | ||
/// @brief Kills entity | ||
/// @see arch::ecs::Domain::kill(const ecs::Entity) | ||
void removeEntity(const ecs::Entity entity) noexcept; | ||
|
||
/// @brief Returns ecs::Domain of this scene | ||
ecs::Domain& domain() noexcept; | ||
/// @brief Returns readonly ecs::Domain of this scene | ||
const ecs::Domain& domain() const noexcept; | ||
|
||
/// @brief Returns root entity | ||
ecs::Entity root() const noexcept; | ||
/// @brief Returns root node | ||
Node& rootNode() noexcept; | ||
/// @brief Returns readonly root node | ||
const Node& rootNode() const noexcept; | ||
|
||
private: | ||
|
||
ecs::Domain _domain; | ||
Node* _rootNode; | ||
}; | ||
|
||
} // namespace arch |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#pragma once | ||
|
||
#include <ecs/EntityTraits.h> | ||
|
||
namespace arch::hier { | ||
|
||
struct HierarchyNode; | ||
|
||
/// @brief Base class of HierarchyNode, also type of sentinel. | ||
struct ChildNode { | ||
/// @brief Previous sibling | ||
ChildNode* _prev; | ||
/// @brief Next sibling | ||
ChildNode* _next; | ||
|
||
/// @brief Entity value | ||
ecs::Entity _entity = ecs::nullEntity; | ||
}; | ||
|
||
} // namespace arch::hier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
#pragma once | ||
|
||
#include "ChildNode.h" | ||
#include <ecs/Domain.h> | ||
|
||
namespace arch::hier { | ||
|
||
/// @brief Simple hierarchy iterator, providing access to children of an entity | ||
/// @details Models std::bidirectional_iterator | ||
class ChildrenIterator { | ||
public: | ||
|
||
/// @brief Default constructor | ||
ChildrenIterator() noexcept = default; | ||
/// @brief Node constructor | ||
/// @param node - node to point to | ||
ChildrenIterator(const ChildNode* node) noexcept; | ||
/// @brief Copy constructor | ||
ChildrenIterator(const ChildrenIterator&) noexcept = default; | ||
/// @brief Move constructor | ||
ChildrenIterator(ChildrenIterator&&) noexcept = default; | ||
|
||
/// @brief Copy-assignment operator | ||
ChildrenIterator& operator=(const ChildrenIterator&) noexcept = default; | ||
/// @brief Move-assignment operator | ||
ChildrenIterator& operator=(ChildrenIterator&&) noexcept = default; | ||
|
||
/// @brief Equality operator | ||
bool operator==(const ChildrenIterator&) const noexcept = default; | ||
|
||
/// @brief Dereference operator | ||
ecs::Entity operator*() const noexcept; | ||
|
||
/// @brief Prefix increment operator | ||
ChildrenIterator& operator++() noexcept; | ||
/// @brief Postfix increment operator | ||
ChildrenIterator operator++(int) noexcept; | ||
|
||
/// @brief Prefix decrement operator | ||
ChildrenIterator& operator--() noexcept; | ||
/// @brief Postfix decrement operator | ||
ChildrenIterator operator--(int) noexcept; | ||
|
||
private: | ||
|
||
const ChildNode* _current; | ||
}; | ||
|
||
} // namespace arch::hier | ||
|
||
template<> | ||
struct std::iterator_traits<arch::hier::ChildrenIterator> { | ||
using difference_type = std::ptrdiff_t; | ||
using value_type = arch::ecs::Entity; | ||
using pointer = void; | ||
using reference = void; | ||
using iterator_category = std::bidirectional_iterator_tag; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
#pragma once | ||
|
||
#include <ecs/Entity.h> | ||
|
||
namespace arch::hier { | ||
|
||
class HierarchyNode; | ||
class ChildNode; | ||
|
||
namespace _details { // NOLINT | ||
|
||
/// @brief Simple hierarchy iterator, providing recursive access to descendants of an entity | ||
/// @details Models std::bidirectional_iterator | ||
class HierarchyIterator { | ||
public: | ||
|
||
/// @brief Default constructor | ||
HierarchyIterator() noexcept = default; | ||
/// @brief Node constructor | ||
/// @param node - node to point to | ||
HierarchyIterator(const ChildNode* node) noexcept; | ||
/// @brief Copy constructor | ||
HierarchyIterator(const HierarchyIterator&) noexcept = default; | ||
/// @brief Move constructor | ||
HierarchyIterator(HierarchyIterator&&) noexcept = default; | ||
|
||
/// @brief Copy-assignment operator | ||
HierarchyIterator& operator=(const HierarchyIterator&) noexcept = default; | ||
/// @brief Move-assignment operator | ||
HierarchyIterator& operator=(HierarchyIterator&&) noexcept = default; | ||
|
||
/// @brief Equality operator | ||
bool operator==(const HierarchyIterator&) const noexcept = default; | ||
|
||
/// @brief Dereference operator | ||
ecs::Entity operator*() const noexcept; | ||
|
||
/// @brief Prefix increment operator | ||
HierarchyIterator& operator++() noexcept; | ||
/// @brief Postfix increment operator | ||
HierarchyIterator operator++(int) noexcept; | ||
|
||
/// @brief Prefix decrement operator | ||
HierarchyIterator& operator--() noexcept; | ||
/// @brief Postfix decrement operator | ||
HierarchyIterator operator--(int) noexcept; | ||
|
||
private: | ||
|
||
const ChildNode* _current; | ||
}; | ||
|
||
} // namespace _details | ||
|
||
} // namespace arch::hier | ||
|
||
template<> | ||
struct std::iterator_traits<arch::hier::_details::HierarchyIterator> { | ||
using difference_type = std::ptrdiff_t; | ||
using value_type = arch::ecs::Entity; | ||
using pointer = void; | ||
using reference = void; | ||
using iterator_category = std::bidirectional_iterator_tag; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
#pragma once | ||
|
||
#include <ranges> | ||
|
||
#include "ChildNode.h" | ||
#include "ChildrenIterator.h" | ||
#include "HierarchyIterator.h" | ||
#include <ecs/ComponentTraits.h> | ||
#include <utils/OptRef.h> | ||
|
||
namespace arch { | ||
|
||
class Scene; | ||
|
||
} | ||
|
||
namespace arch::hier { | ||
|
||
namespace _details { | ||
|
||
class HierarchyIterator; | ||
class ChildrenIterator; | ||
|
||
} // namespace _details | ||
|
||
/// @brief Main node class, implementing hierarchies | ||
/// @details An in-place component | ||
class HierarchyNode: public ChildNode { | ||
using Self = HierarchyNode; | ||
|
||
public: | ||
|
||
/// @brief Makes HierarchyNode immovable in ecs storage, to preserve internal pointers | ||
static constexpr bool inPlaceComponent = true; | ||
|
||
/// @brief Entity constructor | ||
HierarchyNode(const ecs::Entity entity) noexcept; | ||
|
||
/// @brief Iterator type | ||
using Iterator = ChildrenIterator; | ||
/// @brief ReverseIterator type | ||
using ReverseIterator = std::reverse_iterator<ChildrenIterator>; | ||
|
||
bool setParent(Self& newParent) noexcept; | ||
bool isChildOf(const Self& other) const noexcept; | ||
|
||
Self& ancestor(u32 which = 1) noexcept; | ||
const Self& ancestor(u32 which = 1) const noexcept; | ||
i64 ancestry(const Self& other) const noexcept; | ||
|
||
Self& parent() noexcept; | ||
const Self& parent() const noexcept; | ||
|
||
Self& child(u32 which = 1) noexcept; | ||
const Self& child(u32 which = 1) const noexcept; | ||
OptRef<Self> childOpt(u32 which = 1) noexcept; | ||
OptRef<const Self> childOpt(u32 which = 1) const noexcept; | ||
Self& firstChild() noexcept; | ||
const Self& firstChild() const noexcept; | ||
OptRef<Self> firstChildOpt() noexcept; | ||
OptRef<const Self> firstChildOpt() const noexcept; | ||
Self& lastChild() noexcept; | ||
const Self& lastChild() const noexcept; | ||
OptRef<Self> lastChildOpt() noexcept; | ||
OptRef<const Self> lastChildOpt() const noexcept; | ||
u32 childrenCount() const noexcept; | ||
|
||
ecs::Entity entity() const noexcept; | ||
u32 depth() const noexcept; | ||
|
||
/// @brief Returns iterator to first child | ||
Iterator begin() const noexcept; | ||
/// @brief Returns iterator to first child | ||
Iterator cbegin() const noexcept; | ||
/// @brief Returns iterator to sentinel | ||
Iterator end() const noexcept; | ||
/// @brief Returns iterator to sentinel | ||
Iterator cend() const noexcept; | ||
/// @brief Returns reverse iterator to last child | ||
ReverseIterator rbegin() const noexcept; | ||
/// @brief Returns reverse iterator to last child | ||
ReverseIterator crbegin() const noexcept; | ||
/// @brief Returns reverse iterator to sentinel | ||
ReverseIterator rend() const noexcept; | ||
/// @brief Returns reverse iterator to sentinel | ||
ReverseIterator crend() const noexcept; | ||
|
||
/// @brief Return view with recursive iterators | ||
auto recursiveIterable() noexcept | ||
-> decltype(std::ranges::subrange(_details::HierarchyIterator(nullptr), _details::HierarchyIterator(nullptr))); | ||
/// @brief Return readonly view with recursive iterators | ||
auto recursiveIterable() const noexcept | ||
-> decltype(std::ranges::subrange(_details::HierarchyIterator(nullptr), _details::HierarchyIterator(nullptr))); | ||
|
||
private: | ||
|
||
friend class ::arch::Scene; | ||
friend class _details::ChildrenIterator; | ||
friend class _details::HierarchyIterator; | ||
|
||
void _unparent() noexcept; | ||
void _setParentUnchecked(Self& newParent) noexcept; | ||
|
||
using ChildNode::_entity; | ||
using ChildNode::_next; | ||
using ChildNode::_prev; | ||
/// @brief Sentinel node, before first and after the last | ||
ChildNode _sentinel{ &_sentinel, &_sentinel, ecs::nullEntity }; | ||
/// @brief First child node | ||
ChildNode* _first = nullptr; | ||
/// @brief Last child node | ||
ChildNode* _last = nullptr; | ||
/// @brief Children count | ||
u32 _count = 0; | ||
/// @brief Hierarchy depth (distance to root) | ||
u32 _depth = 0; | ||
/// @brief Parent node | ||
Self* _parent = nullptr; | ||
}; | ||
|
||
} // namespace arch::hier |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#pragma once | ||
|
||
#include <optional> | ||
|
||
namespace arch { | ||
|
||
/// @brief std::optional equivalent for references | ||
template<class T> | ||
class OptRef { | ||
public: | ||
|
||
OptRef() noexcept = default; | ||
OptRef(std::nullopt_t) noexcept; | ||
OptRef(const OptRef&) noexcept = default; | ||
OptRef(OptRef&&) noexcept = default; | ||
OptRef(T& ref) noexcept; | ||
|
||
T& operator*() noexcept; | ||
const T& operator*() const noexcept requires(!std::is_const_v<T>); | ||
operator T&() noexcept; | ||
operator const T&() const noexcept requires(!std::is_const_v<T>); | ||
T& get() noexcept; | ||
const T& get() const noexcept requires(!std::is_const_v<T>); | ||
T* operator->() noexcept; | ||
const T* operator->() const noexcept requires(!std::is_const_v<T>); | ||
|
||
operator bool() const noexcept; | ||
bool hasValue() const noexcept; | ||
|
||
T& tryGet(); | ||
const T& tryGet() const requires(!std::is_const_v<T>); | ||
T& getOr(T& other) noexcept; | ||
const T& getOr(const T& other) const noexcept requires(!std::is_const_v<T>); | ||
|
||
void swap(OptRef& other) noexcept; | ||
|
||
private: | ||
|
||
T* _ptr = nullptr; | ||
}; | ||
|
||
} // namespace arch | ||
|
||
#include "OptRef.hpp" |
Oops, something went wrong.