summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Marques <george@gmarqu.es>2017-11-15 13:57:24 -0200
committerGeorge Marques <george@gmarqu.es>2017-11-15 17:13:13 -0200
commit0284727e7bc6337ebcd98e61eacf0d095d74a094 (patch)
tree4c108558ec25992c2c940cbbde4d3832055c45a2
parent9543801d51910cdf61123f591fd91993f57782ae (diff)
Create API to add and remove VisualScript custom nodes
This makes a VisualScriptEditor singleton, which gives plugins the ability to register their own custom nodes. Those will be available for insertion in the Visual Script editor, under the "Custom Nodes" category.
-rw-r--r--modules/visual_script/config.py6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptEditor.xml46
-rw-r--r--modules/visual_script/register_types.cpp11
-rw-r--r--modules/visual_script/visual_script.cpp5
-rw-r--r--modules/visual_script/visual_script.h1
-rw-r--r--modules/visual_script/visual_script_editor.cpp43
-rw-r--r--modules/visual_script/visual_script_editor.h23
7 files changed, 135 insertions, 0 deletions
diff --git a/modules/visual_script/config.py b/modules/visual_script/config.py
index 5698a37295..d10adb09d9 100644
--- a/modules/visual_script/config.py
+++ b/modules/visual_script/config.py
@@ -6,3 +6,9 @@ def can_build(platform):
def configure(env):
pass
+
+def get_doc_classes():
+ return ["VisualScriptEditor"]
+
+def get_doc_path():
+ return "doc_classes"
diff --git a/modules/visual_script/doc_classes/VisualScriptEditor.xml b/modules/visual_script/doc_classes/VisualScriptEditor.xml
new file mode 100644
index 0000000000..70d52b2bd7
--- /dev/null
+++ b/modules/visual_script/doc_classes/VisualScriptEditor.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualScriptEditor" inherits="Object" category="Core" version="3.0.alpha.custom_build">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ <method name="add_custom_node">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="category" type="String">
+ </argument>
+ <argument index="2" name="script" type="Script">
+ </argument>
+ <description>
+ Add a custom Visual Script node to the editor. It'll be placed under "Custom Nodes" with the [code]category[/code] as the parameter.
+ </description>
+ </method>
+ <method name="remove_custom_node">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="category" type="String">
+ </argument>
+ <description>
+ Remove a custom Visual Script node from the editor. Custom nodes already placed on scripts won't be removed.
+ </description>
+ </method>
+ </methods>
+ <signals>
+ <signal name="custom_nodes_updated">
+ <description>
+ Emitted when a custom Visual Script node is added or removed.
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index c50ba17c35..b6ce10381d 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "register_types.h"
+#include "core/engine.h"
#include "io/resource_loader.h"
#include "visual_script.h"
#include "visual_script_builtin_funcs.h"
@@ -40,6 +41,9 @@
#include "visual_script_yield_nodes.h"
VisualScriptLanguage *visual_script_language = NULL;
+#ifdef TOOLS_ENABLED
+static _VisualScriptEditor *vs_editor_singleton = NULL;
+#endif
void register_visual_script_types() {
@@ -107,6 +111,10 @@ void register_visual_script_types() {
register_visual_script_expression_node();
#ifdef TOOLS_ENABLED
+ ClassDB::register_class<_VisualScriptEditor>();
+ vs_editor_singleton = memnew(_VisualScriptEditor);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", _VisualScriptEditor::get_singleton()));
+
VisualScriptEditor::register_editor();
#endif
}
@@ -119,6 +127,9 @@ void unregister_visual_script_types() {
#ifdef TOOLS_ENABLED
VisualScriptEditor::free_clipboard();
+ if (vs_editor_singleton) {
+ memdelete(vs_editor_singleton);
+ }
#endif
if (visual_script_language)
memdelete(visual_script_language);
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 765fe4c2f2..0834bc81d9 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -2644,6 +2644,11 @@ void VisualScriptLanguage::add_register_func(const String &p_name, VisualScriptN
register_funcs[p_name] = p_func;
}
+void VisualScriptLanguage::remove_register_func(const String &p_name) {
+ ERR_FAIL_COND(!register_funcs.has(p_name));
+ register_funcs.erase(p_name);
+}
+
Ref<VisualScriptNode> VisualScriptLanguage::create_node_from_name(const String &p_name) {
ERR_FAIL_COND_V(!register_funcs.has(p_name), Ref<VisualScriptNode>());
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 0f60b103c9..3e31876941 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -600,6 +600,7 @@ public:
virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max);
void add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func);
+ void remove_register_func(const String &p_name);
Ref<VisualScriptNode> create_node_from_name(const String &p_name);
void get_registered_node_names(List<String> *r_names);
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 15e20effc0..86cf5b27e6 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "visual_script_editor.h"
+#include "core/script_language.h"
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
#include "os/input.h"
@@ -3258,6 +3259,8 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_member_rmb_selected", &VisualScriptEditor::_member_rmb_selected);
ClassDB::bind_method("_member_option", &VisualScriptEditor::_member_option);
+
+ ClassDB::bind_method("_update_available_nodes", &VisualScriptEditor::_update_available_nodes);
}
VisualScriptEditor::VisualScriptEditor() {
@@ -3442,6 +3445,8 @@ VisualScriptEditor::VisualScriptEditor() {
members->connect("item_rmb_selected", this, "_member_rmb_selected");
members->set_allow_rmb_select(true);
member_popup->connect("id_pressed", this, "_member_option");
+
+ _VisualScriptEditor::get_singleton()->connect("custom_nodes_updated", this, "_update_available_nodes");
}
VisualScriptEditor::~VisualScriptEditor() {
@@ -3485,4 +3490,42 @@ void VisualScriptEditor::register_editor() {
EditorNode::add_plugin_init_callback(register_editor_callback);
}
+Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_name) {
+
+ Ref<VisualScriptCustomNode> node;
+ node.instance();
+ node->set_script(singleton->custom_nodes[p_name]);
+ return node;
+}
+
+_VisualScriptEditor *_VisualScriptEditor::singleton = NULL;
+Map<String, RefPtr> _VisualScriptEditor::custom_nodes;
+
+_VisualScriptEditor::_VisualScriptEditor() {
+ singleton = this;
+}
+
+_VisualScriptEditor::~_VisualScriptEditor() {
+ custom_nodes.clear();
+}
+
+void _VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
+ String node_name = "custom/" + p_category + "/" + p_name;
+ custom_nodes.insert(node_name, p_script.get_ref_ptr());
+ VisualScriptLanguage::singleton->add_register_func(node_name, &_VisualScriptEditor::create_node_custom);
+ emit_signal("custom_nodes_updated");
+}
+
+void _VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) {
+ String node_name = "custom/" + p_category + "/" + p_name;
+ custom_nodes.erase(node_name);
+ VisualScriptLanguage::singleton->remove_register_func(node_name);
+ emit_signal("custom_nodes_updated");
+}
+
+void _VisualScriptEditor::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &_VisualScriptEditor::add_custom_node);
+ ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &_VisualScriptEditor::remove_custom_node);
+ ADD_SIGNAL(MethodInfo("custom_nodes_updated"));
+}
#endif
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index db54d10300..3d037e82ea 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -278,6 +278,29 @@ public:
VisualScriptEditor();
~VisualScriptEditor();
};
+
+// Singleton
+class _VisualScriptEditor : public Object {
+ GDCLASS(_VisualScriptEditor, Object);
+
+ friend class VisualScriptLanguage;
+
+protected:
+ static void _bind_methods();
+ static _VisualScriptEditor *singleton;
+
+ static Map<String, RefPtr> custom_nodes;
+ static Ref<VisualScriptNode> create_node_custom(const String &p_name);
+
+public:
+ static _VisualScriptEditor *get_singleton() { return singleton; }
+
+ void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script);
+ void remove_custom_node(const String &p_name, const String &p_category);
+
+ _VisualScriptEditor();
+ ~_VisualScriptEditor();
+};
#endif
#endif // VISUALSCRIPT_EDITOR_H