Nameless Engine
|
#include <Node.h>
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 | |
Node & | operator= (const Node &)=delete |
Node (Node &&)=delete | |
Node & | operator= (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< Error > | serializeNodeTree (const std::filesystem::path &pathToFile, bool bEnableBackup) |
std::string | getNodeName () const |
sgc::GcPtr< Node > | getWorldRootNode () |
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< Error > | serialize (std::filesystem::path pathToFile, bool bEnableBackup, const std::unordered_map< std::string, std::string > &customAttributes={}) |
std::variant< std::string, Error > | serialize (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, Error > | serialize (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 >, Error > | deserializeNodeTree (const std::filesystem::path &pathToFile) |
static GameInstance * | getGameInstance () |
Static Public Member Functions inherited from ne::Serializable | |
static std::variant< std::pair< std::set< std::string >, toml::value >, Error > | getIdsFromFile (std::filesystem::path pathToFile) |
static std::optional< Error > | serializeMultiple (std::filesystem::path pathToFile, std::vector< SerializableObjectInformation > vObjects, bool bEnableBackup) |
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, Error > | deserialize (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, Error > | deserialize (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, Error > | deserialize (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, Error > | deserialize (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 > >, Error > | deserializeMultiple (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, Error > | deserialize (const toml::value &tomlData, std::unordered_map< std::string, std::string > &customAttributes, std::string sEntityId="", const std::optional< std::filesystem::path > &optionalPathToFile={}) |
Protected Member Functions | |
void | setIsCalledEveryFrame (bool bEnable) |
void | setTickGroup (TickGroup tickGroup) |
void | setIsReceivingInput (bool bEnable) |
Timer * | createTimer (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) |
World * | findValidWorld () |
std::variant< std::vector< SerializableObjectInformationWithGcPointer >, Error > | getInformationForSerialization (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 |
World * | pWorld = 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 |
Base class for nodes, allows being spawned in the world, attaching child nodes or being attached to some parent node.
|
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).
ne::Node::Node | ( | ) |
Creates a new node with a default name.
ne::Node::Node | ( | const std::string & | sName | ) |
Creates a new node with the specified name.
sName | Name of this node. |
|
overridevirtual |
Logs destruction in debug builds.
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.
pNode | Node to attach as a child. If the specified node is a parent of this node the operation will fail and log an error. |
locationRule | Only 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) |
rotationRule | Only 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) |
scaleRule | Only 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) |
|
inlineprotected |
Creates a new notification broadcaster that only accepts callbacks of the specified type.
Example:
|
protected |
Creates a new timer and saves it inside of this node to be used while the node is spawned.
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).sTimerName | Name of this timer (used for logging). Don't add "timer" word to your timer's name as it will be appended in the logs. |
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).
|
static |
Deserializes a node and all its child nodes (hierarchy information) from a file.
pathToFile | File to read a node tree from. The ".toml" extension will be added automatically if not specified in the path. |
|
private |
Calls onDespawning on this node and all of its child nodes.
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.
gc
pointers.
|
private |
Enables the specified timer and sets a callback validator or stops and disables the timer.
pTimer | Timer to enable/disable. |
bEnable | New timer state to set. |
false
if successful, true
otherwise.
|
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.
|
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.
Example:
|
static |
Returns the total amount of currently alive (allocated) nodes.
|
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.
Example:
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.
sChildNodeName | If not empty, nodes that match the specified node type will also be checked to see if their name exactly matches the specified name. |
std::pair< std::recursive_mutex, sgc::GcVector< sgc::GcPtr< Node > > > * ne::Node::getChildNodes | ( | ) |
Returns pointer to child nodes array.
|
static |
Returns last created game instance.
|
private |
Collects and returns information for serialization for self and all child nodes.
iId | ID for serialization to use (will be incremented). |
iParentId | Parent's serialization ID (if this node has a parent and it will also be serialized). |
std::optional< size_t > ne::Node::getNodeId | ( | ) | const |
Returns a unique ID of the node.
std::string ne::Node::getNodeName | ( | ) | const |
Returns node's name.
std::pair< std::recursive_mutex, sgc::GcPtr< Node > > * ne::Node::getParentNode | ( | ) |
Returns parent node if this node.
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. 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.
sParentNodeName | If not empty, nodes that match the specified node type will also be checked to see if their name exactly matches the specified name. |
|
protected |
Returns mutex that is generally used to protect/prevent spawning/despawning.
TickGroup ne::Node::getTickGroup | ( | ) | const |
Returns the tick group this node resides in.
sgc::GcPtr< Node > ne::Node::getWorldRootNode | ( | ) |
Returns world's root node.
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. bool ne::Node::isCalledEveryFrame | ( | ) |
Returns whether the onBeforeNewFrame should be called each frame or not.
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).
pNode | Node to check. |
true
if the specified node was found as a parent of this node, false
otherwise. 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).
pNode | Node to check. |
true
if the specified node was found as a child of this node, false
otherwise. bool ne::Node::isReceivingInput | ( | ) |
Returns whether this node receives input or not.
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.
false
if this node and its child nodes will be ignored when being serialized as part of a node tree, true
otherwise. bool ne::Node::isSpawned | ( | ) |
Returns whether this node is spawned in the world or not.
|
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).
sPathRelativeToRes | Path relative to the res directory to the file to check, example: game/test.toml . |
false
if this node or some child node(s) were deserialized from other file or if some nodes we not deserialized previously, otherwise true
.
|
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.
|
private |
Calls onAfterAttachedToNewParent on this node and all of its child nodes.
bThisNodeBeingAttached | true if this node was attached to a parent, false if some node in the parent hierarchy was attached to a parent. |
|
private |
Calls onBeforeDetachedFromParent on this node and all of its child nodes.
bThisNodeBeingDetached | true if this node is being detached from its parent, false if some node in the parent hierarchy is being detached from its parent. |
|
inlineprotectedvirtual |
Called after this node or one of the node's parents (in the parent hierarchy) was attached to a new parent node.
bThisNodeBeingAttached | true 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.
|
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.
nullptr
after this function is finished.bThisNodeBeingDetached | true if this node is being detached from its parent, false if some node in the parent hierarchy is being detached from its parent. |
|
inlineprotectedvirtual |
Called before a new frame is rendered.
timeSincePrevFrameInSec | Also known as deltatime - time in seconds that has passed since the last frame was rendered. |
Reimplemented in ne::EditorCameraNode.
|
inlineprotectedvirtual |
Called after onSpawning when this node and all of node's child nodes (at the moment of spawning) were spawned.
|
inlineprotectedvirtual |
Called before this node is despawned from the world to execute custom despawn logic.
Reimplemented in ne::CameraNode, ne::EnvironmentNode, ne::DirectionalLightNode, ne::PointLightNode, ne::SpotlightNode, and ne::MeshNode.
|
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.
iActionId | Unique ID of the input action event (from input manager). |
modifiers | Keyboard modifier keys. |
bIsPressedDown | Whether the key down event occurred or key up. |
|
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.
iAxisEventId | Unique ID of the input axis event (from input manager). |
modifiers | Keyboard modifier keys. |
input | A value in range [-1.0f; 1.0f] that describes input. |
|
inlineprotectedvirtual |
Called when the window received mouse movement.
xOffset | Mouse X movement delta in pixels (plus if moved to the right, minus if moved to the left). |
yOffset | Mouse Y movement delta in pixels (plus if moved up, minus if moved down). |
Reimplemented in ne::EditorCameraNode.
|
inlineprotectedvirtual |
Called when the window receives mouse scroll movement.
iOffset | Movement offset. |
|
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.
Reimplemented in ne::EnvironmentNode, ne::DirectionalLightNode, ne::PointLightNode, ne::SpotlightNode, ne::MeshNode, and ne::SpatialNode.
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.
pathToFile | File 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. |
bEnableBackup | If '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. |
|
protected |
Determines if the onBeforeNewFrame should be called each frame or not (disabled by default).
bEnable | true to enable onBeforeNewFrame, false to disable. |
|
protected |
Determines if the input related functions, such as onMouseMove, onMouseScrollMove, onInputActionEvent and onInputAxisEvent will be called or not.
bEnable | Whether the input function should be enabled or not. |
void ne::Node::setNodeName | ( | const std::string & | sName | ) |
Sets node's name.
sName | New name of this node. |
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.
bSerialize | true to serialize, false ignore when serializing as part of a node tree. |
|
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.
tickGroup | Tick group the node will reside in. |
|
private |
Calls onSpawning on this node and all of its child nodes.
|
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).
|
private |
Defines whether or not this node (and node's child nodes) should be serialized as part of a node tree.
|
private |
Unique ID of the spawned node (initialized after the node is spawned).
|
private |
Map of action events that this node is binded to. Must be used with mutex.
|
private |
Map of axis events that this node is binded to. Must be used with mutex.
|
private |
Attached child nodes. Should be used under the mutex when changing children.
|
private |
Notification broadcasters created using createNotificationBroadcaster.
|
private |
Timers creates using createTimer.
|
private |
Determines if the onBeforeNewFrame should be called each frame or not.
|
private |
Determines if the input related functions, such as onMouseMove, onMouseScrollMove, onInputActionEvent and onInputAxisEvent will be called or not.
|
private |
Whether this node is spawned in the world or not.
|
private |
Attached parent node.
|
private |
Do not delete this pointer. World object that owns this node.
|
inlinestaticprivate |
Name of the attribute we use to store a path to an external node tree.
|
private |
Node's name.
|
inlinestaticprivate |
Name of the attribute we use to serialize information about parent node.
|
private |
Tick group used by this node.