Nameless Engine
Loading...
Searching...
No Matches
ne::Node Class Reference

#include <Node.h>

Inheritance diagram for ne::Node:
ne::Serializable ne::EnvironmentNode ne::SpatialNode ne::CameraNode ne::DirectionalLightNode ne::MeshNode ne::PointLightNode ne::SpotlightNode ne::EditorCameraNode

Classes

struct  SerializableObjectInformationWithGcPointer
 

Public Types

enum class  AttachmentRule { RESET_RELATIVE , KEEP_RELATIVE , KEEP_WORLD }
 

Public Member Functions

 Node ()
 
 Node (const std::string &sName)
 
 Node (const Node &)=delete
 
Nodeoperator= (const Node &)=delete
 
 Node (Node &&)=delete
 
Nodeoperator= (Node &&)=delete
 
virtual ~Node () override
 
void setNodeName (const std::string &sName)
 
void detachFromParentAndDespawn ()
 
void addChildNode (const sgc::GcPtr< Node > &pNode, AttachmentRule locationRule=AttachmentRule::KEEP_WORLD, AttachmentRule rotationRule=AttachmentRule::KEEP_WORLD, AttachmentRule scaleRule=AttachmentRule::KEEP_WORLD)
 
void setSerialize (bool bSerialize)
 
std::optional< ErrorserializeNodeTree (const std::filesystem::path &pathToFile, bool bEnableBackup)
 
std::string getNodeName () const
 
sgc::GcPtr< NodegetWorldRootNode ()
 
std::pair< std::recursive_mutex, sgc::GcPtr< Node > > * getParentNode ()
 
std::pair< std::recursive_mutex, sgc::GcVector< sgc::GcPtr< Node > > > * getChildNodes ()
 
template<typename NodeType >
requires std::derived_from<NodeType, Node>
sgc::GcPtr< NodeType > getParentNodeOfType (const std::string &sParentNodeName="")
 
template<typename NodeType >
requires std::derived_from<NodeType, Node>
sgc::GcPtr< NodeType > getChildNodeOfType (const std::string &sChildNodeName="")
 
TickGroup getTickGroup () const
 
std::optional< size_t > getNodeId () const
 
bool isCalledEveryFrame ()
 
bool isReceivingInput ()
 
bool isSpawned ()
 
bool isParentOf (Node *pNode)
 
bool isChildOf (Node *pNode)
 
bool isSerialized () const
 
- Public Member Functions inherited from ne::Serializable
std::optional< Errorserialize (std::filesystem::path pathToFile, bool bEnableBackup, const std::unordered_map< std::string, std::string > &customAttributes={})
 
std::variant< std::string, Errorserialize (toml::value &tomlData, const std::string &sEntityId="", const std::unordered_map< std::string, std::string > &customAttributes={}, const std::optional< std::filesystem::path > &optionalPathToFile={}, bool bEnableBackup=false)
 
std::variant< std::string, Errorserialize (toml::value &tomlData, Serializable *pOriginalObject, std::string sEntityId="", const std::unordered_map< std::string, std::string > &customAttributes={}, const std::optional< std::filesystem::path > &optionalPathToFile={}, bool bEnableBackup=false)
 
std::optional< std::pair< std::string, std::string > > getPathDeserializedFromRelativeToRes () const
 

Static Public Member Functions

static size_t getAliveNodeCount ()
 
static std::variant< sgc::GcPtr< Node >, ErrordeserializeNodeTree (const std::filesystem::path &pathToFile)
 
static GameInstancegetGameInstance ()
 
- Static Public Member Functions inherited from ne::Serializable
static std::optional< ErrorserializeMultiple (std::filesystem::path pathToFile, std::vector< SerializableObjectInformation > vObjects, bool bEnableBackup)
 
static std::variant< std::set< std::string >, ErrorgetIdsFromFile (std::filesystem::path pathToFile)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::derived_from<InnerType, Serializable> && (std::same_as<SmartPointer, sgc::GcPtr<InnerType>> || std::same_as<SmartPointer, std::unique_ptr<InnerType>>)
static std::variant< SmartPointer, Errordeserialize (const std::filesystem::path &pathToFile)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::derived_from<InnerType, Serializable> && (std::same_as<SmartPointer, sgc::GcPtr<InnerType>> || std::same_as<SmartPointer, std::unique_ptr<InnerType>>)
static std::variant< SmartPointer, Errordeserialize (const std::filesystem::path &pathToFile, std::unordered_map< std::string, std::string > &customAttributes)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::derived_from<InnerType, Serializable> && (std::same_as<SmartPointer, sgc::GcPtr<InnerType>> || std::same_as<SmartPointer, std::unique_ptr<InnerType>>)
static std::variant< SmartPointer, Errordeserialize (std::filesystem::path pathToFile, std::unordered_map< std::string, std::string > &customAttributes, const std::string &sEntityId)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::derived_from<InnerType, Serializable> && (std::same_as<SmartPointer, sgc::GcPtr<InnerType>> || std::same_as<SmartPointer, std::unique_ptr<InnerType>>)
static std::variant< SmartPointer, Errordeserialize (const std::filesystem::path &pathToFile, const std::string &sEntityId)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::same_as<SmartPointer, sgc::GcPtr<Serializable>> || std::same_as<SmartPointer, std::unique_ptr<Serializable>>
static std::variant< std::vector< DeserializedObjectInformation< SmartPointer > >, ErrordeserializeMultiple (std::filesystem::path pathToFile, const std::set< std::string > &ids)
 
template<typename SmartPointer , typename InnerType = typename SmartPointer::element_type>
requires std::derived_from<InnerType, Serializable> && (std::same_as<SmartPointer, sgc::GcPtr<InnerType>> || std::same_as<SmartPointer, std::unique_ptr<InnerType>>)
static std::variant< SmartPointer, Errordeserialize (const toml::value &tomlData, std::unordered_map< std::string, std::string > &customAttributes, std::string sEntityId="", std::optional< std::filesystem::path > optionalPathToFile={})
 

Protected Member Functions

void setIsCalledEveryFrame (bool bEnable)
 
void setTickGroup (TickGroup tickGroup)
 
void setIsReceivingInput (bool bEnable)
 
TimercreateTimer (const std::string &sTimerName)
 
template<typename FunctionType >
NodeNotificationBroadcaster< FunctionType > * createNotificationBroadcaster ()
 
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, bool)> > > * getActionEventBindings ()
 
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, float)> > > * getAxisEventBindings ()
 
std::recursive_mutex * getSpawnDespawnMutex ()
 
virtual void onMouseMove (double xOffset, double yOffset)
 
virtual void onMouseScrollMove (int iOffset)
 
virtual void onBeforeNewFrame (float timeSincePrevFrameInSec)
 
virtual void onSpawning ()
 
virtual void onChildNodesSpawned ()
 
virtual void onDespawning ()
 
virtual void onBeforeDetachedFromParent (bool bThisNodeBeingDetached)
 
virtual void onAfterAttachedToNewParent (bool bThisNodeBeingAttached)
 
- Protected Member Functions inherited from ne::Serializable
virtual void onAfterDeserialized ()
 

Private Member Functions

bool enableTimer (Timer *pTimer, bool bEnable)
 
void onInputActionEvent (unsigned int iActionId, KeyboardModifiers modifiers, bool bIsPressedDown)
 
void onInputAxisEvent (unsigned int iAxisEventId, KeyboardModifiers modifiers, float input)
 
void spawn ()
 
void despawn ()
 
void notifyAboutAttachedToNewParent (bool bThisNodeBeingAttached)
 
void notifyAboutDetachingFromParent (bool bThisNodeBeingDetached)
 
WorldfindValidWorld ()
 
std::variant< std::vector< SerializableObjectInformationWithGcPointer >, ErrorgetInformationForSerialization (size_t &iId, std::optional< size_t > iParentId)
 
bool isTreeDeserializedFromOneFile (const std::string &sPathRelativeToRes)
 
void lockChildren ()
 
void unlockChildren ()
 

Private Attributes

std::string sNodeName
 
std::pair< std::recursive_mutex, sgc::GcVector< sgc::GcPtr< Node > > > mtxChildNodes
 
std::pair< std::recursive_mutex, sgc::GcPtr< Node > > mtxParentNode
 
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, bool)> > > mtxBindedActionEvents
 
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, float)> > > mtxBindedAxisEvents
 
std::pair< std::recursive_mutex, std::vector< std::unique_ptr< Timer > > > mtxCreatedTimers
 
std::pair< std::recursive_mutex, std::vector< std::unique_ptr< NodeNotificationBroadcasterBase > > > mtxCreatedBroadcasters
 
std::pair< std::recursive_mutex, bool > mtxIsSpawned
 
std::pair< std::recursive_mutex, bool > mtxIsCalledEveryFrame
 
std::pair< std::recursive_mutex, bool > mtxIsReceivingInput
 
WorldpWorld = nullptr
 
TickGroup tickGroup = TickGroup::FIRST
 
std::optional< size_t > iNodeId
 
bool bSerialize = true
 

Static Private Attributes

static const auto sParentNodeIdAttributeName = "parent_node_id"
 
static const auto sExternalNodeTreePathAttributeName
 

Friends

class GameManager
 
class World
 

Detailed Description

Base class for nodes, allows being spawned in the world, attaching child nodes or being attached to some parent node.

Member Enumeration Documentation

◆ AttachmentRule

enum class ne::Node::AttachmentRule
strong

Defines how location, rotation or scale of a node being attached as a child node should change after the attachment process (after onAfterAttachedToNewParent was called).

Constructor & Destructor Documentation

◆ Node() [1/2]

ne::Node::Node ( )

Creates a new node with a default name.

◆ Node() [2/2]

ne::Node::Node ( const std::string &  sName)

Creates a new node with the specified name.

Parameters
sNameName of this node.

◆ ~Node()

ne::Node::~Node ( )
overridevirtual

Logs destruction in debug builds.

Member Function Documentation

◆ addChildNode()

void ne::Node::addChildNode ( const sgc::GcPtr< Node > &  pNode,
AttachmentRule  locationRule = AttachmentRule::KEEP_WORLD,
AttachmentRule  rotationRule = AttachmentRule::KEEP_WORLD,
AttachmentRule  scaleRule = AttachmentRule::KEEP_WORLD 
)

Attaches a node as a child of this node.

Remarks
If the specified node already has a parent it will change its parent to be a child of this node. This way you can change to which node you are attached.
If the specified node needs to be spawned it will queue a deferred task to be added to the World on next frame so input events and onBeforeNewFrame (if enabled) will be called only starting from the next frame.
Parameters
pNodeNode to attach as a child. If the specified node is a parent of this node the operation will fail and log an error.
locationRuleOnly applied if the child node is a SpatialNode, otherwise ignored. Defines how child node's location should change after the attachment process (after onAfterAttachedToNewParent was called)
rotationRuleOnly applied if the child node is a SpatialNode, otherwise ignored. Defines how child node's rotation should change after the attachment process (after onAfterAttachedToNewParent was called)
scaleRuleOnly applied if the child node is a SpatialNode, otherwise ignored. Defines how child node's scale should change after the attachment process (after onAfterAttachedToNewParent was called)

◆ createNotificationBroadcaster()

template<typename FunctionType >
NodeNotificationBroadcaster< FunctionType > * ne::Node::createNotificationBroadcaster ( )
inlineprotected

Creates a new notification broadcaster that only accepts callbacks of the specified type.

Example:

// inside of your Node derived class:
auto pBroadcaster = createNotificationBroadcaster<void(bool)>();
// save broadcaster pointer somewhere
// ...
// Subscribe.
pBroadcaster->subscribe(NodeFunction<void(bool)>(getNodeId().value(), [](bool bParameter){
// callback logic ...
});
// Notify.
pBroadcaster->broadcast(true);
Definition: NodeFunction.hpp:11
std::optional< size_t > getNodeId() const
Definition: Node.cpp:1012
Warning
Do not free (delete) returned pointer.
Do not use returned pointer outside of this node object as the broadcaster is only guaranteed to live while the node (that created the broadcaster) is living.
Remarks
Note that although you can create broadcasters while the node is despawned or was not spawned yet any attempt to broadcast the notification will be ignored and will do nothing.
Returns
A non-owning pointer to the created broadcaster that is guaranteed to be valid while this node object is alive (i.e. even valid when despawned).

◆ createTimer()

Timer * ne::Node::createTimer ( const std::string &  sTimerName)
protected

Creates a new timer and saves it inside of this node to be used while the node is spawned.

Warning
Do not free (delete) returned pointer.
Do not use returned pointer outside of this node object as the timer is only guaranteed to live while the node (that created the timer) is living.
Remarks
Note that although you can create timers while the node is despawned or was not spawned yet any attempt to start a timer while the node is despawned (or not spawned yet) will result in an error being logged.
This function exists to add some protection code to not shoot yourself in the foot, such as: Node will automatically stop and disable created timers before onDespawning is called by using Timer::stop(true) so that you don't have to remember to stop created timers. Moreover, if you are using a callback function for the timer's timeout event it's guaranteed that this callback function will only be called while the node is spawned.
There is no removeTimer function but it may appear in the future (although there's really no point in removing a timer so don't care about it).
Parameters
sTimerNameName of this timer (used for logging). Don't add "timer" word to your timer's name as it will be appended in the logs.
Returns
nullptr if something went wrong, otherwise a non-owning pointer to the created timer that is guaranteed to be valid while this node object is alive (i.e. even valid when despawned).

◆ deserializeNodeTree()

std::variant< sgc::GcPtr< Node >, Error > ne::Node::deserializeNodeTree ( const std::filesystem::path &  pathToFile)
static

Deserializes a node and all its child nodes (hierarchy information) from a file.

Parameters
pathToFileFile to read a node tree from. The ".toml" extension will be added automatically if not specified in the path.
Returns
Error if something went wrong, otherwise pointer to the root node.

◆ despawn()

void ne::Node::despawn ( )
private

Calls onDespawning on this node and all of its child nodes.

◆ detachFromParentAndDespawn()

void ne::Node::detachFromParentAndDespawn ( )

Detaches this node from the parent and optionally despawns this node and all of its child nodes if the node was spawned.

Remarks
This function is usually used to mark node (tree) as "to be destroyed", if you just want to change node's parent consider using addChildNode.
The node and its child nodes are not guaranteed to be deleted after this function is finished. Deletion is handled automatically by gc pointers.

◆ enableTimer()

bool ne::Node::enableTimer ( Timer pTimer,
bool  bEnable 
)
private

Enables the specified timer and sets a callback validator or stops and disables the timer.

Remarks
Does nothing if the timer is already in the requested state.
Parameters
pTimerTimer to enable/disable.
bEnableNew timer state to set.
Returns
false if successful, true otherwise.

◆ findValidWorld()

World * ne::Node::findValidWorld ( )
private

Checks if this node has a valid world pointer and if not asks this node's parent and goes up the node hierarchy up to the root node if needed to find valid pointer to world.

Returns
World.

◆ getActionEventBindings()

std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, bool)> > > * ne::Node::getActionEventBindings ( )
protected

Returns map of action events that this node is binded to (must be used with mutex). Binded callbacks will be automatically called when an action event is triggered.

Remarks
Input events will be only triggered if the node is spawned.
Input events will not be called if setIsReceivingInput was not enabled.
Only events in GameInstance's InputManager (GameInstance::getInputManager) will be considered to trigger events in the node.

Example:

const auto iForwardActionId = 0;
const auto pActionEvents = getActionEventBindings();
std::scoped_lock guard(pActionEvents->first);
pActionEvents->second[iForwardActionId] = [&](KeyboardModifiers modifiers, bool bIsPressedDown) {
moveForward(modifiers, bIsPressedDown);
};
Definition: KeyboardKey.hpp:10
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, bool)> > > * getActionEventBindings()
Definition: Node.cpp:919
Returns
Binded action events.

◆ getAliveNodeCount()

size_t ne::Node::getAliveNodeCount ( )
static

Returns the total amount of currently alive (allocated) nodes.

Returns
Number of alive nodes right now.

◆ getAxisEventBindings()

std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, float)> > > * ne::Node::getAxisEventBindings ( )
protected

Returns map of axis events that this node is binded to (must be used with mutex). Binded callbacks will be automatically called when an axis event is triggered.

Remarks
Input events will be only triggered if the node is spawned.
Input events will not be called if setIsReceivingInput was not enabled.
Only events in GameInstance's InputManager (GameInstance::getInputManager) will be considered to trigger events in the node.

Example:

const auto iForwardAxisEventId = 0;
const auto pAxisEvents = getAxisEventBindings();
std::scoped_lock guard(pAxisEvents->first);
pAxisEvents->second[iForwardAxisEventId] = [&](KeyboardModifiers modifiers, float input) {
moveForward(modifiers, input);
};
std::pair< std::recursive_mutex, std::unordered_map< unsigned int, std::function< void(KeyboardModifiers, float)> > > * getAxisEventBindings()
Definition: Node.cpp:926
Remarks
Input parameter is a value in range [-1.0f; 1.0f] that describes input.
Returns
Binded action events.

◆ getChildNodeOfType()

template<typename NodeType >
requires std::derived_from<NodeType, Node>
sgc::GcPtr< NodeType > ne::Node::getChildNodeOfType ( const std::string &  sChildNodeName = "")

Goes down the child node chain to find a first node that matches the specified node type and optionally node name.

Template parameter NodeType specifies node type to look for. Note that this means that we will use dynamic_cast to determine whether the node matches the specified type or not. So if you are looking for a node with the type Node this means that every node will match the type.

Parameters
sChildNodeNameIf not empty, nodes that match the specified node type will also be checked to see if their name exactly matches the specified name.
Returns
nullptr if not found, otherwise a valid pointer to the node.

◆ getChildNodes()

std::pair< std::recursive_mutex, sgc::GcVector< sgc::GcPtr< Node > > > * ne::Node::getChildNodes ( )

Returns pointer to child nodes array.

Warning
Must be used with mutex.
Avoid saving returned raw pointer as it points to the node's field and does not guarantee that the node will always live while you hold this pointer. Returning raw pointer in order to avoid creating GC pointers (if you for example only want to iterate over child nodes there's no point in returning GC vector), but you can always save returned GC vector or GC pointers to child nodes if you need.
Returns
Array of child nodes.

◆ getGameInstance()

GameInstance * ne::Node::getGameInstance ( )
static

Returns last created game instance.

Returns
Game instance.

◆ getInformationForSerialization()

std::variant< std::vector< Node::SerializableObjectInformationWithGcPointer >, Error > ne::Node::getInformationForSerialization ( size_t &  iId,
std::optional< size_t >  iParentId 
)
private

Collects and returns information for serialization for self and all child nodes.

Parameters
iIdID for serialization to use (will be incremented).
iParentIdParent's serialization ID (if this node has a parent and it will also be serialized).
Returns
Error if something went wrong, otherwise an array of collected information that can be serialized.

◆ getNodeId()

std::optional< size_t > ne::Node::getNodeId ( ) const

Returns a unique ID of the node.

Remarks
Each spawn gives the node a new ID.
Returns
Empty if this node was never spawned, otherwise unique ID of this node.

◆ getNodeName()

std::string ne::Node::getNodeName ( ) const

Returns node's name.

Returns
Node name.

◆ getParentNode()

std::pair< std::recursive_mutex, sgc::GcPtr< Node > > * ne::Node::getParentNode ( )

Returns parent node if this node.

Warning
Must be used with mutex.
Avoid saving returned raw pointer as it points to the node's field and does not guarantee that the node will always live while you hold this pointer. Returning raw pointer in order to avoid creating GC pointers (if you for example only want to check the parent node there's no point in returning a gc pointer), but you can always save returned GC pointer to node's parent if you need.
Returns
nullptr as a gc pointer (second value in the pair) if this node has no parent (could only happen when the node is not spawned), otherwise valid gc pointer.

◆ getParentNodeOfType()

template<typename NodeType >
requires std::derived_from<NodeType, Node>
sgc::GcPtr< NodeType > ne::Node::getParentNodeOfType ( const std::string &  sParentNodeName = "")

Goes up the parent node chain (up to the world's root node if needed) to find a first node that matches the specified node type and optionally node name.

Template parameter NodeType specifies node type to look for. Note that this means that we will use dynamic_cast to determine whether the node matches the specified type or not. So if you are looking for a node with the type Node this means that every node will match the type.

Parameters
sParentNodeNameIf not empty, nodes that match the specified node type will also be checked to see if their name exactly matches the specified name.
Returns
nullptr if not found, otherwise a valid pointer to the node.

◆ getSpawnDespawnMutex()

std::recursive_mutex * ne::Node::getSpawnDespawnMutex ( )
protected

Returns mutex that is generally used to protect/prevent spawning/despawning.

Remarks
Do not delete (free) returned pointer.
Returns
Mutex.

◆ getTickGroup()

TickGroup ne::Node::getTickGroup ( ) const

Returns the tick group this node resides in.

Returns
Tick group the node is using.

◆ getWorldRootNode()

sgc::GcPtr< Node > ne::Node::getWorldRootNode ( )

Returns world's root node.

Returns
nullptr if this node is not spawned or was despawned or world is being destroyed (always check returned pointer before doing something), otherwise valid pointer.

◆ isCalledEveryFrame()

bool ne::Node::isCalledEveryFrame ( )

Returns whether the onBeforeNewFrame should be called each frame or not.

Returns
Whether the onBeforeNewFrame should be called each frame or not.

◆ isChildOf()

bool ne::Node::isChildOf ( Node pNode)

Checks if the specified node is a parent of this node (somewhere in the parent hierarchy, not only as a direct parent node).

Parameters
pNodeNode to check.
Returns
true if the specified node was found as a parent of this node, false otherwise.

◆ isParentOf()

bool ne::Node::isParentOf ( Node pNode)

Checks if the specified node is a child of this node (somewhere in the child hierarchy, not only as a direct child node).

Parameters
pNodeNode to check.
Returns
true if the specified node was found as a child of this node, false otherwise.

◆ isReceivingInput()

bool ne::Node::isReceivingInput ( )

Returns whether this node receives input or not.

Returns
Whether this node receives input or not.

◆ isSerialized()

bool ne::Node::isSerialized ( ) const

Tells whether or not this node (and node's child nodes) will be serialized as part of a node tree.

Returns
false if this node and its child nodes will be ignored when being serialized as part of a node tree, true otherwise.

◆ isSpawned()

bool ne::Node::isSpawned ( )

Returns whether this node is spawned in the world or not.

Returns
Whether this node is spawned in the world or not.

◆ isTreeDeserializedFromOneFile()

bool ne::Node::isTreeDeserializedFromOneFile ( const std::string &  sPathRelativeToRes)
private

Checks if this node and all child nodes were deserialized from the same file (i.e. checks if this node tree is located in one file).

Parameters
sPathRelativeToResPath relative to the res directory to the file to check, example: game/test.toml.
Returns
false if this node or some child node(s) were deserialized from other file or if some nodes we not deserialized previously, otherwise true.

◆ lockChildren()

void ne::Node::lockChildren ( )
private

Locks mtxChildNodes mutex for self and recursively for all children.

After a node with children was locked this makes the whole node tree to be frozen (hierarchy can't be changed).

Use unlockChildren for unlocking the tree.

◆ notifyAboutAttachedToNewParent()

void ne::Node::notifyAboutAttachedToNewParent ( bool  bThisNodeBeingAttached)
private

Calls onAfterAttachedToNewParent on this node and all of its child nodes.

Parameters
bThisNodeBeingAttachedtrue if this node was attached to a parent, false if some node in the parent hierarchy was attached to a parent.

◆ notifyAboutDetachingFromParent()

void ne::Node::notifyAboutDetachingFromParent ( bool  bThisNodeBeingDetached)
private

Calls onBeforeDetachedFromParent on this node and all of its child nodes.

Parameters
bThisNodeBeingDetachedtrue if this node is being detached from its parent, false if some node in the parent hierarchy is being detached from its parent.

◆ onAfterAttachedToNewParent()

virtual void ne::Node::onAfterAttachedToNewParent ( bool  bThisNodeBeingAttached)
inlineprotectedvirtual

Called after this node or one of the node's parents (in the parent hierarchy) was attached to a new parent node.

Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic.
Remarks
This function will also be called on all child nodes after this function is finished.
Parameters
bThisNodeBeingAttachedtrue if this node was attached to a parent, false if some node in the parent hierarchy was attached to a parent.

Reimplemented in ne::EditorCameraNode, and ne::SpatialNode.

◆ onBeforeDetachedFromParent()

virtual void ne::Node::onBeforeDetachedFromParent ( bool  bThisNodeBeingDetached)
inlineprotectedvirtual

Called before this node or one of the node's parents (in the parent hierarchy) is about to be detached from the current parent node.

Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic.
Remarks
If this node is being detached from its parent getParentNode will return nullptr after this function is finished.
This function will also be called on all child nodes after this function is finished.
Parameters
bThisNodeBeingDetachedtrue if this node is being detached from its parent, false if some node in the parent hierarchy is being detached from its parent.

◆ onBeforeNewFrame()

virtual void ne::Node::onBeforeNewFrame ( float  timeSincePrevFrameInSec)
inlineprotectedvirtual

Called before a new frame is rendered.

Remarks
This function is disabled by default, use setIsCalledEveryFrame to enable it.
This function will only be called while this node is spawned.
Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic (if there is any).
Parameters
timeSincePrevFrameInSecAlso known as deltatime - time in seconds that has passed since the last frame was rendered.

Reimplemented in ne::EditorCameraNode.

◆ onChildNodesSpawned()

virtual void ne::Node::onChildNodesSpawned ( )
inlineprotectedvirtual

Called after onSpawning when this node and all of node's child nodes (at the moment of spawning) were spawned.

Remarks
Generally you might want to prefer to use onSpawning, this function is mostly used to do some logic related to child nodes after all child nodes were spawned (for example if you have a camera child node you can make it active in this function).
Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic.

◆ onDespawning()

virtual void ne::Node::onDespawning ( )
inlineprotectedvirtual

Called before this node is despawned from the world to execute custom despawn logic.

Remarks
This node will be marked as despawned after this function is called.
This function is called after all child nodes were despawned.
getSpawnDespawnMutex is locked while this function is called.
Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic.

Reimplemented in ne::CameraNode, ne::EnvironmentNode, ne::DirectionalLightNode, ne::PointLightNode, ne::SpotlightNode, and ne::MeshNode.

◆ onInputActionEvent()

void ne::Node::onInputActionEvent ( unsigned int  iActionId,
KeyboardModifiers  modifiers,
bool  bIsPressedDown 
)
private

Called when a window that owns this game instance receives user input and the input key exists as an action event in the InputManager.

Remarks
This function will not be called if setIsReceivingInput was not enabled.
This function will only be called while this node is spawned.
Parameters
iActionIdUnique ID of the input action event (from input manager).
modifiersKeyboard modifier keys.
bIsPressedDownWhether the key down event occurred or key up.

◆ onInputAxisEvent()

void ne::Node::onInputAxisEvent ( unsigned int  iAxisEventId,
KeyboardModifiers  modifiers,
float  input 
)
private

Called when a window that owns this game instance receives user input and the input key exists as an axis event in the InputManager.

Remarks
This function will not be called if setIsReceivingInput was not enabled.
This function will only be called while this node is spawned.
Parameters
iAxisEventIdUnique ID of the input axis event (from input manager).
modifiersKeyboard modifier keys.
inputA value in range [-1.0f; 1.0f] that describes input.

◆ onMouseMove()

virtual void ne::Node::onMouseMove ( double  xOffset,
double  yOffset 
)
inlineprotectedvirtual

Called when the window received mouse movement.

Remarks
This function will not be called if setIsReceivingInput was not enabled.
This function will only be called while this node is spawned.
Parameters
xOffsetMouse X movement delta in pixels (plus if moved to the right, minus if moved to the left).
yOffsetMouse Y movement delta in pixels (plus if moved up, minus if moved down).

Reimplemented in ne::EditorCameraNode.

◆ onMouseScrollMove()

virtual void ne::Node::onMouseScrollMove ( int  iOffset)
inlineprotectedvirtual

Called when the window receives mouse scroll movement.

Remarks
This function will not be called if setIsReceivingInput was not enabled.
This function will only be called while this node is spawned.
Parameters
iOffsetMovement offset.

◆ onSpawning()

virtual void ne::Node::onSpawning ( )
inlineprotectedvirtual

Called when this node was not spawned previously and it was either attached to a parent node that is spawned or set as world's root node to execute custom spawn logic.

Remarks
This node will be marked as spawned before this function is called.
getSpawnDespawnMutex is locked while this function is called.
This function is called before any of the child nodes are spawned. If you need to do some logic after child nodes are spawned use onChildNodesSpawned.
Warning
If overriding you must call the parent's version of this function first (before executing your login) to execute parent's logic.

Reimplemented in ne::EnvironmentNode, ne::DirectionalLightNode, ne::PointLightNode, ne::SpotlightNode, ne::MeshNode, and ne::SpatialNode.

◆ serializeNodeTree()

std::optional< Error > ne::Node::serializeNodeTree ( const std::filesystem::path &  pathToFile,
bool  bEnableBackup 
)

Serializes the node and all child nodes (hierarchy information will also be saved) into a file. Node tree can later be deserialized using deserializeNodeTree.

Parameters
pathToFileFile to write the node tree to. The ".toml" extension will be added automatically if not specified in the path. If the specified file already exists it will be overwritten.
bEnableBackupIf 'true' will also use a backup (copy) file. deserializeNodeTree can use backup file if the original file does not exist. Generally you want to use a backup file if you are saving important information, such as player progress, other cases such as player game settings and etc. usually do not need a backup but you can use it if you want.
Remarks
Custom attributes, like in Serializable::serialize, are not available here because they are used internally to store hierarchy and other information.
Returns
Error if something went wrong, for example when found an unsupported for serialization reflected field.

◆ setIsCalledEveryFrame()

void ne::Node::setIsCalledEveryFrame ( bool  bEnable)
protected

Determines if the onBeforeNewFrame should be called each frame or not (disabled by default).

Remarks
Safe to call any time (while spawned/despawned).
Parameters
bEnabletrue to enable onBeforeNewFrame, false to disable.

◆ setIsReceivingInput()

void ne::Node::setIsReceivingInput ( bool  bEnable)
protected

Determines if the input related functions, such as onMouseMove, onMouseScrollMove, onInputActionEvent and onInputAxisEvent will be called or not.

Remarks
Typically you should call this function in your node's constructor to determine if this node should receive input or not.
Nodes do not receive input by default.
Safe to call any time (while spawned/despawned).
Parameters
bEnableWhether the input function should be enabled or not.

◆ setNodeName()

void ne::Node::setNodeName ( const std::string &  sName)

Sets node's name.

Parameters
sNameNew name of this node.

◆ setSerialize()

void ne::Node::setSerialize ( bool  bSerialize)

Sets if this node (and node's child nodes) should be serialized as part of a node tree or not.

Parameters
bSerializetrue to serialize, false ignore when serializing as part of a node tree.

◆ setTickGroup()

void ne::Node::setTickGroup ( TickGroup  tickGroup)
protected

Sets the tick group in which the node will reside.

Tick groups determine the order in which the onBeforeNewFrame functions will be called on nodes. Each frame, onBeforeNewFrame will be called first on the nodes that use the first tick group, then on the nodes that use the second group and etc. This allows defining a special order in which onBeforeNewFrame functions will be called on nodes, thus if you want some nodes to execute their onBeforeNewFrame function only after some other nodes do so, you can define this with tick groups.

Remarks
Tick group is ignored if setIsCalledEveryFrame was not enabled.
Typically you should call this function in your node's constructor to determine in which tick group the node will reside.
Nodes use the first tick group by default.
Warning
Calling this function while the node is spawned will cause an error to be shown.
Parameters
tickGroupTick group the node will reside in.

◆ spawn()

void ne::Node::spawn ( )
private

Calls onSpawning on this node and all of its child nodes.

◆ unlockChildren()

void ne::Node::unlockChildren ( )
private

Unlocks mtxChildNodes mutex for self and recursively for all children.

After a node with children was unlocked this makes the whole node tree to be unfrozen (hierarchy can be changed as usual).

Member Data Documentation

◆ bSerialize

bool ne::Node::bSerialize = true
private

Defines whether or not this node (and node's child nodes) should be serialized as part of a node tree.

◆ iNodeId

std::optional<size_t> ne::Node::iNodeId
private

Unique ID of the spawned node (initialized after the node is spawned).

◆ mtxBindedActionEvents

std::pair< std::recursive_mutex, std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, bool)> > > ne::Node::mtxBindedActionEvents
private

Map of action events that this node is binded to. Must be used with mutex.

◆ mtxBindedAxisEvents

std::pair< std::recursive_mutex, std::unordered_map<unsigned int, std::function<void(KeyboardModifiers, float)> > > ne::Node::mtxBindedAxisEvents
private

Map of axis events that this node is binded to. Must be used with mutex.

◆ mtxChildNodes

std::pair<std::recursive_mutex, sgc::GcVector<sgc::GcPtr<Node> > > ne::Node::mtxChildNodes
private

Attached child nodes. Should be used under the mutex when changing children.

◆ mtxCreatedBroadcasters

std::pair<std::recursive_mutex, std::vector<std::unique_ptr<NodeNotificationBroadcasterBase> > > ne::Node::mtxCreatedBroadcasters
private

Notification broadcasters created using createNotificationBroadcaster.

Warning
Don't remove/erase broadcasters from this array because it's allowed to use broadcasters while the node is despawned. Additionally, all users hold raw pointers to broadcasters so they will hit deleted memory in the case of deletion.

◆ mtxCreatedTimers

std::pair<std::recursive_mutex, std::vector<std::unique_ptr<Timer> > > ne::Node::mtxCreatedTimers
private

Timers creates using createTimer.

Warning
Don't remove/erase timers from this array because in despawn we might submit a deferred task (while stopping the timer) and will use the timer to check its state in deferred task so we need to make sure that stopped timer will not be deleted while the node exists. Additionally, all users hold raw pointers to timers so they will hit deleted memory in the case of deletion.

◆ mtxIsCalledEveryFrame

std::pair<std::recursive_mutex, bool> ne::Node::mtxIsCalledEveryFrame
private

Determines if the onBeforeNewFrame should be called each frame or not.

◆ mtxIsReceivingInput

std::pair<std::recursive_mutex, bool> ne::Node::mtxIsReceivingInput
private

Determines if the input related functions, such as onMouseMove, onMouseScrollMove, onInputActionEvent and onInputAxisEvent will be called or not.

◆ mtxIsSpawned

std::pair<std::recursive_mutex, bool> ne::Node::mtxIsSpawned
private

Whether this node is spawned in the world or not.

◆ mtxParentNode

std::pair<std::recursive_mutex, sgc::GcPtr<Node> > ne::Node::mtxParentNode
private

Attached parent node.

◆ pWorld

World* ne::Node::pWorld = nullptr
private

Do not delete this pointer. World object that owns this node.

Warning
Will be initialized after the node is spawned and reset when despawned.

◆ sExternalNodeTreePathAttributeName

const auto ne::Node::sExternalNodeTreePathAttributeName
inlinestaticprivate
Initial value:
=
"external_node_tree_path_relative_to_res"

Name of the attribute we use to store a path to an external node tree.

◆ sNodeName

std::string ne::Node::sNodeName
private

Node's name.

◆ sParentNodeIdAttributeName

const auto ne::Node::sParentNodeIdAttributeName = "parent_node_id"
inlinestaticprivate

Name of the attribute we use to serialize information about parent node.

◆ tickGroup

TickGroup ne::Node::tickGroup = TickGroup::FIRST
private

Tick group used by this node.


The documentation for this class was generated from the following files: