summaryrefslogtreecommitdiff
path: root/modules/visual_script/visual_script_nodes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/visual_script/visual_script_nodes.cpp')
-rw-r--r--modules/visual_script/visual_script_nodes.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 07be47c96f..009d13a2f2 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -2037,6 +2037,266 @@ VisualScriptSelf::VisualScriptSelf() {
}
+//////////////////////////////////////////
+////////////////CUSTOM (SCRIPTED)///////////
+//////////////////////////////////////////
+
+int VisualScriptCustomNode::get_output_sequence_port_count() const {
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) {
+ return get_script_instance()->call("_get_output_sequence_port_count");
+ }
+ return 0;
+}
+
+bool VisualScriptCustomNode::has_input_sequence_port() const{
+
+ if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) {
+ return get_script_instance()->call("_has_input_sequence_port");
+ }
+ return false;
+}
+
+int VisualScriptCustomNode::get_input_value_port_count() const{
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) {
+ return get_script_instance()->call("_get_input_value_port_count");
+ }
+ return 0;
+}
+int VisualScriptCustomNode::get_output_value_port_count() const{
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) {
+ return get_script_instance()->call("_get_output_value_port_count");
+ }
+ return 0;
+}
+
+String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) {
+ return get_script_instance()->call("_get_output_sequence_port_text",p_port);
+ }
+
+ return String();
+}
+
+PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const{
+
+ PropertyInfo info;
+ if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) {
+ info.type=Variant::Type(int(get_script_instance()->call("_get_input_value_port_type",p_idx)));
+ }
+ if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_name")) {
+ info.name=get_script_instance()->call("_get_input_value_port_name",p_idx);
+ }
+ return info;
+}
+
+PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const{
+
+ PropertyInfo info;
+ if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) {
+ info.type=Variant::Type(int(get_script_instance()->call("_get_output_value_port_type",p_idx)));
+ }
+ if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_name")) {
+ info.name=get_script_instance()->call("_get_output_value_port_name",p_idx);
+ }
+ return info;
+}
+
+
+String VisualScriptCustomNode::get_caption() const {
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_caption")) {
+ return get_script_instance()->call("_get_caption");
+ }
+ return "CustomNode";
+}
+
+String VisualScriptCustomNode::get_text() const {
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_text")) {
+ return get_script_instance()->call("_get_text");
+ }
+ return "";
+}
+
+String VisualScriptCustomNode::get_category() const {
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
+ return get_script_instance()->call("_get_category");
+ }
+ return "custom";
+}
+
+class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance {
+public:
+
+ VisualScriptInstance* instance;
+ VisualScriptCustomNode *node;
+ int in_count;
+ int out_count;
+ int work_mem_size;
+ Vector<bool> out_unsequenced;
+
+ virtual int get_working_memory_size() const { return work_mem_size; }
+ virtual bool is_output_port_unsequenced(int p_idx) const { return out_unsequenced[p_idx]; }
+ virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const {
+
+ if (!node->get_script_instance() || !node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_get_output_port_unsequenced)) {
+#ifdef DEBUG_ENABLED
+ r_error=RTR("Custom node has no _get_output_port_unsequenced(idx,wmem), but unsequenced ports were specified.");
+ return false;
+ }
+#endif
+
+ Array work_mem(true);
+ work_mem.resize(work_mem_size);
+
+ *r_value = node->get_script_instance()->call(VisualScriptLanguage::singleton->_get_output_port_unsequenced,p_idx,work_mem);
+
+
+ for(int i=0;i<work_mem_size;i++) {
+ if (i<work_mem.size()) {
+ p_working_mem[i]=work_mem[i];
+ }
+ }
+
+ return true;
+
+ }
+
+ virtual int step(const Variant** p_inputs,Variant** p_outputs,StartMode p_start_mode,Variant* p_working_mem,Variant::CallError& r_error,String& r_error_str) {
+
+ if (node->get_script_instance()) {
+#ifdef DEBUG_ENABLED
+ if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
+ r_error_str=RTR("Custom node has no _step() method, can't process graph.");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return 0;
+ }
+#endif
+ Array in_values(true);
+ Array out_values(true);
+ Array work_mem(true);
+
+ in_values.resize(in_count);
+
+ for(int i=0;i<in_count;i++) {
+ in_values[i]=p_inputs[i];
+ }
+
+ out_values.resize(in_count);
+
+ work_mem.resize(work_mem_size);
+
+ for(int i=0;i<work_mem_size;i++) {
+ work_mem[i]=p_working_mem[i];
+ }
+
+ int ret_out;
+
+ Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step,in_values,out_values,p_start_mode,work_mem);
+ if (ret.get_type()==Variant::STRING) {
+ r_error_str=ret;
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return 0;
+ } else if (ret.is_num()) {
+ ret_out=ret;
+ } else {
+ r_error_str=RTR("Invalid return value from _step(), must be integer (seq out), or string (error).");
+ r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
+ return 0;
+ }
+
+ for(int i=0;i<out_count;i++) {
+ if (i<out_values.size()) {
+ *p_outputs[i]=out_values[i];
+ }
+ }
+
+ for(int i=0;i<work_mem_size;i++) {
+ if (i<work_mem.size()) {
+ p_working_mem[i]=work_mem[i];
+ }
+ }
+
+ return ret_out;
+
+ }
+
+ return 0;
+ }
+
+
+};
+
+VisualScriptNodeInstance* VisualScriptCustomNode::instance(VisualScriptInstance* p_instance) {
+
+ VisualScriptNodeInstanceCustomNode * instance = memnew(VisualScriptNodeInstanceCustomNode );
+ instance->instance=p_instance;
+ instance->in_count=get_input_value_port_count();
+ instance->out_count=get_output_value_port_count();
+
+ for(int i=0;i<instance->out_count;i++) {
+ bool unseq = get_script_instance() && get_script_instance()->has_method("_is_output_port_unsequenced") && bool(get_script_instance()->call("_is_output_port_unsequenced",i));
+ instance->out_unsequenced.push_back(unseq);
+ }
+
+ if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
+ instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
+ } else {
+ instance->work_mem_size=0;
+ }
+
+ return instance;
+}
+
+
+
+void VisualScriptCustomNode::_bind_methods() {
+
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_sequence_port_count") );
+ BIND_VMETHOD( MethodInfo(Variant::BOOL,"_has_input_sequence_port") );
+
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_output_sequence_port_text",PropertyInfo(Variant::INT,"idx")) );
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_input_value_port_count") );
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_value_port_count") );
+
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_input_value_port_type",PropertyInfo(Variant::INT,"idx")) );
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_input_value_port_name",PropertyInfo(Variant::INT,"idx")) );
+
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_value_port_type",PropertyInfo(Variant::INT,"idx")) );
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_output_value_port_name",PropertyInfo(Variant::INT,"idx")) );
+
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_caption") );
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_text") );
+ BIND_VMETHOD( MethodInfo(Variant::STRING,"_get_category") );
+
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_working_memory_size") );
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_is_output_port_unsequenced",PropertyInfo(Variant::INT,"idx")) );
+ BIND_VMETHOD( MethodInfo(Variant::INT,"_get_output_port_unsequenced",PropertyInfo(Variant::INT,"idx"),PropertyInfo(Variant::ARRAY,"work_mem")) );
+ BIND_VMETHOD( MethodInfo(Variant::NIL,"_step:Variant",PropertyInfo(Variant::ARRAY,"inputs"),PropertyInfo(Variant::ARRAY,"outputs"),PropertyInfo(Variant::INT,"start_mode"),PropertyInfo(Variant::ARRAY,"working_mem")) );
+
+ BIND_CONSTANT( START_MODE_BEGIN_SEQUENCE );
+ BIND_CONSTANT( START_MODE_CONTINUE_SEQUENCE );
+ BIND_CONSTANT( START_MODE_RESUME_YIELD );
+
+ BIND_CONSTANT( STEP_PUSH_STACK_BIT );
+ BIND_CONSTANT( STEP_GO_BACK_BIT );
+ BIND_CONSTANT( STEP_NO_ADVANCE_BIT );
+ BIND_CONSTANT( STEP_EXIT_FUNCTION_BIT );
+ BIND_CONSTANT( STEP_YIELD_BIT );
+
+}
+
+VisualScriptCustomNode::VisualScriptCustomNode() {
+
+
+}
+
+
void register_visual_script_nodes() {
@@ -2050,6 +2310,7 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("data/scene_tree",create_node_generic<VisualScriptSceneTree>);
VisualScriptLanguage::singleton->add_register_func("data/resource_path",create_node_generic<VisualScriptResourcePath>);
VisualScriptLanguage::singleton->add_register_func("data/self",create_node_generic<VisualScriptSelf>);
+ VisualScriptLanguage::singleton->add_register_func("custom/custom_node",create_node_generic<VisualScriptCustomNode>);
VisualScriptLanguage::singleton->add_register_func("index/get_index",create_node_generic<VisualScriptIndexGet>);