From 69d2e2d2e31c9e0b7822e4013955087c1e7d8145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf-Andr=C3=A9=20Walla?= Date: Mon, 28 Oct 2024 06:28:47 +0100 Subject: [PATCH] Add more Node methods and improve existing ones --- program/cpp/api/node.cpp | 28 +++++++++++++++++----------- program/cpp/api/node.hpp | 35 ++++++++++++++++++++++++++++++++++- program/cpp/api/syscalls.h | 1 + src/sandbox_syscalls.cpp | 28 ++++++++++++++++++++-------- 4 files changed, 72 insertions(+), 20 deletions(-) diff --git a/program/cpp/api/node.cpp b/program/cpp/api/node.cpp index ffcc0d7..9c6c374 100644 --- a/program/cpp/api/node.cpp +++ b/program/cpp/api/node.cpp @@ -43,15 +43,15 @@ Variant Node::get_path() const { } Node Node::get_parent() const { - Variant var; - sys_node(Node_Op::GET_PARENT, address(), &var); - return var.as_node(); + uint64_t addr; + sys_node(Node_Op::GET_PARENT, address(), &addr); + return Node(addr); } unsigned Node::get_child_count() const { - Variant var; - sys_node(Node_Op::GET_CHILD_COUNT, address(), &var); - return int64_t(var); + int64_t result; + sys_node(Node_Op::GET_CHILD_COUNT, address(), &result); + return result; } Node Node::get_child(unsigned index) const { @@ -82,7 +82,7 @@ void Node::remove_child(const Node &child, bool deferred) { std::vector Node::get_children() const { std::vector children; - sys_node(Node_Op::GET_CHILDREN, address(), (Variant *)&children); + sys_node(Node_Op::GET_CHILDREN, address(), &children); return children; } @@ -95,10 +95,10 @@ void Node::queue_free() { //this->m_address = 0; } -Node Node::duplicate() const { - Variant result; - sys_node(Node_Op::DUPLICATE, this->address(), &result); - return result.as_node(); +Node Node::duplicate(int flags) const { + uint64_t result; + sys_node(Node_Op::DUPLICATE, this->address(), &result, flags); + return Node(result); } Node Node::Create(std::string_view path) { @@ -126,3 +126,9 @@ bool Node::is_in_group(std::string_view group) const { sys_node(Node_Op::IS_IN_GROUP, this->address(), group.data(), group.size(), &result); return result; } + +bool Node::is_inside_tree() const { + bool result; + sys_node(Node_Op::IS_INSIDE_TREE, this->address(), &result); + return result; +} diff --git a/program/cpp/api/node.hpp b/program/cpp/api/node.hpp index 15edb7f..d9322c7 100644 --- a/program/cpp/api/node.hpp +++ b/program/cpp/api/node.hpp @@ -83,6 +83,10 @@ struct Node : public Object { /// @return True if the node is in the group, false otherwise. bool is_in_group(std::string_view group) const; + /// @brief Check if the node is inside the scene tree. + /// @return True if the node is inside the scene tree, false otherwise. + bool is_inside_tree() const; + /// @brief Replace the node with another node. /// @param node The node to replace this node with. void replace_by(const Node &node, bool keep_groups = false); @@ -102,7 +106,7 @@ struct Node : public Object { /// @brief Duplicate the node. /// @return A new Node object with the same properties and children. - Node duplicate() const; + Node duplicate(int flags) const; /// @brief Create a new Node object. /// @param path The path to the Node object. @@ -119,6 +123,15 @@ struct Node : public Object { PROPERTY(process_priority, int64_t); //- Methods -// + METHOD(Object, create_tween); + METHOD(Node, find_child); + METHOD(Variant, find_children); + METHOD(Node, find_parent); + METHOD(Node, get_viewport); + METHOD(Node, get_window); + METHOD(bool, has_node); + METHOD(bool, has_node_and_resource); + METHOD(bool, is_ancestor_of); METHOD(void, set_physics_process); METHOD(bool, is_physics_processing); METHOD(void, set_physics_process_internal); @@ -135,6 +148,7 @@ struct Node : public Object { METHOD(bool, is_processing_unhandled_key_input); METHOD(void, set_process_shortcut_input); METHOD(bool, is_processing_shortcut_input); + METHOD(bool, is_node_ready); METHOD(void, set_thread_safe); METHOD(void, set_owner); METHOD(Node, get_owner); @@ -144,6 +158,25 @@ struct Node : public Object { METHOD(void, print_tree_pretty); METHOD(void, print_orphan_nodes); METHOD(void, propagate_call); + + + //- Signals -// + + //- Constants -// + static constexpr int PROCESS_MODE_INHERIT = 0; + static constexpr int PROCESS_MODE_PAUSABLE = 1; + static constexpr int PROCESS_MODE_WHEN_PAUSED = 2; + static constexpr int PROCESS_MODE_ALWAYS = 3; + static constexpr int PROCESS_MODE_DISABLED = 4; + + static constexpr int PHYSICS_INTERPOLATION_MODE_INHERIT = 0; + static constexpr int PHYSICS_INTERPOLATION_MODE_ON = 1; + static constexpr int PHYSICS_INTERPOLATION_MODE_OFF = 2; + + static constexpr int DUPLICATE_SIGNALS = 1; + static constexpr int DUPLICATE_GROUPS = 2; + static constexpr int DUPLICATE_SCRIPTS = 4; + static constexpr int DUPLICATE_USE_INSTANTIATION = 8; }; inline Node Variant::as_node() const { diff --git a/program/cpp/api/syscalls.h b/program/cpp/api/syscalls.h index ffa4c35..5185179 100644 --- a/program/cpp/api/syscalls.h +++ b/program/cpp/api/syscalls.h @@ -124,6 +124,7 @@ enum class Node_Op { ADD_TO_GROUP, REMOVE_FROM_GROUP, IS_IN_GROUP, + IS_INSIDE_TREE, }; enum class Node2D_Op { diff --git a/src/sandbox_syscalls.cpp b/src/sandbox_syscalls.cpp index da4cb3a..b11cf8f 100644 --- a/src/sandbox_syscalls.cpp +++ b/src/sandbox_syscalls.cpp @@ -969,13 +969,16 @@ APICALL(api_node) { var->create(emu, node->get_path()); } break; case Node_Op::GET_PARENT: { - GuestVariant *var = machine.memory.memarray(gvar, 1); + uint64_t *result = machine.memory.memarray(gvar, 1); godot::Object *parent = node->get_parent(); if (parent == nullptr) { - var->set(emu, Variant()); + *result = 0; } else { // TODO: Parent nodes allow access higher up the tree, which could be a security issue. - var->set(emu, parent, true); // Implicit trust, as we are returning engine-provided result. + if (!emu.is_allowed_object(parent)) + throw std::runtime_error("Node::get_parent(): Parent is not allowed"); + emu.add_scoped_object(parent); + *result = uint64_t(uintptr_t(parent)); } } break; case Node_Op::QUEUE_FREE: @@ -987,14 +990,18 @@ APICALL(api_node) { node->queue_free(); break; case Node_Op::DUPLICATE: { - auto *var = machine.memory.memarray(gvar, 1); - auto *new_node = node->duplicate(); + if (!emu.is_allowed_class(node->get_class())) { + throw std::runtime_error("Node::duplicate(): Creating a new node of this type is not allowed"); + } + uint64_t *result = machine.memory.memarray(gvar, 1); + int flags = machine.cpu.reg(13); // Flags are passed in reg 13. + auto *new_node = node->duplicate(flags); emu.add_scoped_object(new_node); - var->set(emu, new_node, true); // Implicit trust, as we are returning our own object. + *result = uint64_t(uintptr_t(new_node)); } break; case Node_Op::GET_CHILD_COUNT: { - GuestVariant *var = machine.memory.memarray(gvar, 1); - var->set(emu, node->get_child_count()); + int64_t *result = machine.memory.memarray(gvar, 1); + *result = node->get_child_count(); } break; case Node_Op::GET_CHILD: { GuestVariant *var = machine.memory.memarray(gvar, 1); @@ -1086,6 +1093,11 @@ APICALL(api_node) { bool keep_transform = machine.cpu.reg(13); node->reparent(new_parent, keep_transform); } break; + case Node_Op::IS_INSIDE_TREE: { + // Reg 12: Result bool pointer. + bool *result = machine.memory.memarray(gvar, 1); + *result = node->is_inside_tree(); + } break; default: throw std::runtime_error("Invalid Node operation"); }