Skip to content

Commit

Permalink
Add more Node methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fwsGonzo committed Oct 27, 2024
1 parent 7f1caef commit af3b50c
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
24 changes: 23 additions & 1 deletion program/cpp/api/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "syscalls.h"

MAKE_SYSCALL(ECALL_GET_NODE, uint64_t, sys_get_node, uint64_t, const char *, size_t);
MAKE_SYSCALL(ECALL_NODE, void, sys_node, Node_Op, uint64_t, Variant *);
MAKE_SYSCALL(ECALL_NODE, void, sys_node, Node_Op, uint64_t, ...);
MAKE_SYSCALL(ECALL_NODE_CREATE, uint64_t, sys_node_create, Node_Create_Shortlist, const char *, size_t, const char *, size_t);

static uint64_t sys_fast_get_node(uint64_t parent, const char *path, size_t path_len) {
Expand Down Expand Up @@ -104,3 +104,25 @@ Node Node::duplicate() const {
Node Node::Create(std::string_view path) {
return Node(sys_node_create(Node_Create_Shortlist::CREATE_NODE, nullptr, 0, path.data(), path.size()));
}

void Node::reparent(const Node &new_parent, bool keep_global_transform) {
sys_node(Node_Op::REPARENT, this->address(), new_parent.address(), keep_global_transform);
}

void Node::replace_by(const Node &node, bool keep_groups) {
sys_node(Node_Op::REPLACE_BY, this->address(), node.address(), keep_groups);
}

void Node::add_to_group(std::string_view group) {
sys_node(Node_Op::ADD_TO_GROUP, this->address(), group.data(), group.size());
}

void Node::remove_from_group(std::string_view group) {
sys_node(Node_Op::REMOVE_FROM_GROUP, this->address(), group.data(), group.size());
}

bool Node::is_in_group(std::string_view group) const {
bool result;
sys_node(Node_Op::IS_IN_GROUP, this->address(), group.data(), group.size(), &result);
return result;
}
38 changes: 38 additions & 0 deletions program/cpp/api/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,32 @@ struct Node : public Object {
/// @return A list of children nodes.
std::vector<Node> get_children() const;

/// @brief Add the node to a group.
/// @param group The group to add the node to.
void add_to_group(std::string_view group);

/// @brief Remove the node from a group.
/// @param group The group to remove the node from.
void remove_from_group(std::string_view group);

/// @brief Check if the node is in a group.
/// @param group The group to check.
/// @return True if the node is in the group, false otherwise.
bool is_in_group(std::string_view group) 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);

/// @brief Changes the parent of this Node to the new_parent.
/// The node needs to already have a parent.
/// The node's owner is preserved if its owner is still reachable
/// from the new location (i.e., the node is still a descendant
/// of the new parent after the operation).
/// @param new_parent The new parent node.
/// @param keep_global_transform If true, the node's global transform is preserved.
void reparent(const Node &new_parent, bool keep_global_transform = true);

/// @brief Remove this node from its parent, freeing it.
/// @note This is a potentially deferred operation.
void queue_free();
Expand All @@ -94,18 +120,30 @@ struct Node : public Object {

//- Methods -//
METHOD(void, set_physics_process);
METHOD(bool, is_physics_processing);
METHOD(void, set_physics_process_internal);
METHOD(bool, is_physics_processing_internal);
METHOD(void, set_process);
METHOD(bool, is_processing);
METHOD(void, set_process_input);
METHOD(bool, is_processing_input);
METHOD(void, set_process_internal);
METHOD(bool, is_processing_internal);
METHOD(void, set_process_unhandled_input);
METHOD(bool, is_processing_unhandled_input);
METHOD(void, set_process_unhandled_key_input);
METHOD(bool, is_processing_unhandled_key_input);
METHOD(void, set_process_shortcut_input);
METHOD(bool, is_processing_shortcut_input);
METHOD(void, set_thread_safe);
METHOD(void, set_owner);
METHOD(Node, get_owner);
METHOD(void, set_scene_file_path);
METHOD(String, get_scene_file_path);
METHOD(void, print_tree);
METHOD(void, print_tree_pretty);
METHOD(void, print_orphan_nodes);
METHOD(void, propagate_call);
};

inline Node Variant::as_node() const {
Expand Down
5 changes: 5 additions & 0 deletions program/cpp/api/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ enum class Node_Op {
REMOVE_CHILD_DEFERRED,
GET_CHILDREN,
SET_NAME,
REPARENT,
REPLACE_BY,
ADD_TO_GROUP,
REMOVE_FROM_GROUP,
IS_IN_GROUP,
};

enum class Node2D_Op {
Expand Down
28 changes: 28 additions & 0 deletions src/sandbox_syscalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,34 @@ APICALL(api_node) {
}
// No return value is needed.
} break;
case Node_Op::ADD_TO_GROUP: {
// Reg 12: Group string pointer, Reg 13: Group string length.
std::string_view group = machine.memory.memview(gvar, machine.cpu.reg(13));
node->add_to_group(String::utf8(group.data(), group.size()));
} break;
case Node_Op::REMOVE_FROM_GROUP: {
// Reg 12: Group string pointer, Reg 13: Group string length.
std::string_view group = machine.memory.memview(gvar, machine.cpu.reg(13));
node->remove_from_group(String::utf8(group.data(), group.size()));
} break;
case Node_Op::IS_IN_GROUP: {
// Reg 12: Group string pointer, Reg 13: Group string length, Reg 14: Result bool pointer.
std::string_view group = machine.memory.memview(gvar, machine.cpu.reg(13));
bool *result = machine.memory.memarray<bool>(machine.cpu.reg(14), 1);
*result = node->is_in_group(String::utf8(group.data(), group.size()));
} break;
case Node_Op::REPLACE_BY: {
// Reg 12: Node address to replace with, Reg 13: Keep groups bool.
godot::Node *replace_node = get_node_from_address(emu, gvar);
bool keep_groups = machine.cpu.reg(13);
node->replace_by(replace_node, keep_groups);
} break;
case Node_Op::REPARENT: {
// Reg 12: New parent node address, Reg 13: Keep transform bool.
godot::Node *new_parent = get_node_from_address(emu, gvar);
bool keep_transform = machine.cpu.reg(13);
node->reparent(new_parent, keep_transform);
} break;
default:
throw std::runtime_error("Invalid Node operation");
}
Expand Down

0 comments on commit af3b50c

Please sign in to comment.