diff --git a/core/nodes/node.cpp b/core/nodes/node.cpp index e41089f..5d61ff9 100644 --- a/core/nodes/node.cpp +++ b/core/nodes/node.cpp @@ -1,9 +1,96 @@ #include "node.h" -#include "request.h" +#include "node_tree.h" -Node::Node() : Object() { +Node *Node::get_parent() { + return _parent; +} +void Node::set_parent(Node *parent) { + if (_parent == parent) { + return; + } + + if (_parent) { + notification(NOTIFICATION_UNPARENTED); + } + + _parent = parent; + + if (_parent) { + notification(NOTIFICATION_PARENTED); + } +} + +int Node::get_child_count() { + return _children.size(); +} +Node *Node::get_child(int index) { + return _children[index]; +} +void Node::add_child(Node *child) { + ERR_FAIL_COND(!child); + ERR_FAIL_COND(child->get_parent()); + + _children.push_back(child); + child->set_parent(this); + + notification(NOTIFICATION_CHILD_ADDED); +} +void Node::remove_child_index(int index) { + Node *c = _children[index]; + + _children.remove_keep_order(index); + c->set_parent(nullptr); + + notification(NOTIFICATION_CHILD_REMOVED); +} +void Node::remove_child(Node *child) { + ERR_FAIL_COND(!child); + + for (int i = 0; i < _children.size(); ++i) { + Node *c = _children[i]; + + if (c == child) { + _children.remove_keep_order(i); + child->set_parent(nullptr); + notification(NOTIFICATION_CHILD_REMOVED); + return; + } + } +} + +NodeTree *Node::get_tree() { + return _tree; +} + +void Node::set_tree(NodeTree *tree) { + if (_tree) { + notification(NOTIFICATION_EXIT_TREE); + } + + _tree = tree; + + if (_tree) { + notification(NOTIFICATION_ENTER_TREE); + } +} + +void Node::notification(int what) { + _notification(what); + + for (int i = 0; i < _children.size(); ++i) { + _children[i]->notification(what); + } +} +void Node::_notification(int what) { +} + +Node::Node() : + Object() { + + _parent = nullptr; + _tree = nullptr; } Node::~Node() { diff --git a/core/nodes/node.h b/core/nodes/node.h index 4c2eaad..b4dd774 100644 --- a/core/nodes/node.h +++ b/core/nodes/node.h @@ -2,13 +2,44 @@ #define NODE_H #include "core/object.h" +#include "core/containers/vector.h" + +class NodeTree; class Node : public Object { public: + enum { + NOTIFICATION_ENTER_TREE = 0, + NOTIFICATION_EXIT_TREE = 1, + NOTIFICATION_PARENTED = 2, + NOTIFICATION_UNPARENTED = 3, + NOTIFICATION_CHILD_ADDED = 4, + NOTIFICATION_CHILD_REMOVED = 5, + NOTIFICATION_CHILD_MOVED = 6, + }; + + Node *get_parent(); + void set_parent(Node *parent); + + int get_child_count(); + Node *get_child(int index); + void add_child(Node *child); + void remove_child_index(int index); + void remove_child(Node *child); + + NodeTree *get_tree(); + void set_tree(NodeTree *tree); + + virtual void notification(int what); + virtual void _notification(int what); + Node(); ~Node(); protected: + Node * _parent; + Vector _children; + NodeTree *_tree; }; #endif \ No newline at end of file diff --git a/core/nodes/node_tree.cpp b/core/nodes/node_tree.cpp index 72a2c93..ac70cdc 100644 --- a/core/nodes/node_tree.cpp +++ b/core/nodes/node_tree.cpp @@ -1,6 +1,28 @@ #include "node_tree.h" +#include "node.h" + +Node *NodeTree::get_root() { + return _root_node; +} + +void NodeTree::set_root(Node *root) { + if (_root_node) { + _root_node->set_tree(nullptr); + } + + _root_node = root; + + if (_root_node) { + _root_node->set_tree(this); + } +} + +void NodeTree::send_update(float delta) { + //todo +} + NodeTree::NodeTree() : Object() { } diff --git a/core/nodes/node_tree.h b/core/nodes/node_tree.h index d6df762..8d0a06f 100644 --- a/core/nodes/node_tree.h +++ b/core/nodes/node_tree.h @@ -3,35 +3,21 @@ #include "core/object.h" -//should be a template -//It should be inherited from -//Similar idea to godot's scenetree -//Should handle all functionality of base nodes -//refreshes etc -> good for web nodes aswell -> can use dirtying if there are updates, or clearing caches -//Should have a root node (templated) -//Nodes should have a tree set into them (not templated) -> set() should be virtual - -//For the web: -//The webserver could be a webtree, the nodes themselves could handle routing with their hierarchy (easy to cache) would have the same speed -//Routing could be overridable per node -//MIddlewares can be handled by the tree before sending the request to the tree, also files (that could be a middleware aswell) -//WebTree : public NodeTree -//and then Server : public WebTree -//This way webapps could be build like guis in godot. - -//WebTree -// - WebRoot (Normal WebNode - if uri is '/news/...' if it has a news node, pushes the uri stack and forwards the request to that node. Else 404 -// ---- news (News node f.e. - handles request, stops forwarding) -// ---- projects (Projects node, either forwards, or if /projects sends back a list etc) -// -------- p1 -//etc +class Node; class NodeTree : public Object { public: + Node *get_root(); + virtual void set_root(Node *root); + + virtual void send_update(float delta); + NodeTree(); ~NodeTree(); protected: + Node *_root_node; + float _update_interval; }; #endif \ No newline at end of file