Skip to content

Commit

Permalink
Add more Node methods and improve existing ones
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Oct 28, 2024
1 parent af3b50c commit 69d2e2d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 20 deletions.
28 changes: 17 additions & 11 deletions program/cpp/api/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -82,7 +82,7 @@ void Node::remove_child(const Node &child, bool deferred) {

std::vector<Node> Node::get_children() const {
std::vector<Node> children;
sys_node(Node_Op::GET_CHILDREN, address(), (Variant *)&children);
sys_node(Node_Op::GET_CHILDREN, address(), &children);
return children;
}

Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
35 changes: 34 additions & 1 deletion program/cpp/api/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions program/cpp/api/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ enum class Node_Op {
ADD_TO_GROUP,
REMOVE_FROM_GROUP,
IS_IN_GROUP,
IS_INSIDE_TREE,
};

enum class Node2D_Op {
Expand Down
28 changes: 20 additions & 8 deletions src/sandbox_syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,13 +969,16 @@ APICALL(api_node) {
var->create(emu, node->get_path());
} break;
case Node_Op::GET_PARENT: {
GuestVariant *var = machine.memory.memarray<GuestVariant>(gvar, 1);
uint64_t *result = machine.memory.memarray<uint64_t>(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:
Expand All @@ -987,14 +990,18 @@ APICALL(api_node) {
node->queue_free();
break;
case Node_Op::DUPLICATE: {
auto *var = machine.memory.memarray<GuestVariant>(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<uint64_t>(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<GuestVariant>(gvar, 1);
var->set(emu, node->get_child_count());
int64_t *result = machine.memory.memarray<int64_t>(gvar, 1);
*result = node->get_child_count();
} break;
case Node_Op::GET_CHILD: {
GuestVariant *var = machine.memory.memarray<GuestVariant>(gvar, 1);
Expand Down Expand Up @@ -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<bool>(gvar, 1);
*result = node->is_inside_tree();
} break;
default:
throw std::runtime_error("Invalid Node operation");
}
Expand Down

0 comments on commit 69d2e2d

Please sign in to comment.