Skip to content

Commit

Permalink
GH-265 Support Object new() and free() nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
Naros committed Apr 21, 2024
1 parent ccecadb commit cd59f49
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/editor/graph/actions/default_action_registrar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@ void OrchestratorDefaultGraphActionRegistrar::_register_script_nodes(const Orche
// Input
_register_node<OScriptNodeInputAction>(p_context, "Input/input_action");

// Memory
_register_node<OScriptNodeNew>(p_context, "Memory/new_object");
_register_node<OScriptNodeFree>(p_context, "Memory/free_object");

// Resource
_register_node<OScriptNodePreload>(p_context, "Resource/preload_resource");
_register_node<OScriptNodeResourcePath>(p_context, "Resource/get_resource_path");
Expand Down
1 change: 1 addition & 0 deletions src/plugin/settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ void OrchestratorSettings::_register_settings()
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/function_terminator", Color(0.294, 0.0, 0.506)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/function_result", Color(1.0, 0.65, 0.4)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/math_operations", Color(0.259, 0.408, 0.384)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/memory", Color(0.351, .339, .133)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/properties", Color(.467, 0.28, 0.175)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/resources", Color(0.263, 0.275, 0.359)));
_settings.emplace_back(COLOR_NO_ALPHA_SETTING("ui/node_colors/scene", Color(0.208, 0.141, 0.282)));
Expand Down
193 changes: 193 additions & 0 deletions src/script/nodes/memory/memory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "script/nodes/memory/memory.h"

#include <godot_cpp/classes/engine.hpp>
#include <godot_cpp/classes/node.hpp>

class OScriptNodeNewInstance : public OScriptNodeInstance
{
DECLARE_SCRIPT_NODE_INSTANCE(OScriptNodeNew);
String _class_name;

public:
int step(OScriptNodeExecutionContext& p_context) override
{
if (!_class_name.is_empty() && ClassDB::can_instantiate(_class_name))
{
Variant object = ClassDB::instantiate(_class_name);
p_context.set_output(0, object);
}
return 0;
}
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class OScriptNodeFreeInstance : public OScriptNodeInstance
{
DECLARE_SCRIPT_NODE_INSTANCE(OScriptNodeFree);
public:
int step(OScriptNodeExecutionContext& p_context) override
{
Variant object = p_context.get_input(0);
if (object)
{
Object* casted = Object::cast_to<Object>(object);
if (ClassDB::is_parent_class(casted->get_class(), "Node"))
{
Node* node = Object::cast_to<Node>(casted);
node->queue_free();
}
else if (ClassDB::is_parent_class(casted->get_class(), "RefCounted"))
{
RefCounted *ref = Object::cast_to<RefCounted>(casted);
ref->unreference();
}
else
{
memdelete(casted);
}
}
return 0;
}
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

OScriptNodeNew::OScriptNodeNew()
{
_flags.set_flag(OScriptNode::ScriptNodeFlags::EXPERIMENTAL);
}

void OScriptNodeNew::_bind_methods()
{
}

void OScriptNodeNew::_get_property_list(List<PropertyInfo>* r_list) const
{
r_list->push_back(PropertyInfo(Variant::STRING, "class_name", PROPERTY_HINT_TYPE_STRING, "Object"));
}

bool OScriptNodeNew::_get(const StringName& p_name, Variant& r_value) const
{
if (p_name.match("class_name"))
{
r_value = _class_name;
return true;
}
return false;
}

bool OScriptNodeNew::_set(const StringName& p_name, const Variant& p_value)
{
if (p_name.match("class_name"))
{
if (_class_name != p_value)
{
const bool is_singleton = Engine::get_singleton()->get_singleton_list().has(p_value);
ERR_FAIL_COND_V_MSG(is_singleton, false, vformat("Cannot create an instance of '%s', a singleton.", p_value));

_class_name = p_value;
_notify_pins_changed();
return true;
}
}
return false;
}

void OScriptNodeNew::allocate_default_pins()
{
create_pin(PD_Input, "ExecIn")->set_flags(OScriptNodePin::Flags::EXECUTION);
create_pin(PD_Output, "ExecOut")->set_flags(OScriptNodePin::Flags::EXECUTION);
create_pin(PD_Output, "Instance", Variant::OBJECT)->set_flags(OScriptNodePin::Flags::DATA);

super::allocate_default_pins();
}

String OScriptNodeNew::get_tooltip_text() const
{
return vformat("Creates a new instance of %s.", _class_name.is_empty() ? "a class" : _class_name);
}

String OScriptNodeNew::get_node_title() const
{
return _class_name.is_empty() ? "Create instance" : vformat("Create a %s", _class_name);
}

String OScriptNodeNew::get_icon() const
{
return "CurveCreate";
}

OScriptNodeInstance* OScriptNodeNew::instantiate(OScriptInstance* p_instance)
{
OScriptNodeNewInstance* i = memnew(OScriptNodeNewInstance);
i->_node = this;
i->_instance = p_instance;
i->_class_name = _class_name;
return i;
}

void OScriptNodeNew::initialize(const OScriptNodeInitContext& p_context)
{
_class_name = "Object";
super::initialize(p_context);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

OScriptNodeFree::OScriptNodeFree()
{
_flags.set_flag(OScriptNode::ScriptNodeFlags::EXPERIMENTAL);
}

void OScriptNodeFree::_bind_methods()
{
}

void OScriptNodeFree::allocate_default_pins()
{
create_pin(PD_Input, "ExecIn")->set_flags(OScriptNodePin::Flags::EXECUTION);
create_pin(PD_Input, "Target", Variant::OBJECT)->set_flags(OScriptNodePin::Flags::DATA | OScriptNodePin::Flags::IGNORE_DEFAULT);
create_pin(PD_Output, "ExecOut")->set_flags(OScriptNodePin::Flags::EXECUTION);

super::allocate_default_pins();
}

String OScriptNodeFree::get_tooltip_text() const
{
return "Free the memory used by the specified object.";
}

String OScriptNodeFree::get_node_title() const
{
return "Free instance";
}

String OScriptNodeFree::get_icon() const
{
return "CurveDelete";
}

OScriptNodeInstance* OScriptNodeFree::instantiate(OScriptInstance* p_instance)
{
OScriptNodeFreeInstance* i = memnew(OScriptNodeFreeInstance);
i->_node = this;
i->_instance = p_instance;
return i;
}
73 changes: 73 additions & 0 deletions src/script/nodes/memory/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// This file is part of the Godot Orchestrator project.
//
// Copyright (c) 2023-present Vahera Studios LLC and its contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#ifndef ORCHESTRATOR_SCRIPT_NODE_MEMORY_H
#define ORCHESTRATOR_SCRIPT_NODE_MEMORY_H

#include "script/script.h"

/// Creates a new instance of a Godot class
class OScriptNodeNew : public OScriptNode
{
ORCHESTRATOR_NODE_CLASS(OScriptNodeNew, OScriptNode)

protected:
String _class_name;

//~ Begin Wrapped Interface
void _get_property_list(List<PropertyInfo>* r_list) const;
bool _get(const StringName& p_name, Variant& r_value) const;
bool _set(const StringName& p_name, const Variant& p_value);
//~ End Wrapped Interface

static void _bind_methods();

public:
//~ Begin OScriptNode Interface
void allocate_default_pins() override;
String get_tooltip_text() const override;
String get_node_title() const override;
String get_node_title_color_name() const override { return "memory"; }
String get_icon() const override;
StringName resolve_type_class(const Ref<OScriptNodePin>& p_pin) const override { return _class_name; }
OScriptNodeInstance* instantiate(OScriptInstance* p_instance) override;
void initialize(const OScriptNodeInitContext& p_context) override;
//~ End OScriptNode Interface

OScriptNodeNew();
};

/// Destroys an instance of a Godot class
class OScriptNodeFree : public OScriptNode
{
ORCHESTRATOR_NODE_CLASS(OScriptNodeFree, OScriptNode)
protected:
static void _bind_methods();

public:
//~ Begin OScriptNode Interface
void allocate_default_pins() override;
String get_tooltip_text() const override;
String get_node_title() const override;
String get_node_title_color_name() const override { return "memory"; }
String get_icon() const override;
OScriptNodeInstance* instantiate(OScriptInstance* p_instance) override;
//~ End OScriptNode Interface

OScriptNodeFree();
};

#endif // ORCHESTRATOR_SCRIPT_NODE_MEMORY_H
4 changes: 4 additions & 0 deletions src/script/nodes/script_nodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ void register_script_node_classes()
//~ Math
ORCHESTRATOR_REGISTER_NODE_CLASS(OScriptNodeOperator)

//~ Memory
ORCHESTRATOR_REGISTER_NODE_CLASS(OScriptNodeNew);
ORCHESTRATOR_REGISTER_NODE_CLASS(OScriptNodeFree);

//~ Properties
ORCHESTRATOR_REGISTER_NODE_CLASS(OScriptNodePropertyGet)
ORCHESTRATOR_REGISTER_NODE_CLASS(OScriptNodePropertySet)
Expand Down
3 changes: 3 additions & 0 deletions src/script/nodes/script_nodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
// Math
#include "math/operator_node.h"

// Memory
#include "memory/memory.h"

// Properties
#include "properties/property_get.h"
#include "properties/property_set.h"
Expand Down

0 comments on commit cd59f49

Please sign in to comment.