Nameless Engine
Loading...
Searching...
No Matches
Node.h
1#pragma once
2
3// Standard.
4#include <vector>
5#include <memory>
6#include <mutex>
7#include <atomic>
8#include <unordered_map>
9
10// Custom.
11#include "io/Serializable.h"
12#include "input/KeyboardKey.hpp"
13#include "gccontainers/GcVector.hpp"
14#include "game/node/callback/NodeNotificationBroadcaster.hpp"
15
16// External.
17#include "GcPtr.h"
18
19#include "Node.generated.h"
20
21namespace ne RNAMESPACE() {
22 class GameInstance;
23 class World;
24 class Timer;
25
33 enum class TickGroup { FIRST, SECOND };
34
39 class RCLASS(Guid("2a721c37-3c22-450c-8dad-7b6985cbbd61")) Node : public Serializable {
40 // GameManager will propagate functions to all nodes in the world such as `onBeforeNewFrame`.
41 friend class GameManager;
42
43 // World is able to spawn root node.
44 friend class World;
45
46 public:
51 enum class AttachmentRule {
52 RESET_RELATIVE, //< After the new child node was attached, resets its relative location
53 //< or rotation to 0 and relative scale to 1.
54 KEEP_RELATIVE, //< After the new child node was attached, its relative location/rotation/scale
55 //< will stay the same, but world location/rotation/scale might change.
56 KEEP_WORLD, //< After the new child node was attached, its relative
57 //< location/rotation/scale will be recalculated so that its
58 //< world location/rotation/scale will stay the same (as before attached).
59 };
60
66 static size_t getAliveNodeCount();
67
71 Node();
72
78 Node(const std::string& sName);
79
80 Node(const Node&) = delete;
81 Node& operator=(const Node&) = delete;
82 Node(Node&&) = delete;
83 Node& operator=(Node&&) = delete;
84
86 virtual ~Node() override;
87
96 static std::variant<sgc::GcPtr<Node>, Error>
97 deserializeNodeTree(const std::filesystem::path& pathToFile);
98
104 void setNodeName(const std::string& sName);
105
116 void detachFromParentAndDespawn();
117
140 void addChildNode(
141 const sgc::GcPtr<Node>& pNode,
142 AttachmentRule locationRule = AttachmentRule::KEEP_WORLD,
143 AttachmentRule rotationRule = AttachmentRule::KEEP_WORLD,
144 AttachmentRule scaleRule = AttachmentRule::KEEP_WORLD);
145
151 void setSerialize(bool bSerialize);
152
172 [[nodiscard]] std::optional<Error>
173 serializeNodeTree(const std::filesystem::path& pathToFile, bool bEnableBackup);
174
180 std::string getNodeName() const;
181
188 sgc::GcPtr<Node> getWorldRootNode();
189
204 std::pair<std::recursive_mutex, sgc::GcPtr<Node>>* getParentNode();
205
219 std::pair<std::recursive_mutex, sgc::GcVector<sgc::GcPtr<Node>>>* getChildNodes();
220
235 template <typename NodeType>
236 requires std::derived_from<NodeType, Node>
237 sgc::GcPtr<NodeType> getParentNodeOfType(const std::string& sParentNodeName = "");
238
253 template <typename NodeType>
254 requires std::derived_from<NodeType, Node>
255 sgc::GcPtr<NodeType> getChildNodeOfType(const std::string& sChildNodeName = "");
256
262 static GameInstance* getGameInstance();
263
269 TickGroup getTickGroup() const;
270
278 std::optional<size_t> getNodeId() const;
279
285 bool isCalledEveryFrame();
286
292 bool isReceivingInput();
293
299 bool isSpawned();
300
309 bool isParentOf(Node* pNode);
310
319 bool isChildOf(Node* pNode);
320
327 bool isSerialized() const;
328
329 protected:
338 void setIsCalledEveryFrame(bool bEnable);
339
359 void setTickGroup(TickGroup tickGroup);
360
372 void setIsReceivingInput(bool bEnable);
373
399 Timer* createTimer(const std::string& sTimerName);
400
431 template <typename FunctionType>
433 std::scoped_lock guard(mtxIsSpawned.first, mtxCreatedBroadcasters.first);
434
435 // Create broadcaster.
436 auto pNewBroadcaster = std::unique_ptr<NodeNotificationBroadcaster<FunctionType>>(
438 const auto pRawBroadcaster = pNewBroadcaster.get();
439
440 // Add to our array.
441 mtxCreatedBroadcasters.second.push_back(std::move(pNewBroadcaster));
442
443 if (mtxIsSpawned.second) {
444 // Get node ID.
445 if (!iNodeId.has_value()) [[unlikely]] {
446 Error error(std::format(
447 "node \"{}\" created a new broadcaster while being spawned but node's ID is empty",
448 sNodeName));
449 error.showError();
450 throw std::runtime_error(error.getFullErrorMessage());
451 }
452
453 // Notify broadcaster about node being spawned.
454 pRawBroadcaster->onOwnerNodeSpawning(this);
455 }
456
457 return pRawBroadcaster;
458 }
459
482 std::pair<
483 std::recursive_mutex,
484 std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, bool)>>>*
485 getActionEventBindings();
486
511 std::pair<
512 std::recursive_mutex,
513 std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, float)>>>*
514 getAxisEventBindings();
515
523 std::recursive_mutex* getSpawnDespawnMutex();
524
536 virtual void onMouseMove(double xOffset, double yOffset) {}
537
546 virtual void onMouseScrollMove(int iOffset) {}
547
560 virtual void onBeforeNewFrame(float timeSincePrevFrameInSec) {}
561
576 virtual void onSpawning() {}
577
589 virtual void onChildNodesSpawned() {}
590
602 virtual void onDespawning() {}
603
620 virtual void onBeforeDetachedFromParent(bool bThisNodeBeingDetached) {}
621
635 virtual void onAfterAttachedToNewParent(bool bThisNodeBeingAttached) {}
636
637 private:
652 Serializable* pObject,
653 const std::string& sObjectUniqueId,
654 const std::unordered_map<std::string, std::string>& customAttributes = {},
655 Serializable* pOriginalObject = nullptr,
656 sgc::GcPtr<Node> pDeserializedOriginalObject = nullptr)
657 : SerializableObjectInformation(pObject, sObjectUniqueId, customAttributes, pOriginalObject) {
658 this->pDeserializedOriginalObject = pDeserializedOriginalObject;
659 }
660
662 sgc::GcPtr<Node> pDeserializedOriginalObject = nullptr;
663 };
664
675 bool enableTimer(Timer* pTimer, bool bEnable);
676
688 void onInputActionEvent(unsigned int iActionId, KeyboardModifiers modifiers, bool bIsPressedDown);
689
701 void onInputAxisEvent(unsigned int iAxisEventId, KeyboardModifiers modifiers, float input);
702
704 void spawn();
705
707 void despawn();
708
715 void notifyAboutAttachedToNewParent(bool bThisNodeBeingAttached);
716
723 void notifyAboutDetachingFromParent(bool bThisNodeBeingDetached);
724
732 World* findValidWorld();
733
744 std::variant<std::vector<SerializableObjectInformationWithGcPointer>, Error>
745 getInformationForSerialization(size_t& iId, std::optional<size_t> iParentId);
746
757 bool isTreeDeserializedFromOneFile(const std::string& sPathRelativeToRes);
758
767 void lockChildren();
768
775 void unlockChildren();
776
778 RPROPERTY(Serialize)
779 std::string sNodeName;
780
782 std::pair<std::recursive_mutex, sgc::GcVector<sgc::GcPtr<Node>>> mtxChildNodes;
783
785 std::pair<std::recursive_mutex, sgc::GcPtr<Node>> mtxParentNode;
786
788 std::pair<
789 std::recursive_mutex,
790 std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, bool)>>>
791 mtxBindedActionEvents;
792
794 std::pair<
795 std::recursive_mutex,
796 std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, float)>>>
797 mtxBindedAxisEvents;
798
809 std::pair<std::recursive_mutex, std::vector<std::unique_ptr<Timer>>> mtxCreatedTimers;
810
819 std::pair<std::recursive_mutex, std::vector<std::unique_ptr<NodeNotificationBroadcasterBase>>>
820 mtxCreatedBroadcasters;
821
823 std::pair<std::recursive_mutex, bool> mtxIsSpawned;
824
826 std::pair<std::recursive_mutex, bool> mtxIsCalledEveryFrame;
827
832 std::pair<std::recursive_mutex, bool> mtxIsReceivingInput;
833
839 World* pWorld = nullptr;
840
842 TickGroup tickGroup = TickGroup::FIRST;
843
845 std::optional<size_t> iNodeId;
846
851 bool bSerialize = true;
852
854 static inline const auto sParentNodeIdAttributeName = "parent_node_id";
855
857 static inline const auto sExternalNodeTreePathAttributeName =
858 "external_node_tree_path_relative_to_res";
859
860 ne_Node_GENERATED
861 };
862
863 template <typename NodeType>
864 requires std::derived_from<NodeType, Node>
865 sgc::GcPtr<NodeType> Node::getParentNodeOfType(const std::string& sParentNodeName) {
866 std::scoped_lock guard(mtxParentNode.first);
867
868 // Check if have a parent.
869 if (mtxParentNode.second == nullptr) {
870 return nullptr;
871 }
872
873 // Check parent's type and optionally name.
874 sgc::GcPtr<NodeType> pCastedParentNode = dynamic_cast<NodeType*>(mtxParentNode.second.get());
875 if (pCastedParentNode != nullptr &&
876 (sParentNodeName.empty() || mtxParentNode.second->getNodeName() == sParentNodeName)) {
877 // Found the node.
878 return pCastedParentNode;
879 }
880
881 // Ask parent nodes of that node.
882 return mtxParentNode.second->getParentNodeOfType<NodeType>(sParentNodeName);
883 }
884
885 template <typename NodeType>
886 requires std::derived_from<NodeType, Node>
887 sgc::GcPtr<NodeType> Node::getChildNodeOfType(const std::string& sChildNodeName) {
888 std::scoped_lock guard(mtxChildNodes.first);
889
890 // Iterate over child nodes.
891 for (auto& pChildNode : mtxChildNodes.second) {
892 // Check if this is the node we are looking for.
893 sgc::GcPtr<NodeType> pCastedChildNode = dynamic_cast<NodeType*>(pChildNode.get());
894 if (pCastedChildNode != nullptr &&
895 (sChildNodeName.empty() || pChildNode->getNodeName() == sChildNodeName)) {
896 // Found the node.
897 return pCastedChildNode;
898 }
899
900 // Ask child nodes of that node.
901 const auto pNode = pChildNode->getChildNodeOfType<NodeType>(sChildNodeName);
902 if (pNode == nullptr) {
903 // Check the next child node.
904 continue;
905 }
906
907 // Found the node.
908 return pNode;
909 }
910
911 return nullptr;
912 }
913} // namespace ne RNAMESPACE()
914
915File_Node_GENERATED
Definition: Error.h:27
std::string getFullErrorMessage() const
Definition: Error.cpp:84
void showError() const
Definition: Error.cpp:102
Definition: GameInstance.h:32
Definition: GameManager.h:34
Definition: GuidProperty.h:30
Definition: KeyboardKey.hpp:10
Definition: NodeNotificationBroadcaster.hpp:16
Definition: NodeNotificationBroadcaster.hpp:45
Definition: Node.h:39
AttachmentRule
Definition: Node.h:51
virtual void onBeforeDetachedFromParent(bool bThisNodeBeingDetached)
Definition: Node.h:620
virtual void onMouseMove(double xOffset, double yOffset)
Definition: Node.h:536
NodeNotificationBroadcaster< FunctionType > * createNotificationBroadcaster()
Definition: Node.h:432
virtual void onBeforeNewFrame(float timeSincePrevFrameInSec)
Definition: Node.h:560
virtual void onChildNodesSpawned()
Definition: Node.h:589
virtual void onDespawning()
Definition: Node.h:602
virtual void onAfterAttachedToNewParent(bool bThisNodeBeingAttached)
Definition: Node.h:635
virtual void onSpawning()
Definition: Node.h:576
virtual void onMouseScrollMove(int iOffset)
Definition: Node.h:546
Definition: Serializable.h:113
Definition: SerializeProperty.h:42
Definition: Timer.h:13
Definition: World.h:43
SerializableObjectInformationWithGcPointer(Serializable *pObject, const std::string &sObjectUniqueId, const std::unordered_map< std::string, std::string > &customAttributes={}, Serializable *pOriginalObject=nullptr, sgc::GcPtr< Node > pDeserializedOriginalObject=nullptr)
Definition: Node.h:651
Definition: Serializable.h:31