3#include "structure/design_pattern/spk_activable_object.hpp"
4#include "structure/design_pattern/spk_inherence_object.hpp"
6#include "structure/system/event/spk_keyboard_event.hpp"
7#include "structure/system/event/spk_mouse_event.hpp"
8#include "structure/system/event/spk_paint_event.hpp"
9#include "structure/system/event/spk_system_event.hpp"
10#include "structure/system/event/spk_update_event.hpp"
20#include "structure/design_pattern/spk_contract_provider.hpp"
21#include "structure/engine/spk_component.hpp"
23#include "type/spk_binary_operator.hpp"
43 std::set<std::wstring> _tags;
45 std::atomic<int> _priority = 0;
47 mutable std::recursive_mutex _componentMutex;
48 mutable std::recursive_mutex _childMutex;
50 std::vector<std::unique_ptr<Component>> _components;
54 void _sortByPriority(std::vector<T> &p_container, std::recursive_mutex &p_mutex)
56 std::unique_lock<std::recursive_mutex> mutexLock(p_mutex);
61 [](
const T &p_a,
const T &p_b) {
62 int priorityA = p_a->priority();
63 int priorityB = p_b->priority();
65 bool aNoPriority = (priorityA < 0);
66 bool bNoPriority = (priorityB < 0);
68 if (aNoPriority && bNoPriority)
73 if (aNoPriority != bNoPriority)
75 return (!aNoPriority);
78 return (priorityA > priorityB);
82 template <
typename TCallback>
83 void _forEachChild(TCallback &&p_callback)
85 std::vector<Entity *> childSnapshot;
88 std::lock_guard<std::recursive_mutex> lock(_childMutex);
89 childSnapshot.assign(children().begin(), children().end());
92 for (
auto child : childSnapshot)
96 if constexpr (std::is_same_v<std::invoke_result_t<TCallback, Entity *>,
bool>)
98 if (p_callback(child) ==
false)
111 template <
typename TCallback>
112 void _forEachComponent(TCallback &&p_callback)
114 std::vector<spk::Component *> componentSnapshot;
117 std::lock_guard<std::recursive_mutex> lock(_componentMutex);
118 componentSnapshot.reserve(_components.size());
119 for (
const auto &component : _components)
121 if (component !=
nullptr)
123 componentSnapshot.emplace_back(component.get());
128 for (
auto component : componentSnapshot)
130 if (component !=
nullptr)
132 if constexpr (std::is_same_v<std::invoke_result_t<TCallback, spk::Component *>,
bool>)
134 if (p_callback(component) ==
false)
141 p_callback(component);
153 Entity(
const std::wstring &p_name,
Entity *p_owner =
nullptr);
167 virtual void setName(
const std::wstring &p_name);
172 void setPriority(
const int &p_priority);
178 void addTag(
const std::wstring &p_tag);
183 void removeTag(
const std::wstring &p_tag);
191 bool containTag(
const std::wstring &p_tag)
const;
213 const std::wstring &name()
const;
218 const std::set<std::wstring> &tags()
const;
223 int priority()
const;
228 size_t componentCount()
const;
231 void removeAllComponents();
237 void addChild(
Entity *p_child)
override;
242 void removeChild(
Entity *p_child)
override;
244 void clearChildren();
249 std::vector<Entity *> &children()
override;
254 const std::vector<Entity *> &children()
const override;
263 template <
typename TComponentType,
typename... TArgs>
266 static_assert(std::is_base_of_v<Component, TComponentType>,
"TComponentType must inherit from Component");
267 std::unique_ptr<TComponentType> newUniquePtr = std::make_unique<TComponentType>(std::forward<TArgs>(p_args)...);
268 TComponentType *newComponent = newUniquePtr.get();
271 std::unique_lock<std::recursive_mutex> lock(_componentMutex);
273 _components.emplace_back(std::move(newUniquePtr));
276 newComponent->_setOwner(
this);
278 newComponent->start();
279 newComponent->activate();
282 return (*newComponent);
289 void removeComponent(
const std::wstring &p_name);
297 template <
typename TComponentType>
300 std::unique_lock<std::recursive_mutex> lock(_componentMutex);
302 for (std::unique_ptr<Component> &component : _components)
304 TComponentType *castedComponent =
dynamic_cast<TComponentType *
>(component.get());
305 if (castedComponent !=
nullptr)
307 if (p_name.empty() || castedComponent->name() == p_name)
309 return (castedComponent);
322 template <
typename TComponentType>
325 std::unique_lock<std::recursive_mutex> lock(_componentMutex);
326 std::vector<TComponentType *> result;
328 for (std::unique_ptr<Component> &component : _components)
330 TComponentType *castedComponent =
dynamic_cast<TComponentType *
>(component.get());
331 if (castedComponent !=
nullptr)
333 result.emplace_back(castedComponent);
346 template <
typename TComponentType>
347 const TComponentType *
getComponent(
const std::wstring &p_name = L
"")
const
349 std::unique_lock<std::recursive_mutex> lock(_componentMutex);
350 for (
const std::unique_ptr<Component> &component : _components)
352 TComponentType *castedComponent =
dynamic_cast<TComponentType *
>(component.get());
353 if (castedComponent !=
nullptr)
355 if (p_name.empty() || castedComponent->name() == p_name)
357 return (castedComponent);
370 template <
typename TComponentType>
373 std::unique_lock<std::recursive_mutex> lock(_componentMutex);
374 std::vector<const TComponentType *> result;
376 for (
const std::unique_ptr<Component> &component : _components)
378 const TComponentType *castedComponent =
dynamic_cast<const TComponentType *
>(component.get());
379 if (castedComponent !=
nullptr)
381 result.emplace_back(castedComponent);
392 virtual void handleGeometryChange(
const spk::Extend2D &p_geometry)
final;
487 void sortComponent();
494 Entity *getChild(
const std::wstring &p_name);
500 const Entity *getChild(
const std::wstring &p_name)
const;
506 std::vector<Entity *> getChildren(
const std::wstring &p_name);
512 std::vector<const Entity *> getChildren(
const std::wstring &p_name)
const;
518 bool contains(
const std::wstring &p_name)
const;
524 size_t count(
const std::wstring &p_name)
const;
531 Entity *getChildByTag(
const std::wstring &p_tag);
537 const Entity *getChildByTag(
const std::wstring &p_tag)
const;
543 std::vector<Entity *> getChildrenByTag(
const std::wstring &p_tag);
549 std::vector<const Entity *> getChildrenByTag(
const std::wstring &p_tag)
const;
555 bool containsTag(
const std::wstring &p_tag)
const;
561 size_t countTag(
const std::wstring &p_tag)
const;
570 const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And);
577 const Entity *getChildByTags(
578 const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And)
const;
585 std::vector<Entity *> getChildrenByTags(
586 const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And);
593 std::vector<const Entity *> getChildrenByTags(
594 const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And)
const;
601 bool containsTags(
const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And)
const;
608 size_t countTags(
const std::span<const std::wstring> &p_tags, spk::BinaryOperator p_binaryOperator = spk::BinaryOperator::And)
const;
Stateful helper toggling between activated/deactivated states.
Definition spk_activable_object.hpp:20
StatefulObject< ActivationStatus >::Contract Contract
Subscription handle controlling callback lifetime.
Definition spk_activable_object.hpp:23
StatefulObject< ActivationStatus >::Job Job
Callback signature executed on activation state changes.
Definition spk_activable_object.hpp:25
Hierarchical game object containing components and children.
Definition spk_entity.hpp:34
const TComponentType * getComponent(const std::wstring &p_name=L"") const
Returns the first component matching the type and optional name.
Definition spk_entity.hpp:347
TComponentType * getComponent(const std::wstring &p_name=L"")
Returns the first component matching the type and optional name.
Definition spk_entity.hpp:298
spk::ActivableObject::Job Job
Job callback type for activation callbacks.
Definition spk_entity.hpp:39
void sortComponent()
Sorts components by priority.
Definition spk_entity.cpp:708
std::vector< TComponentType * > getComponents()
Returns all components matching the type.
Definition spk_entity.hpp:323
TComponentType & addComponent(TArgs &&...p_args)
Creates and adds a component of the given type.
Definition spk_entity.hpp:264
std::vector< const TComponentType * > getComponents() const
Returns all components matching the type.
Definition spk_entity.hpp:371
spk::ActivableObject::Contract Contract
Contract type for activation callbacks.
Definition spk_entity.hpp:37
Entity(const std::wstring &p_name, Entity *p_owner=nullptr)
Creates an entity with a name and optional owner.
Definition spk_entity.cpp:5
Root container that manages entities and dispatches events.
Definition spk_game_engine.hpp:22
Provides parent/child ownership links for tree structures.
Definition spk_inherence_object.hpp:22
Signals the window enters resize mode.
Definition spk_system_event.hpp:16
Signals the window exits resize mode.
Definition spk_system_event.hpp:34
Axis-aligned rectangle defined by an anchor point and size.
Definition spk_extend_2d.hpp:24
Reports focus gain or loss.
Definition spk_system_event.hpp:80
Requests or reports fullscreen state.
Definition spk_system_event.hpp:60
Character input event.
Definition spk_keyboard_event.hpp:38
Keyboard key press event.
Definition spk_keyboard_event.hpp:14
Keyboard key release event.
Definition spk_keyboard_event.hpp:26
Requests or reports maximized state.
Definition spk_system_event.hpp:70
Mouse button double-click event.
Definition spk_mouse_event.hpp:38
Mouse move event carrying current position.
Definition spk_mouse_event.hpp:50
Mouse button press event.
Definition spk_mouse_event.hpp:14
Mouse button release event.
Definition spk_mouse_event.hpp:26
Mouse wheel scroll event.
Definition spk_mouse_event.hpp:62
Reports a window move event.
Definition spk_system_event.hpp:50
Event emitted when a drawable region needs repainting.
Definition spk_paint_event.hpp:19
Signals application quit.
Definition spk_system_event.hpp:42
Reports a window/client-area resize.
Definition spk_system_event.hpp:24
Carries per-frame update timing and input state snapshot.
Definition spk_update_event.hpp:15