1 /*************************************************************************/
2 /*  visual_script_nodes.cpp                                              */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #include "visual_script_nodes.h"
32 
33 #include "core/engine.h"
34 #include "core/global_constants.h"
35 #include "core/os/input.h"
36 #include "core/os/os.h"
37 #include "core/project_settings.h"
38 #include "scene/main/node.h"
39 #include "scene/main/scene_tree.h"
40 
41 //////////////////////////////////////////
42 ////////////////FUNCTION//////////////////
43 //////////////////////////////////////////
44 
_set(const StringName & p_name,const Variant & p_value)45 bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value) {
46 
47 	if (p_name == "argument_count") {
48 
49 		int new_argc = p_value;
50 		int argc = arguments.size();
51 		if (argc == new_argc)
52 			return true;
53 
54 		arguments.resize(new_argc);
55 
56 		for (int i = argc; i < new_argc; i++) {
57 			arguments.write[i].name = "arg" + itos(i + 1);
58 			arguments.write[i].type = Variant::NIL;
59 		}
60 		ports_changed_notify();
61 		_change_notify();
62 		return true;
63 	}
64 	if (String(p_name).begins_with("argument_")) {
65 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
66 		ERR_FAIL_INDEX_V(idx, arguments.size(), false);
67 		String what = String(p_name).get_slice("/", 1);
68 		if (what == "type") {
69 
70 			Variant::Type new_type = Variant::Type(int(p_value));
71 			arguments.write[idx].type = new_type;
72 			ports_changed_notify();
73 
74 			return true;
75 		}
76 
77 		if (what == "name") {
78 
79 			arguments.write[idx].name = p_value;
80 			ports_changed_notify();
81 			return true;
82 		}
83 	}
84 
85 	if (p_name == "stack/stackless") {
86 		set_stack_less(p_value);
87 		return true;
88 	}
89 
90 	if (p_name == "stack/size") {
91 		stack_size = p_value;
92 		return true;
93 	}
94 
95 	if (p_name == "rpc/mode") {
96 		rpc_mode = MultiplayerAPI::RPCMode(int(p_value));
97 		return true;
98 	}
99 
100 	if (p_name == "sequenced/sequenced") {
101 		sequenced = p_value;
102 		ports_changed_notify();
103 		return true;
104 	}
105 
106 	return false;
107 }
108 
_get(const StringName & p_name,Variant & r_ret) const109 bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const {
110 
111 	if (p_name == "argument_count") {
112 		r_ret = arguments.size();
113 		return true;
114 	}
115 	if (String(p_name).begins_with("argument_")) {
116 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
117 		ERR_FAIL_INDEX_V(idx, arguments.size(), false);
118 		String what = String(p_name).get_slice("/", 1);
119 		if (what == "type") {
120 			r_ret = arguments[idx].type;
121 			return true;
122 		}
123 		if (what == "name") {
124 			r_ret = arguments[idx].name;
125 			return true;
126 		}
127 	}
128 
129 	if (p_name == "stack/stackless") {
130 		r_ret = stack_less;
131 		return true;
132 	}
133 
134 	if (p_name == "stack/size") {
135 		r_ret = stack_size;
136 		return true;
137 	}
138 
139 	if (p_name == "rpc/mode") {
140 		r_ret = rpc_mode;
141 		return true;
142 	}
143 
144 	if (p_name == "sequenced/sequenced") {
145 		r_ret = sequenced;
146 		return true;
147 	}
148 
149 	return false;
150 }
_get_property_list(List<PropertyInfo> * p_list) const151 void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const {
152 
153 	p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256"));
154 	String argt = "Any";
155 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
156 		argt += "," + Variant::get_type_name(Variant::Type(i));
157 	}
158 
159 	for (int i = 0; i < arguments.size(); i++) {
160 		p_list->push_back(PropertyInfo(Variant::INT, "argument_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));
161 		p_list->push_back(PropertyInfo(Variant::STRING, "argument_" + itos(i + 1) + "/name"));
162 	}
163 
164 	p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced"));
165 
166 	if (!stack_less) {
167 		p_list->push_back(PropertyInfo(Variant::INT, "stack/size", PROPERTY_HINT_RANGE, "1,100000"));
168 	}
169 	p_list->push_back(PropertyInfo(Variant::BOOL, "stack/stackless"));
170 	p_list->push_back(PropertyInfo(Variant::INT, "rpc/mode", PROPERTY_HINT_ENUM, "Disabled,Remote,Master,Puppet,Remote Sync,Master Sync,Puppet Sync"));
171 }
172 
get_output_sequence_port_count() const173 int VisualScriptFunction::get_output_sequence_port_count() const {
174 
175 	return 1;
176 }
177 
has_input_sequence_port() const178 bool VisualScriptFunction::has_input_sequence_port() const {
179 
180 	return false;
181 }
182 
get_input_value_port_count() const183 int VisualScriptFunction::get_input_value_port_count() const {
184 
185 	return 0;
186 }
get_output_value_port_count() const187 int VisualScriptFunction::get_output_value_port_count() const {
188 
189 	return arguments.size();
190 }
191 
get_output_sequence_port_text(int p_port) const192 String VisualScriptFunction::get_output_sequence_port_text(int p_port) const {
193 
194 	return String();
195 }
196 
get_input_value_port_info(int p_idx) const197 PropertyInfo VisualScriptFunction::get_input_value_port_info(int p_idx) const {
198 
199 	ERR_FAIL_V(PropertyInfo());
200 }
get_output_value_port_info(int p_idx) const201 PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
202 
203 	ERR_FAIL_INDEX_V(p_idx, arguments.size(), PropertyInfo());
204 	PropertyInfo out;
205 	out.type = arguments[p_idx].type;
206 	out.name = arguments[p_idx].name;
207 	out.hint = arguments[p_idx].hint;
208 	out.hint_string = arguments[p_idx].hint_string;
209 	return out;
210 }
211 
get_caption() const212 String VisualScriptFunction::get_caption() const {
213 
214 	return "Function";
215 }
216 
get_text() const217 String VisualScriptFunction::get_text() const {
218 
219 	return get_name(); //use name as function name I guess
220 }
221 
add_argument(Variant::Type p_type,const String & p_name,int p_index,const PropertyHint p_hint,const String & p_hint_string)222 void VisualScriptFunction::add_argument(Variant::Type p_type, const String &p_name, int p_index, const PropertyHint p_hint, const String &p_hint_string) {
223 
224 	Argument arg;
225 	arg.name = p_name;
226 	arg.type = p_type;
227 	arg.hint = p_hint;
228 	arg.hint_string = p_hint_string;
229 	if (p_index >= 0)
230 		arguments.insert(p_index, arg);
231 	else
232 		arguments.push_back(arg);
233 
234 	ports_changed_notify();
235 }
set_argument_type(int p_argidx,Variant::Type p_type)236 void VisualScriptFunction::set_argument_type(int p_argidx, Variant::Type p_type) {
237 
238 	ERR_FAIL_INDEX(p_argidx, arguments.size());
239 
240 	arguments.write[p_argidx].type = p_type;
241 	ports_changed_notify();
242 }
get_argument_type(int p_argidx) const243 Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const {
244 
245 	ERR_FAIL_INDEX_V(p_argidx, arguments.size(), Variant::NIL);
246 	return arguments[p_argidx].type;
247 }
set_argument_name(int p_argidx,const String & p_name)248 void VisualScriptFunction::set_argument_name(int p_argidx, const String &p_name) {
249 
250 	ERR_FAIL_INDEX(p_argidx, arguments.size());
251 
252 	arguments.write[p_argidx].name = p_name;
253 	ports_changed_notify();
254 }
get_argument_name(int p_argidx) const255 String VisualScriptFunction::get_argument_name(int p_argidx) const {
256 
257 	ERR_FAIL_INDEX_V(p_argidx, arguments.size(), String());
258 	return arguments[p_argidx].name;
259 }
remove_argument(int p_argidx)260 void VisualScriptFunction::remove_argument(int p_argidx) {
261 
262 	ERR_FAIL_INDEX(p_argidx, arguments.size());
263 
264 	arguments.remove(p_argidx);
265 	ports_changed_notify();
266 }
267 
get_argument_count() const268 int VisualScriptFunction::get_argument_count() const {
269 
270 	return arguments.size();
271 }
272 
set_rpc_mode(MultiplayerAPI::RPCMode p_mode)273 void VisualScriptFunction::set_rpc_mode(MultiplayerAPI::RPCMode p_mode) {
274 	rpc_mode = p_mode;
275 }
276 
get_rpc_mode() const277 MultiplayerAPI::RPCMode VisualScriptFunction::get_rpc_mode() const {
278 	return rpc_mode;
279 }
280 
281 class VisualScriptNodeInstanceFunction : public VisualScriptNodeInstance {
282 public:
283 	VisualScriptFunction *node;
284 	VisualScriptInstance *instance;
285 
286 	//virtual int get_working_memory_size() const { return 0; }
287 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)288 	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) {
289 
290 		int ac = node->get_argument_count();
291 
292 		for (int i = 0; i < ac; i++) {
293 #ifdef DEBUG_ENABLED
294 			Variant::Type expected = node->get_argument_type(i);
295 			if (expected != Variant::NIL) {
296 				if (!Variant::can_convert_strict(p_inputs[i]->get_type(), expected)) {
297 					r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
298 					r_error.expected = expected;
299 					r_error.argument = i;
300 					return 0;
301 				}
302 			}
303 #endif
304 
305 			*p_outputs[i] = *p_inputs[i];
306 		}
307 
308 		return 0;
309 	}
310 };
311 
instance(VisualScriptInstance * p_instance)312 VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p_instance) {
313 
314 	VisualScriptNodeInstanceFunction *instance = memnew(VisualScriptNodeInstanceFunction);
315 	instance->node = this;
316 	instance->instance = p_instance;
317 	return instance;
318 }
319 
VisualScriptFunction()320 VisualScriptFunction::VisualScriptFunction() {
321 
322 	stack_size = 256;
323 	stack_less = false;
324 	sequenced = true;
325 	rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
326 }
327 
set_stack_less(bool p_enable)328 void VisualScriptFunction::set_stack_less(bool p_enable) {
329 	stack_less = p_enable;
330 	_change_notify();
331 }
332 
is_stack_less() const333 bool VisualScriptFunction::is_stack_less() const {
334 	return stack_less;
335 }
336 
set_sequenced(bool p_enable)337 void VisualScriptFunction::set_sequenced(bool p_enable) {
338 
339 	sequenced = p_enable;
340 }
341 
is_sequenced() const342 bool VisualScriptFunction::is_sequenced() const {
343 
344 	return sequenced;
345 }
346 
set_stack_size(int p_size)347 void VisualScriptFunction::set_stack_size(int p_size) {
348 
349 	ERR_FAIL_COND(p_size < 1 || p_size > 100000);
350 	stack_size = p_size;
351 }
352 
get_stack_size() const353 int VisualScriptFunction::get_stack_size() const {
354 
355 	return stack_size;
356 }
357 
358 //////////////////////////////////////////
359 /////////////////LISTS////////////////////
360 //////////////////////////////////////////
361 
get_output_sequence_port_count() const362 int VisualScriptLists::get_output_sequence_port_count() const {
363 	if (sequenced)
364 		return 1;
365 	return 0;
366 }
has_input_sequence_port() const367 bool VisualScriptLists::has_input_sequence_port() const {
368 	return sequenced;
369 }
370 
get_output_sequence_port_text(int p_port) const371 String VisualScriptLists::get_output_sequence_port_text(int p_port) const {
372 	return "";
373 }
374 
get_input_value_port_count() const375 int VisualScriptLists::get_input_value_port_count() const {
376 	return inputports.size();
377 }
get_output_value_port_count() const378 int VisualScriptLists::get_output_value_port_count() const {
379 	return outputports.size();
380 }
381 
get_input_value_port_info(int p_idx) const382 PropertyInfo VisualScriptLists::get_input_value_port_info(int p_idx) const {
383 	ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());
384 
385 	PropertyInfo pi;
386 	pi.name = inputports[p_idx].name;
387 	pi.type = inputports[p_idx].type;
388 	return pi;
389 }
get_output_value_port_info(int p_idx) const390 PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const {
391 	ERR_FAIL_INDEX_V(p_idx, outputports.size(), PropertyInfo());
392 
393 	PropertyInfo pi;
394 	pi.name = outputports[p_idx].name;
395 	pi.type = outputports[p_idx].type;
396 	return pi;
397 }
398 
is_input_port_editable() const399 bool VisualScriptLists::is_input_port_editable() const {
400 	return ((flags & INPUT_EDITABLE) == INPUT_EDITABLE);
401 }
is_input_port_name_editable() const402 bool VisualScriptLists::is_input_port_name_editable() const {
403 	return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
404 }
is_input_port_type_editable() const405 bool VisualScriptLists::is_input_port_type_editable() const {
406 	return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
407 }
408 
is_output_port_editable() const409 bool VisualScriptLists::is_output_port_editable() const {
410 	return ((flags & OUTPUT_EDITABLE) == OUTPUT_EDITABLE);
411 }
is_output_port_name_editable() const412 bool VisualScriptLists::is_output_port_name_editable() const {
413 	return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
414 }
is_output_port_type_editable() const415 bool VisualScriptLists::is_output_port_type_editable() const {
416 	return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
417 }
418 
419 // for the inspector
_set(const StringName & p_name,const Variant & p_value)420 bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
421 
422 	if (p_name == "input_count" && is_input_port_editable()) {
423 
424 		int new_argc = p_value;
425 		int argc = inputports.size();
426 		if (argc == new_argc)
427 			return true;
428 
429 		inputports.resize(new_argc);
430 
431 		for (int i = argc; i < new_argc; i++) {
432 			inputports.write[i].name = "arg" + itos(i + 1);
433 			inputports.write[i].type = Variant::NIL;
434 		}
435 		ports_changed_notify();
436 		_change_notify();
437 		return true;
438 	}
439 	if (String(p_name).begins_with("input_") && is_input_port_editable()) {
440 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
441 		ERR_FAIL_INDEX_V(idx, inputports.size(), false);
442 		String what = String(p_name).get_slice("/", 1);
443 		if (what == "type") {
444 
445 			Variant::Type new_type = Variant::Type(int(p_value));
446 			inputports.write[idx].type = new_type;
447 			ports_changed_notify();
448 
449 			return true;
450 		}
451 
452 		if (what == "name") {
453 
454 			inputports.write[idx].name = p_value;
455 			ports_changed_notify();
456 			return true;
457 		}
458 	}
459 
460 	if (p_name == "output_count" && is_output_port_editable()) {
461 
462 		int new_argc = p_value;
463 		int argc = outputports.size();
464 		if (argc == new_argc)
465 			return true;
466 
467 		outputports.resize(new_argc);
468 
469 		for (int i = argc; i < new_argc; i++) {
470 			outputports.write[i].name = "arg" + itos(i + 1);
471 			outputports.write[i].type = Variant::NIL;
472 		}
473 		ports_changed_notify();
474 		_change_notify();
475 		return true;
476 	}
477 	if (String(p_name).begins_with("output_") && is_output_port_editable()) {
478 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
479 		ERR_FAIL_INDEX_V(idx, outputports.size(), false);
480 		String what = String(p_name).get_slice("/", 1);
481 		if (what == "type") {
482 
483 			Variant::Type new_type = Variant::Type(int(p_value));
484 			outputports.write[idx].type = new_type;
485 			ports_changed_notify();
486 
487 			return true;
488 		}
489 
490 		if (what == "name") {
491 
492 			outputports.write[idx].name = p_value;
493 			ports_changed_notify();
494 			return true;
495 		}
496 	}
497 
498 	if (p_name == "sequenced/sequenced") {
499 		sequenced = p_value;
500 		ports_changed_notify();
501 		return true;
502 	}
503 
504 	return false;
505 }
_get(const StringName & p_name,Variant & r_ret) const506 bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {
507 
508 	if (p_name == "input_count" && is_input_port_editable()) {
509 		r_ret = inputports.size();
510 		return true;
511 	}
512 	if (String(p_name).begins_with("input_") && is_input_port_editable()) {
513 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
514 		ERR_FAIL_INDEX_V(idx, inputports.size(), false);
515 		String what = String(p_name).get_slice("/", 1);
516 		if (what == "type") {
517 			r_ret = inputports[idx].type;
518 			return true;
519 		}
520 		if (what == "name") {
521 			r_ret = inputports[idx].name;
522 			return true;
523 		}
524 	}
525 
526 	if (p_name == "output_count" && is_output_port_editable()) {
527 		r_ret = outputports.size();
528 		return true;
529 	}
530 	if (String(p_name).begins_with("output_") && is_output_port_editable()) {
531 		int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int() - 1;
532 		ERR_FAIL_INDEX_V(idx, outputports.size(), false);
533 		String what = String(p_name).get_slice("/", 1);
534 		if (what == "type") {
535 			r_ret = outputports[idx].type;
536 			return true;
537 		}
538 		if (what == "name") {
539 			r_ret = outputports[idx].name;
540 			return true;
541 		}
542 	}
543 
544 	if (p_name == "sequenced/sequenced") {
545 		r_ret = sequenced;
546 		return true;
547 	}
548 
549 	return false;
550 }
_get_property_list(List<PropertyInfo> * p_list) const551 void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {
552 
553 	if (is_input_port_editable()) {
554 		p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,256"));
555 		String argt = "Any";
556 		for (int i = 1; i < Variant::VARIANT_MAX; i++) {
557 			argt += "," + Variant::get_type_name(Variant::Type(i));
558 		}
559 
560 		for (int i = 0; i < inputports.size(); i++) {
561 			p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));
562 			p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i + 1) + "/name"));
563 		}
564 	}
565 
566 	if (is_output_port_editable()) {
567 		p_list->push_back(PropertyInfo(Variant::INT, "output_count", PROPERTY_HINT_RANGE, "0,256"));
568 		String argt = "Any";
569 		for (int i = 1; i < Variant::VARIANT_MAX; i++) {
570 			argt += "," + Variant::get_type_name(Variant::Type(i));
571 		}
572 
573 		for (int i = 0; i < outputports.size(); i++) {
574 			p_list->push_back(PropertyInfo(Variant::INT, "output_" + itos(i + 1) + "/type", PROPERTY_HINT_ENUM, argt));
575 			p_list->push_back(PropertyInfo(Variant::STRING, "output_" + itos(i + 1) + "/name"));
576 		}
577 	}
578 	p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced/sequenced"));
579 }
580 
581 // input data port interaction
add_input_data_port(Variant::Type p_type,const String & p_name,int p_index)582 void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &p_name, int p_index) {
583 
584 	if (!is_input_port_editable())
585 		return;
586 
587 	Port inp;
588 	inp.name = p_name;
589 	inp.type = p_type;
590 	if (p_index >= 0)
591 		inputports.insert(p_index, inp);
592 	else
593 		inputports.push_back(inp);
594 
595 	ports_changed_notify();
596 	_change_notify();
597 }
set_input_data_port_type(int p_idx,Variant::Type p_type)598 void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {
599 
600 	if (!is_input_port_type_editable())
601 		return;
602 
603 	ERR_FAIL_INDEX(p_idx, inputports.size());
604 
605 	inputports.write[p_idx].type = p_type;
606 	ports_changed_notify();
607 	_change_notify();
608 }
set_input_data_port_name(int p_idx,const String & p_name)609 void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {
610 
611 	if (!is_input_port_name_editable())
612 		return;
613 
614 	ERR_FAIL_INDEX(p_idx, inputports.size());
615 
616 	inputports.write[p_idx].name = p_name;
617 	ports_changed_notify();
618 	_change_notify();
619 }
remove_input_data_port(int p_argidx)620 void VisualScriptLists::remove_input_data_port(int p_argidx) {
621 
622 	if (!is_input_port_editable())
623 		return;
624 
625 	ERR_FAIL_INDEX(p_argidx, inputports.size());
626 
627 	inputports.remove(p_argidx);
628 
629 	ports_changed_notify();
630 	_change_notify();
631 }
632 
633 // output data port interaction
add_output_data_port(Variant::Type p_type,const String & p_name,int p_index)634 void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String &p_name, int p_index) {
635 
636 	if (!is_output_port_editable())
637 		return;
638 
639 	Port out;
640 	out.name = p_name;
641 	out.type = p_type;
642 	if (p_index >= 0)
643 		outputports.insert(p_index, out);
644 	else
645 		outputports.push_back(out);
646 
647 	ports_changed_notify();
648 	_change_notify();
649 }
set_output_data_port_type(int p_idx,Variant::Type p_type)650 void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {
651 
652 	if (!is_output_port_type_editable())
653 		return;
654 
655 	ERR_FAIL_INDEX(p_idx, outputports.size());
656 
657 	outputports.write[p_idx].type = p_type;
658 	ports_changed_notify();
659 	_change_notify();
660 }
set_output_data_port_name(int p_idx,const String & p_name)661 void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {
662 
663 	if (!is_output_port_name_editable())
664 		return;
665 
666 	ERR_FAIL_INDEX(p_idx, outputports.size());
667 
668 	outputports.write[p_idx].name = p_name;
669 	ports_changed_notify();
670 	_change_notify();
671 }
remove_output_data_port(int p_argidx)672 void VisualScriptLists::remove_output_data_port(int p_argidx) {
673 
674 	if (!is_output_port_editable())
675 		return;
676 
677 	ERR_FAIL_INDEX(p_argidx, outputports.size());
678 
679 	outputports.remove(p_argidx);
680 
681 	ports_changed_notify();
682 	_change_notify();
683 }
684 
685 // sequences
set_sequenced(bool p_enable)686 void VisualScriptLists::set_sequenced(bool p_enable) {
687 	if (sequenced == p_enable)
688 		return;
689 	sequenced = p_enable;
690 	ports_changed_notify();
691 }
is_sequenced() const692 bool VisualScriptLists::is_sequenced() const {
693 	return sequenced;
694 }
695 
VisualScriptLists()696 VisualScriptLists::VisualScriptLists() {
697 	// initialize
698 	sequenced = false;
699 	flags = 0;
700 }
701 
_bind_methods()702 void VisualScriptLists::_bind_methods() {
703 	ClassDB::bind_method(D_METHOD("add_input_data_port", "type", "name", "index"), &VisualScriptLists::add_input_data_port);
704 	ClassDB::bind_method(D_METHOD("set_input_data_port_name", "index", "name"), &VisualScriptLists::set_input_data_port_name);
705 	ClassDB::bind_method(D_METHOD("set_input_data_port_type", "index", "type"), &VisualScriptLists::set_input_data_port_type);
706 	ClassDB::bind_method(D_METHOD("remove_input_data_port", "index"), &VisualScriptLists::remove_input_data_port);
707 
708 	ClassDB::bind_method(D_METHOD("add_output_data_port", "type", "name", "index"), &VisualScriptLists::add_output_data_port);
709 	ClassDB::bind_method(D_METHOD("set_output_data_port_name", "index", "name"), &VisualScriptLists::set_output_data_port_name);
710 	ClassDB::bind_method(D_METHOD("set_output_data_port_type", "index", "type"), &VisualScriptLists::set_output_data_port_type);
711 	ClassDB::bind_method(D_METHOD("remove_output_data_port", "index"), &VisualScriptLists::remove_output_data_port);
712 }
713 
714 //////////////////////////////////////////
715 //////////////COMPOSEARRAY////////////////
716 //////////////////////////////////////////
717 
get_output_sequence_port_count() const718 int VisualScriptComposeArray::get_output_sequence_port_count() const {
719 	if (sequenced)
720 		return 1;
721 	return 0;
722 }
has_input_sequence_port() const723 bool VisualScriptComposeArray::has_input_sequence_port() const {
724 	return sequenced;
725 }
726 
get_output_sequence_port_text(int p_port) const727 String VisualScriptComposeArray::get_output_sequence_port_text(int p_port) const {
728 	return "";
729 }
730 
get_input_value_port_count() const731 int VisualScriptComposeArray::get_input_value_port_count() const {
732 	return inputports.size();
733 }
get_output_value_port_count() const734 int VisualScriptComposeArray::get_output_value_port_count() const {
735 	return 1;
736 }
737 
get_input_value_port_info(int p_idx) const738 PropertyInfo VisualScriptComposeArray::get_input_value_port_info(int p_idx) const {
739 	ERR_FAIL_INDEX_V(p_idx, inputports.size(), PropertyInfo());
740 
741 	PropertyInfo pi;
742 	pi.name = inputports[p_idx].name;
743 	pi.type = inputports[p_idx].type;
744 	return pi;
745 }
get_output_value_port_info(int p_idx) const746 PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) const {
747 	PropertyInfo pi;
748 	pi.name = "out";
749 	pi.type = Variant::ARRAY;
750 	return pi;
751 }
752 
get_caption() const753 String VisualScriptComposeArray::get_caption() const {
754 	return "Compose Array";
755 }
get_text() const756 String VisualScriptComposeArray::get_text() const {
757 	return "";
758 }
759 
760 class VisualScriptComposeArrayNode : public VisualScriptNodeInstance {
761 public:
762 	int input_count = 0;
get_working_memory_size() const763 	virtual int get_working_memory_size() const { return 0; }
764 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)765 	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) {
766 
767 		if (input_count > 0) {
768 			Array arr;
769 			for (int i = 0; i < input_count; i++)
770 				arr.push_back((*p_inputs[i]));
771 			Variant va = Variant(arr);
772 
773 			*p_outputs[0] = va;
774 		}
775 
776 		return 0;
777 	}
778 };
779 
instance(VisualScriptInstance * p_instance)780 VisualScriptNodeInstance *VisualScriptComposeArray::instance(VisualScriptInstance *p_instance) {
781 
782 	VisualScriptComposeArrayNode *instance = memnew(VisualScriptComposeArrayNode);
783 	instance->input_count = inputports.size();
784 	return instance;
785 }
786 
VisualScriptComposeArray()787 VisualScriptComposeArray::VisualScriptComposeArray() {
788 	// initialize stuff here
789 	sequenced = false;
790 	flags = INPUT_EDITABLE;
791 }
792 
793 //////////////////////////////////////////
794 ////////////////OPERATOR//////////////////
795 //////////////////////////////////////////
796 
get_output_sequence_port_count() const797 int VisualScriptOperator::get_output_sequence_port_count() const {
798 
799 	return 0;
800 }
801 
has_input_sequence_port() const802 bool VisualScriptOperator::has_input_sequence_port() const {
803 
804 	return false;
805 }
806 
get_input_value_port_count() const807 int VisualScriptOperator::get_input_value_port_count() const {
808 
809 	return (op == Variant::OP_BIT_NEGATE || op == Variant::OP_NOT || op == Variant::OP_NEGATE || op == Variant::OP_POSITIVE) ? 1 : 2;
810 }
get_output_value_port_count() const811 int VisualScriptOperator::get_output_value_port_count() const {
812 
813 	return 1;
814 }
815 
get_output_sequence_port_text(int p_port) const816 String VisualScriptOperator::get_output_sequence_port_text(int p_port) const {
817 
818 	return String();
819 }
820 
get_input_value_port_info(int p_idx) const821 PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const {
822 
823 	static const Variant::Type port_types[Variant::OP_MAX][2] = {
824 		{ Variant::NIL, Variant::NIL }, //OP_EQUAL,
825 		{ Variant::NIL, Variant::NIL }, //OP_NOT_EQUAL,
826 		{ Variant::NIL, Variant::NIL }, //OP_LESS,
827 		{ Variant::NIL, Variant::NIL }, //OP_LESS_EQUAL,
828 		{ Variant::NIL, Variant::NIL }, //OP_GREATER,
829 		{ Variant::NIL, Variant::NIL }, //OP_GREATER_EQUAL,
830 		//mathematic
831 		{ Variant::NIL, Variant::NIL }, //OP_ADD,
832 		{ Variant::NIL, Variant::NIL }, //OP_SUBTRACT,
833 		{ Variant::NIL, Variant::NIL }, //OP_MULTIPLY,
834 		{ Variant::NIL, Variant::NIL }, //OP_DIVIDE,
835 		{ Variant::NIL, Variant::NIL }, //OP_NEGATE,
836 		{ Variant::NIL, Variant::NIL }, //OP_POSITIVE,
837 		{ Variant::INT, Variant::INT }, //OP_MODULE,
838 		{ Variant::STRING, Variant::STRING }, //OP_STRING_CONCAT,
839 		//bitwise
840 		{ Variant::INT, Variant::INT }, //OP_SHIFT_LEFT,
841 		{ Variant::INT, Variant::INT }, //OP_SHIFT_RIGHT,
842 		{ Variant::INT, Variant::INT }, //OP_BIT_AND,
843 		{ Variant::INT, Variant::INT }, //OP_BIT_OR,
844 		{ Variant::INT, Variant::INT }, //OP_BIT_XOR,
845 		{ Variant::INT, Variant::INT }, //OP_BIT_NEGATE,
846 		//logic
847 		{ Variant::BOOL, Variant::BOOL }, //OP_AND,
848 		{ Variant::BOOL, Variant::BOOL }, //OP_OR,
849 		{ Variant::BOOL, Variant::BOOL }, //OP_XOR,
850 		{ Variant::BOOL, Variant::BOOL }, //OP_NOT,
851 		//containment
852 		{ Variant::NIL, Variant::NIL } //OP_IN,
853 	};
854 
855 	ERR_FAIL_INDEX_V(p_idx, 2, PropertyInfo());
856 
857 	PropertyInfo pinfo;
858 	pinfo.name = p_idx == 0 ? "A" : "B";
859 	pinfo.type = port_types[op][p_idx];
860 	if (pinfo.type == Variant::NIL)
861 		pinfo.type = typed;
862 	return pinfo;
863 }
get_output_value_port_info(int p_idx) const864 PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const {
865 	static const Variant::Type port_types[Variant::OP_MAX] = {
866 		//comparison
867 		Variant::BOOL, //OP_EQUAL,
868 		Variant::BOOL, //OP_NOT_EQUAL,
869 		Variant::BOOL, //OP_LESS,
870 		Variant::BOOL, //OP_LESS_EQUAL,
871 		Variant::BOOL, //OP_GREATER,
872 		Variant::BOOL, //OP_GREATER_EQUAL,
873 		//mathematic
874 		Variant::NIL, //OP_ADD,
875 		Variant::NIL, //OP_SUBTRACT,
876 		Variant::NIL, //OP_MULTIPLY,
877 		Variant::NIL, //OP_DIVIDE,
878 		Variant::NIL, //OP_NEGATE,
879 		Variant::NIL, //OP_POSITIVE,
880 		Variant::INT, //OP_MODULE,
881 		Variant::STRING, //OP_STRING_CONCAT,
882 		//bitwise
883 		Variant::INT, //OP_SHIFT_LEFT,
884 		Variant::INT, //OP_SHIFT_RIGHT,
885 		Variant::INT, //OP_BIT_AND,
886 		Variant::INT, //OP_BIT_OR,
887 		Variant::INT, //OP_BIT_XOR,
888 		Variant::INT, //OP_BIT_NEGATE,
889 		//logic
890 		Variant::BOOL, //OP_AND,
891 		Variant::BOOL, //OP_OR,
892 		Variant::BOOL, //OP_XOR,
893 		Variant::BOOL, //OP_NOT,
894 		//containment
895 		Variant::BOOL //OP_IN,
896 	};
897 
898 	PropertyInfo pinfo;
899 	pinfo.name = "";
900 	pinfo.type = port_types[op];
901 	if (pinfo.type == Variant::NIL)
902 		pinfo.type = typed;
903 	return pinfo;
904 }
905 
906 static const char *op_names[] = {
907 	//comparison
908 	"Are Equal", //OP_EQUAL,
909 	"Are Not Equal", //OP_NOT_EQUAL,
910 	"Less Than", //OP_LESS,
911 	"Less Than or Equal", //OP_LESS_EQUAL,
912 	"Greater Than", //OP_GREATER,
913 	"Greater Than or Equal", //OP_GREATER_EQUAL,
914 	//mathematic
915 	"Add", //OP_ADD,
916 	"Subtract", //OP_SUBTRACT,
917 	"Multiply", //OP_MULTIPLY,
918 	"Divide", //OP_DIVIDE,
919 	"Negate", //OP_NEGATE,
920 	"Positive", //OP_POSITIVE,
921 	"Remainder", //OP_MODULE,
922 	"Concatenate", //OP_STRING_CONCAT,
923 	//bitwise
924 	"Bit Shift Left", //OP_SHIFT_LEFT,
925 	"Bit Shift Right", //OP_SHIFT_RIGHT,
926 	"Bit And", //OP_BIT_AND,
927 	"Bit Or", //OP_BIT_OR,
928 	"Bit Xor", //OP_BIT_XOR,
929 	"Bit Negate", //OP_BIT_NEGATE,
930 	//logic
931 	"And", //OP_AND,
932 	"Or", //OP_OR,
933 	"Xor", //OP_XOR,
934 	"Not", //OP_NOT,
935 	//containment
936 	"In", //OP_IN,
937 };
938 
get_caption() const939 String VisualScriptOperator::get_caption() const {
940 
941 	static const wchar_t *op_names[] = {
942 		//comparison
943 		L"A = B", //OP_EQUAL,
944 		L"A \u2260 B", //OP_NOT_EQUAL,
945 		L"A < B", //OP_LESS,
946 		L"A \u2264 B", //OP_LESS_EQUAL,
947 		L"A > B", //OP_GREATER,
948 		L"A \u2265 B", //OP_GREATER_EQUAL,
949 		//mathematic
950 		L"A + B", //OP_ADD,
951 		L"A - B", //OP_SUBTRACT,
952 		L"A \u00D7 B", //OP_MULTIPLY,
953 		L"A \u00F7 B", //OP_DIVIDE,
954 		L"\u00AC A", //OP_NEGATE,
955 		L"+ A", //OP_POSITIVE,
956 		L"A mod B", //OP_MODULE,
957 		L"A .. B", //OP_STRING_CONCAT,
958 		//bitwise
959 		L"A << B", //OP_SHIFT_LEFT,
960 		L"A >> B", //OP_SHIFT_RIGHT,
961 		L"A & B", //OP_BIT_AND,
962 		L"A | B", //OP_BIT_OR,
963 		L"A ^ B", //OP_BIT_XOR,
964 		L"~A", //OP_BIT_NEGATE,
965 		//logic
966 		L"A and B", //OP_AND,
967 		L"A or B", //OP_OR,
968 		L"A xor B", //OP_XOR,
969 		L"not A", //OP_NOT,
970 		L"A in B", //OP_IN,
971 
972 	};
973 	return op_names[op];
974 }
975 
set_operator(Variant::Operator p_op)976 void VisualScriptOperator::set_operator(Variant::Operator p_op) {
977 
978 	if (op == p_op)
979 		return;
980 	op = p_op;
981 	ports_changed_notify();
982 }
983 
get_operator() const984 Variant::Operator VisualScriptOperator::get_operator() const {
985 
986 	return op;
987 }
988 
set_typed(Variant::Type p_op)989 void VisualScriptOperator::set_typed(Variant::Type p_op) {
990 
991 	if (typed == p_op)
992 		return;
993 
994 	typed = p_op;
995 	ports_changed_notify();
996 }
997 
get_typed() const998 Variant::Type VisualScriptOperator::get_typed() const {
999 
1000 	return typed;
1001 }
1002 
_bind_methods()1003 void VisualScriptOperator::_bind_methods() {
1004 
1005 	ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualScriptOperator::set_operator);
1006 	ClassDB::bind_method(D_METHOD("get_operator"), &VisualScriptOperator::get_operator);
1007 
1008 	ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptOperator::set_typed);
1009 	ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptOperator::get_typed);
1010 
1011 	String types;
1012 	for (int i = 0; i < Variant::OP_MAX; i++) {
1013 		if (i > 0)
1014 			types += ",";
1015 		types += op_names[i];
1016 	}
1017 
1018 	String argt = "Any";
1019 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
1020 		argt += "," + Variant::get_type_name(Variant::Type(i));
1021 	}
1022 
1023 	ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, types), "set_operator", "get_operator");
1024 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed");
1025 }
1026 
1027 class VisualScriptNodeInstanceOperator : public VisualScriptNodeInstance {
1028 public:
1029 	bool unary;
1030 	Variant::Operator op;
1031 
1032 	//virtual int get_working_memory_size() const { return 0; }
1033 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1034 	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) {
1035 
1036 		bool valid;
1037 		if (unary) {
1038 
1039 			Variant::evaluate(op, *p_inputs[0], Variant(), *p_outputs[0], valid);
1040 		} else {
1041 			Variant::evaluate(op, *p_inputs[0], *p_inputs[1], *p_outputs[0], valid);
1042 		}
1043 
1044 		if (!valid) {
1045 
1046 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1047 			if (p_outputs[0]->get_type() == Variant::STRING) {
1048 				r_error_str = *p_outputs[0];
1049 			} else {
1050 				if (unary)
1051 					r_error_str = String(op_names[op]) + RTR(": Invalid argument of type: ") + Variant::get_type_name(p_inputs[0]->get_type());
1052 				else
1053 					r_error_str = String(op_names[op]) + RTR(": Invalid arguments: ") + "A: " + Variant::get_type_name(p_inputs[0]->get_type()) + "  B: " + Variant::get_type_name(p_inputs[1]->get_type());
1054 			}
1055 		}
1056 
1057 		return 0;
1058 	}
1059 };
1060 
instance(VisualScriptInstance * p_instance)1061 VisualScriptNodeInstance *VisualScriptOperator::instance(VisualScriptInstance *p_instance) {
1062 
1063 	VisualScriptNodeInstanceOperator *instance = memnew(VisualScriptNodeInstanceOperator);
1064 	instance->unary = get_input_value_port_count() == 1;
1065 	instance->op = op;
1066 	return instance;
1067 }
1068 
VisualScriptOperator()1069 VisualScriptOperator::VisualScriptOperator() {
1070 
1071 	op = Variant::OP_ADD;
1072 	typed = Variant::NIL;
1073 }
1074 
1075 template <Variant::Operator OP>
create_op_node(const String & p_name)1076 static Ref<VisualScriptNode> create_op_node(const String &p_name) {
1077 
1078 	Ref<VisualScriptOperator> node;
1079 	node.instance();
1080 	node->set_operator(OP);
1081 	return node;
1082 }
1083 
1084 //////////////////////////////////////////
1085 ////////////////OPERATOR//////////////////
1086 //////////////////////////////////////////
1087 
get_output_sequence_port_count() const1088 int VisualScriptSelect::get_output_sequence_port_count() const {
1089 
1090 	return 0;
1091 }
1092 
has_input_sequence_port() const1093 bool VisualScriptSelect::has_input_sequence_port() const {
1094 
1095 	return false;
1096 }
1097 
get_input_value_port_count() const1098 int VisualScriptSelect::get_input_value_port_count() const {
1099 
1100 	return 3;
1101 }
get_output_value_port_count() const1102 int VisualScriptSelect::get_output_value_port_count() const {
1103 
1104 	return 1;
1105 }
1106 
get_output_sequence_port_text(int p_port) const1107 String VisualScriptSelect::get_output_sequence_port_text(int p_port) const {
1108 
1109 	return String();
1110 }
1111 
get_input_value_port_info(int p_idx) const1112 PropertyInfo VisualScriptSelect::get_input_value_port_info(int p_idx) const {
1113 
1114 	if (p_idx == 0) {
1115 		return PropertyInfo(Variant::BOOL, "cond");
1116 	} else if (p_idx == 1) {
1117 		return PropertyInfo(typed, "a");
1118 	} else {
1119 		return PropertyInfo(typed, "b");
1120 	}
1121 }
get_output_value_port_info(int p_idx) const1122 PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const {
1123 
1124 	return PropertyInfo(typed, "out");
1125 }
1126 
get_caption() const1127 String VisualScriptSelect::get_caption() const {
1128 
1129 	return "Select";
1130 }
1131 
get_text() const1132 String VisualScriptSelect::get_text() const {
1133 
1134 	return "a if cond, else b";
1135 }
1136 
set_typed(Variant::Type p_op)1137 void VisualScriptSelect::set_typed(Variant::Type p_op) {
1138 
1139 	if (typed == p_op)
1140 		return;
1141 
1142 	typed = p_op;
1143 	ports_changed_notify();
1144 }
1145 
get_typed() const1146 Variant::Type VisualScriptSelect::get_typed() const {
1147 
1148 	return typed;
1149 }
1150 
_bind_methods()1151 void VisualScriptSelect::_bind_methods() {
1152 
1153 	ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptSelect::set_typed);
1154 	ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptSelect::get_typed);
1155 
1156 	String argt = "Any";
1157 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
1158 		argt += "," + Variant::get_type_name(Variant::Type(i));
1159 	}
1160 
1161 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_typed", "get_typed");
1162 }
1163 
1164 class VisualScriptNodeInstanceSelect : public VisualScriptNodeInstance {
1165 public:
1166 	//virtual int get_working_memory_size() const { return 0; }
1167 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1168 	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) {
1169 
1170 		bool cond = *p_inputs[0];
1171 		if (cond)
1172 			*p_outputs[0] = *p_inputs[1];
1173 		else
1174 			*p_outputs[0] = *p_inputs[2];
1175 
1176 		return 0;
1177 	}
1178 };
1179 
instance(VisualScriptInstance * p_instance)1180 VisualScriptNodeInstance *VisualScriptSelect::instance(VisualScriptInstance *p_instance) {
1181 
1182 	VisualScriptNodeInstanceSelect *instance = memnew(VisualScriptNodeInstanceSelect);
1183 	return instance;
1184 }
1185 
VisualScriptSelect()1186 VisualScriptSelect::VisualScriptSelect() {
1187 
1188 	typed = Variant::NIL;
1189 }
1190 
1191 //////////////////////////////////////////
1192 ////////////////VARIABLE GET//////////////////
1193 //////////////////////////////////////////
1194 
get_output_sequence_port_count() const1195 int VisualScriptVariableGet::get_output_sequence_port_count() const {
1196 
1197 	return 0;
1198 }
1199 
has_input_sequence_port() const1200 bool VisualScriptVariableGet::has_input_sequence_port() const {
1201 
1202 	return false;
1203 }
1204 
get_input_value_port_count() const1205 int VisualScriptVariableGet::get_input_value_port_count() const {
1206 
1207 	return 0;
1208 }
get_output_value_port_count() const1209 int VisualScriptVariableGet::get_output_value_port_count() const {
1210 
1211 	return 1;
1212 }
1213 
get_output_sequence_port_text(int p_port) const1214 String VisualScriptVariableGet::get_output_sequence_port_text(int p_port) const {
1215 
1216 	return String();
1217 }
1218 
get_input_value_port_info(int p_idx) const1219 PropertyInfo VisualScriptVariableGet::get_input_value_port_info(int p_idx) const {
1220 
1221 	return PropertyInfo();
1222 }
1223 
get_output_value_port_info(int p_idx) const1224 PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) const {
1225 
1226 	PropertyInfo pinfo;
1227 	pinfo.name = "value";
1228 	if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) {
1229 		PropertyInfo vinfo = get_visual_script()->get_variable_info(variable);
1230 		pinfo.type = vinfo.type;
1231 		pinfo.hint = vinfo.hint;
1232 		pinfo.hint_string = vinfo.hint_string;
1233 	}
1234 	return pinfo;
1235 }
1236 
get_caption() const1237 String VisualScriptVariableGet::get_caption() const {
1238 
1239 	return "Get " + variable;
1240 }
set_variable(StringName p_variable)1241 void VisualScriptVariableGet::set_variable(StringName p_variable) {
1242 
1243 	if (variable == p_variable)
1244 		return;
1245 	variable = p_variable;
1246 	ports_changed_notify();
1247 }
1248 
get_variable() const1249 StringName VisualScriptVariableGet::get_variable() const {
1250 
1251 	return variable;
1252 }
1253 
_validate_property(PropertyInfo & property) const1254 void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const {
1255 
1256 	if (property.name == "var_name" && get_visual_script().is_valid()) {
1257 		Ref<VisualScript> vs = get_visual_script();
1258 		List<StringName> vars;
1259 		vs->get_variable_list(&vars);
1260 
1261 		String vhint;
1262 		for (List<StringName>::Element *E = vars.front(); E; E = E->next()) {
1263 			if (vhint != String())
1264 				vhint += ",";
1265 
1266 			vhint += E->get().operator String();
1267 		}
1268 
1269 		property.hint = PROPERTY_HINT_ENUM;
1270 		property.hint_string = vhint;
1271 	}
1272 }
1273 
_bind_methods()1274 void VisualScriptVariableGet::_bind_methods() {
1275 
1276 	ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableGet::set_variable);
1277 	ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableGet::get_variable);
1278 
1279 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_variable", "get_variable");
1280 }
1281 
1282 class VisualScriptNodeInstanceVariableGet : public VisualScriptNodeInstance {
1283 public:
1284 	VisualScriptVariableGet *node;
1285 	VisualScriptInstance *instance;
1286 	StringName variable;
1287 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1288 	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) {
1289 
1290 		if (!instance->get_variable(variable, p_outputs[0])) {
1291 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1292 			r_error_str = RTR("VariableGet not found in script: ") + "'" + String(variable) + "'";
1293 			return 0;
1294 		}
1295 		return 0;
1296 	}
1297 };
1298 
instance(VisualScriptInstance * p_instance)1299 VisualScriptNodeInstance *VisualScriptVariableGet::instance(VisualScriptInstance *p_instance) {
1300 
1301 	VisualScriptNodeInstanceVariableGet *instance = memnew(VisualScriptNodeInstanceVariableGet);
1302 	instance->node = this;
1303 	instance->instance = p_instance;
1304 	instance->variable = variable;
1305 	return instance;
1306 }
VisualScriptVariableGet()1307 VisualScriptVariableGet::VisualScriptVariableGet() {
1308 }
1309 
1310 //////////////////////////////////////////
1311 ////////////////VARIABLE SET//////////////////
1312 //////////////////////////////////////////
1313 
get_output_sequence_port_count() const1314 int VisualScriptVariableSet::get_output_sequence_port_count() const {
1315 
1316 	return 1;
1317 }
1318 
has_input_sequence_port() const1319 bool VisualScriptVariableSet::has_input_sequence_port() const {
1320 
1321 	return true;
1322 }
1323 
get_input_value_port_count() const1324 int VisualScriptVariableSet::get_input_value_port_count() const {
1325 
1326 	return 1;
1327 }
get_output_value_port_count() const1328 int VisualScriptVariableSet::get_output_value_port_count() const {
1329 
1330 	return 0;
1331 }
1332 
get_output_sequence_port_text(int p_port) const1333 String VisualScriptVariableSet::get_output_sequence_port_text(int p_port) const {
1334 
1335 	return String();
1336 }
1337 
get_input_value_port_info(int p_idx) const1338 PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const {
1339 
1340 	PropertyInfo pinfo;
1341 	pinfo.name = "set";
1342 	if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) {
1343 		PropertyInfo vinfo = get_visual_script()->get_variable_info(variable);
1344 		pinfo.type = vinfo.type;
1345 		pinfo.hint = vinfo.hint;
1346 		pinfo.hint_string = vinfo.hint_string;
1347 	}
1348 	return pinfo;
1349 }
1350 
get_output_value_port_info(int p_idx) const1351 PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) const {
1352 
1353 	return PropertyInfo();
1354 }
1355 
get_caption() const1356 String VisualScriptVariableSet::get_caption() const {
1357 
1358 	return "Set " + variable;
1359 }
1360 
set_variable(StringName p_variable)1361 void VisualScriptVariableSet::set_variable(StringName p_variable) {
1362 
1363 	if (variable == p_variable)
1364 		return;
1365 	variable = p_variable;
1366 	ports_changed_notify();
1367 }
1368 
get_variable() const1369 StringName VisualScriptVariableSet::get_variable() const {
1370 
1371 	return variable;
1372 }
1373 
_validate_property(PropertyInfo & property) const1374 void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const {
1375 
1376 	if (property.name == "var_name" && get_visual_script().is_valid()) {
1377 		Ref<VisualScript> vs = get_visual_script();
1378 		List<StringName> vars;
1379 		vs->get_variable_list(&vars);
1380 
1381 		String vhint;
1382 		for (List<StringName>::Element *E = vars.front(); E; E = E->next()) {
1383 			if (vhint != String())
1384 				vhint += ",";
1385 
1386 			vhint += E->get().operator String();
1387 		}
1388 
1389 		property.hint = PROPERTY_HINT_ENUM;
1390 		property.hint_string = vhint;
1391 	}
1392 }
1393 
_bind_methods()1394 void VisualScriptVariableSet::_bind_methods() {
1395 
1396 	ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableSet::set_variable);
1397 	ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableSet::get_variable);
1398 
1399 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_variable", "get_variable");
1400 }
1401 
1402 class VisualScriptNodeInstanceVariableSet : public VisualScriptNodeInstance {
1403 public:
1404 	VisualScriptVariableSet *node;
1405 	VisualScriptInstance *instance;
1406 	StringName variable;
1407 
1408 	//virtual int get_working_memory_size() const { return 0; }
1409 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1410 	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) {
1411 
1412 		if (!instance->set_variable(variable, *p_inputs[0])) {
1413 
1414 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1415 			r_error_str = RTR("VariableSet not found in script: ") + "'" + String(variable) + "'";
1416 		}
1417 
1418 		return 0;
1419 	}
1420 };
1421 
instance(VisualScriptInstance * p_instance)1422 VisualScriptNodeInstance *VisualScriptVariableSet::instance(VisualScriptInstance *p_instance) {
1423 
1424 	VisualScriptNodeInstanceVariableSet *instance = memnew(VisualScriptNodeInstanceVariableSet);
1425 	instance->node = this;
1426 	instance->instance = p_instance;
1427 	instance->variable = variable;
1428 	return instance;
1429 }
VisualScriptVariableSet()1430 VisualScriptVariableSet::VisualScriptVariableSet() {
1431 }
1432 
1433 //////////////////////////////////////////
1434 ////////////////CONSTANT//////////////////
1435 //////////////////////////////////////////
1436 
get_output_sequence_port_count() const1437 int VisualScriptConstant::get_output_sequence_port_count() const {
1438 
1439 	return 0;
1440 }
1441 
has_input_sequence_port() const1442 bool VisualScriptConstant::has_input_sequence_port() const {
1443 
1444 	return false;
1445 }
1446 
get_input_value_port_count() const1447 int VisualScriptConstant::get_input_value_port_count() const {
1448 
1449 	return 0;
1450 }
get_output_value_port_count() const1451 int VisualScriptConstant::get_output_value_port_count() const {
1452 
1453 	return 1;
1454 }
1455 
get_output_sequence_port_text(int p_port) const1456 String VisualScriptConstant::get_output_sequence_port_text(int p_port) const {
1457 
1458 	return String();
1459 }
1460 
get_input_value_port_info(int p_idx) const1461 PropertyInfo VisualScriptConstant::get_input_value_port_info(int p_idx) const {
1462 
1463 	return PropertyInfo();
1464 }
1465 
get_output_value_port_info(int p_idx) const1466 PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const {
1467 
1468 	PropertyInfo pinfo;
1469 	pinfo.name = String(value);
1470 	pinfo.type = type;
1471 	return pinfo;
1472 }
1473 
get_caption() const1474 String VisualScriptConstant::get_caption() const {
1475 
1476 	return "Constant";
1477 }
1478 
set_constant_type(Variant::Type p_type)1479 void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
1480 
1481 	if (type == p_type)
1482 		return;
1483 
1484 	type = p_type;
1485 	Variant::CallError ce;
1486 	value = Variant::construct(type, NULL, 0, ce);
1487 	ports_changed_notify();
1488 	_change_notify();
1489 }
1490 
get_constant_type() const1491 Variant::Type VisualScriptConstant::get_constant_type() const {
1492 
1493 	return type;
1494 }
1495 
set_constant_value(Variant p_value)1496 void VisualScriptConstant::set_constant_value(Variant p_value) {
1497 
1498 	if (value == p_value)
1499 		return;
1500 
1501 	value = p_value;
1502 	ports_changed_notify();
1503 }
get_constant_value() const1504 Variant VisualScriptConstant::get_constant_value() const {
1505 
1506 	return value;
1507 }
1508 
_validate_property(PropertyInfo & property) const1509 void VisualScriptConstant::_validate_property(PropertyInfo &property) const {
1510 
1511 	if (property.name == "value") {
1512 		property.type = type;
1513 		if (type == Variant::NIL)
1514 			property.usage = 0; //do not save if nil
1515 	}
1516 }
1517 
_bind_methods()1518 void VisualScriptConstant::_bind_methods() {
1519 
1520 	ClassDB::bind_method(D_METHOD("set_constant_type", "type"), &VisualScriptConstant::set_constant_type);
1521 	ClassDB::bind_method(D_METHOD("get_constant_type"), &VisualScriptConstant::get_constant_type);
1522 
1523 	ClassDB::bind_method(D_METHOD("set_constant_value", "value"), &VisualScriptConstant::set_constant_value);
1524 	ClassDB::bind_method(D_METHOD("get_constant_value"), &VisualScriptConstant::get_constant_value);
1525 
1526 	String argt = "Null";
1527 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
1528 		argt += "," + Variant::get_type_name(Variant::Type(i));
1529 	}
1530 
1531 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_constant_type", "get_constant_type");
1532 	ADD_PROPERTY(PropertyInfo(Variant::NIL, "value", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT | PROPERTY_USAGE_DEFAULT), "set_constant_value", "get_constant_value");
1533 }
1534 
1535 class VisualScriptNodeInstanceConstant : public VisualScriptNodeInstance {
1536 public:
1537 	Variant constant;
1538 	//virtual int get_working_memory_size() const { return 0; }
1539 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1540 	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) {
1541 
1542 		*p_outputs[0] = constant;
1543 		return 0;
1544 	}
1545 };
1546 
instance(VisualScriptInstance * p_instance)1547 VisualScriptNodeInstance *VisualScriptConstant::instance(VisualScriptInstance *p_instance) {
1548 
1549 	VisualScriptNodeInstanceConstant *instance = memnew(VisualScriptNodeInstanceConstant);
1550 	instance->constant = value;
1551 	return instance;
1552 }
1553 
VisualScriptConstant()1554 VisualScriptConstant::VisualScriptConstant() {
1555 
1556 	type = Variant::NIL;
1557 }
1558 
1559 //////////////////////////////////////////
1560 ////////////////PRELOAD//////////////////
1561 //////////////////////////////////////////
1562 
get_output_sequence_port_count() const1563 int VisualScriptPreload::get_output_sequence_port_count() const {
1564 
1565 	return 0;
1566 }
1567 
has_input_sequence_port() const1568 bool VisualScriptPreload::has_input_sequence_port() const {
1569 
1570 	return false;
1571 }
1572 
get_input_value_port_count() const1573 int VisualScriptPreload::get_input_value_port_count() const {
1574 
1575 	return 0;
1576 }
get_output_value_port_count() const1577 int VisualScriptPreload::get_output_value_port_count() const {
1578 
1579 	return 1;
1580 }
1581 
get_output_sequence_port_text(int p_port) const1582 String VisualScriptPreload::get_output_sequence_port_text(int p_port) const {
1583 
1584 	return String();
1585 }
1586 
get_input_value_port_info(int p_idx) const1587 PropertyInfo VisualScriptPreload::get_input_value_port_info(int p_idx) const {
1588 
1589 	return PropertyInfo();
1590 }
1591 
get_output_value_port_info(int p_idx) const1592 PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const {
1593 
1594 	PropertyInfo pinfo;
1595 	pinfo.type = Variant::OBJECT;
1596 	if (preload.is_valid()) {
1597 		pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE;
1598 		pinfo.hint_string = preload->get_class();
1599 		if (preload->get_path().is_resource_file()) {
1600 			pinfo.name = preload->get_path();
1601 		} else if (preload->get_name() != String()) {
1602 			pinfo.name = preload->get_name();
1603 		} else {
1604 			pinfo.name = preload->get_class();
1605 		}
1606 	} else {
1607 		pinfo.name = "<empty>";
1608 	}
1609 
1610 	return pinfo;
1611 }
1612 
get_caption() const1613 String VisualScriptPreload::get_caption() const {
1614 
1615 	return "Preload";
1616 }
1617 
set_preload(const Ref<Resource> & p_preload)1618 void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) {
1619 
1620 	if (preload == p_preload)
1621 		return;
1622 
1623 	preload = p_preload;
1624 	ports_changed_notify();
1625 }
1626 
get_preload() const1627 Ref<Resource> VisualScriptPreload::get_preload() const {
1628 
1629 	return preload;
1630 }
1631 
_bind_methods()1632 void VisualScriptPreload::_bind_methods() {
1633 
1634 	ClassDB::bind_method(D_METHOD("set_preload", "resource"), &VisualScriptPreload::set_preload);
1635 	ClassDB::bind_method(D_METHOD("get_preload"), &VisualScriptPreload::get_preload);
1636 
1637 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), "set_preload", "get_preload");
1638 }
1639 
1640 class VisualScriptNodeInstancePreload : public VisualScriptNodeInstance {
1641 public:
1642 	Ref<Resource> preload;
1643 	//virtual int get_working_memory_size() const { return 0; }
1644 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1645 	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) {
1646 
1647 		*p_outputs[0] = preload;
1648 		return 0;
1649 	}
1650 };
1651 
instance(VisualScriptInstance * p_instance)1652 VisualScriptNodeInstance *VisualScriptPreload::instance(VisualScriptInstance *p_instance) {
1653 
1654 	VisualScriptNodeInstancePreload *instance = memnew(VisualScriptNodeInstancePreload);
1655 	instance->preload = preload;
1656 	return instance;
1657 }
1658 
VisualScriptPreload()1659 VisualScriptPreload::VisualScriptPreload() {
1660 }
1661 
1662 //////////////////////////////////////////
1663 ////////////////INDEX////////////////////
1664 //////////////////////////////////////////
1665 
get_output_sequence_port_count() const1666 int VisualScriptIndexGet::get_output_sequence_port_count() const {
1667 
1668 	return 0;
1669 }
1670 
has_input_sequence_port() const1671 bool VisualScriptIndexGet::has_input_sequence_port() const {
1672 
1673 	return false;
1674 }
1675 
get_input_value_port_count() const1676 int VisualScriptIndexGet::get_input_value_port_count() const {
1677 
1678 	return 2;
1679 }
get_output_value_port_count() const1680 int VisualScriptIndexGet::get_output_value_port_count() const {
1681 
1682 	return 1;
1683 }
1684 
get_output_sequence_port_text(int p_port) const1685 String VisualScriptIndexGet::get_output_sequence_port_text(int p_port) const {
1686 
1687 	return String();
1688 }
1689 
get_input_value_port_info(int p_idx) const1690 PropertyInfo VisualScriptIndexGet::get_input_value_port_info(int p_idx) const {
1691 
1692 	if (p_idx == 0) {
1693 		return PropertyInfo(Variant::NIL, "base");
1694 	} else {
1695 		return PropertyInfo(Variant::NIL, "index");
1696 	}
1697 }
1698 
get_output_value_port_info(int p_idx) const1699 PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const {
1700 
1701 	return PropertyInfo();
1702 }
1703 
get_caption() const1704 String VisualScriptIndexGet::get_caption() const {
1705 
1706 	return "Get Index";
1707 }
1708 
1709 class VisualScriptNodeInstanceIndexGet : public VisualScriptNodeInstance {
1710 public:
1711 	//virtual int get_working_memory_size() const { return 0; }
1712 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1713 	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) {
1714 
1715 		bool valid;
1716 		*p_outputs[0] = p_inputs[0]->get(*p_inputs[1], &valid);
1717 
1718 		if (!valid) {
1719 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1720 			r_error_str = "Invalid get: " + p_inputs[0]->get_construct_string();
1721 		}
1722 		return 0;
1723 	}
1724 };
1725 
instance(VisualScriptInstance * p_instance)1726 VisualScriptNodeInstance *VisualScriptIndexGet::instance(VisualScriptInstance *p_instance) {
1727 
1728 	VisualScriptNodeInstanceIndexGet *instance = memnew(VisualScriptNodeInstanceIndexGet);
1729 	return instance;
1730 }
VisualScriptIndexGet()1731 VisualScriptIndexGet::VisualScriptIndexGet() {
1732 }
1733 
1734 //////////////////////////////////////////
1735 ////////////////INDEXSET//////////////////
1736 //////////////////////////////////////////
1737 
get_output_sequence_port_count() const1738 int VisualScriptIndexSet::get_output_sequence_port_count() const {
1739 
1740 	return 1;
1741 }
1742 
has_input_sequence_port() const1743 bool VisualScriptIndexSet::has_input_sequence_port() const {
1744 
1745 	return true;
1746 }
1747 
get_input_value_port_count() const1748 int VisualScriptIndexSet::get_input_value_port_count() const {
1749 
1750 	return 3;
1751 }
get_output_value_port_count() const1752 int VisualScriptIndexSet::get_output_value_port_count() const {
1753 
1754 	return 0;
1755 }
1756 
get_output_sequence_port_text(int p_port) const1757 String VisualScriptIndexSet::get_output_sequence_port_text(int p_port) const {
1758 
1759 	return String();
1760 }
1761 
get_input_value_port_info(int p_idx) const1762 PropertyInfo VisualScriptIndexSet::get_input_value_port_info(int p_idx) const {
1763 
1764 	if (p_idx == 0) {
1765 		return PropertyInfo(Variant::NIL, "base");
1766 	} else if (p_idx == 1) {
1767 		return PropertyInfo(Variant::NIL, "index");
1768 
1769 	} else {
1770 		return PropertyInfo(Variant::NIL, "value");
1771 	}
1772 }
1773 
get_output_value_port_info(int p_idx) const1774 PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const {
1775 
1776 	return PropertyInfo();
1777 }
1778 
get_caption() const1779 String VisualScriptIndexSet::get_caption() const {
1780 
1781 	return "Set Index";
1782 }
1783 
1784 class VisualScriptNodeInstanceIndexSet : public VisualScriptNodeInstance {
1785 public:
1786 	//virtual int get_working_memory_size() const { return 0; }
1787 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1788 	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) {
1789 
1790 		bool valid;
1791 		*p_outputs[0] = *p_inputs[0];
1792 		p_outputs[0]->set(*p_inputs[1], *p_inputs[2], &valid);
1793 
1794 		if (!valid) {
1795 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1796 			r_error_str = "Invalid set: " + p_inputs[1]->get_construct_string();
1797 		}
1798 		return 0;
1799 	}
1800 };
1801 
instance(VisualScriptInstance * p_instance)1802 VisualScriptNodeInstance *VisualScriptIndexSet::instance(VisualScriptInstance *p_instance) {
1803 
1804 	VisualScriptNodeInstanceIndexSet *instance = memnew(VisualScriptNodeInstanceIndexSet);
1805 	return instance;
1806 }
VisualScriptIndexSet()1807 VisualScriptIndexSet::VisualScriptIndexSet() {
1808 }
1809 
1810 //////////////////////////////////////////
1811 ////////////////GLOBALCONSTANT///////////
1812 //////////////////////////////////////////
1813 
get_output_sequence_port_count() const1814 int VisualScriptGlobalConstant::get_output_sequence_port_count() const {
1815 
1816 	return 0;
1817 }
1818 
has_input_sequence_port() const1819 bool VisualScriptGlobalConstant::has_input_sequence_port() const {
1820 
1821 	return false;
1822 }
1823 
get_input_value_port_count() const1824 int VisualScriptGlobalConstant::get_input_value_port_count() const {
1825 
1826 	return 0;
1827 }
get_output_value_port_count() const1828 int VisualScriptGlobalConstant::get_output_value_port_count() const {
1829 
1830 	return 1;
1831 }
1832 
get_output_sequence_port_text(int p_port) const1833 String VisualScriptGlobalConstant::get_output_sequence_port_text(int p_port) const {
1834 
1835 	return String();
1836 }
1837 
get_input_value_port_info(int p_idx) const1838 PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) const {
1839 
1840 	return PropertyInfo();
1841 }
1842 
get_output_value_port_info(int p_idx) const1843 PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) const {
1844 	String name = GlobalConstants::get_global_constant_name(index);
1845 	return PropertyInfo(Variant::INT, name);
1846 }
1847 
get_caption() const1848 String VisualScriptGlobalConstant::get_caption() const {
1849 
1850 	return "Global Constant";
1851 }
1852 
set_global_constant(int p_which)1853 void VisualScriptGlobalConstant::set_global_constant(int p_which) {
1854 
1855 	index = p_which;
1856 	_change_notify();
1857 	ports_changed_notify();
1858 }
1859 
get_global_constant()1860 int VisualScriptGlobalConstant::get_global_constant() {
1861 	return index;
1862 }
1863 
1864 class VisualScriptNodeInstanceGlobalConstant : public VisualScriptNodeInstance {
1865 public:
1866 	int index;
1867 	//virtual int get_working_memory_size() const { return 0; }
1868 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1869 	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) {
1870 
1871 		*p_outputs[0] = GlobalConstants::get_global_constant_value(index);
1872 		return 0;
1873 	}
1874 };
1875 
instance(VisualScriptInstance * p_instance)1876 VisualScriptNodeInstance *VisualScriptGlobalConstant::instance(VisualScriptInstance *p_instance) {
1877 
1878 	VisualScriptNodeInstanceGlobalConstant *instance = memnew(VisualScriptNodeInstanceGlobalConstant);
1879 	instance->index = index;
1880 	return instance;
1881 }
1882 
_bind_methods()1883 void VisualScriptGlobalConstant::_bind_methods() {
1884 
1885 	ClassDB::bind_method(D_METHOD("set_global_constant", "index"), &VisualScriptGlobalConstant::set_global_constant);
1886 	ClassDB::bind_method(D_METHOD("get_global_constant"), &VisualScriptGlobalConstant::get_global_constant);
1887 
1888 	String cc;
1889 
1890 	for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
1891 
1892 		if (i > 0)
1893 			cc += ",";
1894 		cc += GlobalConstants::get_global_constant_name(i);
1895 	}
1896 	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant");
1897 }
1898 
VisualScriptGlobalConstant()1899 VisualScriptGlobalConstant::VisualScriptGlobalConstant() {
1900 
1901 	index = 0;
1902 }
1903 
1904 //////////////////////////////////////////
1905 ////////////////CLASSCONSTANT///////////
1906 //////////////////////////////////////////
1907 
get_output_sequence_port_count() const1908 int VisualScriptClassConstant::get_output_sequence_port_count() const {
1909 
1910 	return 0;
1911 }
1912 
has_input_sequence_port() const1913 bool VisualScriptClassConstant::has_input_sequence_port() const {
1914 
1915 	return false;
1916 }
1917 
get_input_value_port_count() const1918 int VisualScriptClassConstant::get_input_value_port_count() const {
1919 
1920 	return 0;
1921 }
get_output_value_port_count() const1922 int VisualScriptClassConstant::get_output_value_port_count() const {
1923 
1924 	return 1;
1925 }
1926 
get_output_sequence_port_text(int p_port) const1927 String VisualScriptClassConstant::get_output_sequence_port_text(int p_port) const {
1928 
1929 	return String();
1930 }
1931 
get_input_value_port_info(int p_idx) const1932 PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) const {
1933 
1934 	return PropertyInfo();
1935 }
1936 
get_output_value_port_info(int p_idx) const1937 PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) const {
1938 	if (name == "") {
1939 		return PropertyInfo(Variant::INT, String(base_type));
1940 	} else {
1941 		return PropertyInfo(Variant::INT, String(base_type) + "." + String(name));
1942 	}
1943 }
1944 
get_caption() const1945 String VisualScriptClassConstant::get_caption() const {
1946 
1947 	return "Class Constant";
1948 }
1949 
set_class_constant(const StringName & p_which)1950 void VisualScriptClassConstant::set_class_constant(const StringName &p_which) {
1951 
1952 	name = p_which;
1953 	_change_notify();
1954 	ports_changed_notify();
1955 }
1956 
get_class_constant()1957 StringName VisualScriptClassConstant::get_class_constant() {
1958 	return name;
1959 }
1960 
set_base_type(const StringName & p_which)1961 void VisualScriptClassConstant::set_base_type(const StringName &p_which) {
1962 
1963 	base_type = p_which;
1964 	List<String> constants;
1965 	ClassDB::get_integer_constant_list(base_type, &constants, true);
1966 	if (constants.size() > 0) {
1967 		bool found_name = false;
1968 		for (List<String>::Element *E = constants.front(); E; E = E->next()) {
1969 			if (E->get() == name) {
1970 				found_name = true;
1971 				break;
1972 			}
1973 		}
1974 		if (!found_name) {
1975 			name = constants[0];
1976 		}
1977 	} else {
1978 		name = "";
1979 	}
1980 	_change_notify();
1981 	ports_changed_notify();
1982 }
1983 
get_base_type()1984 StringName VisualScriptClassConstant::get_base_type() {
1985 	return base_type;
1986 }
1987 
1988 class VisualScriptNodeInstanceClassConstant : public VisualScriptNodeInstance {
1989 public:
1990 	int value;
1991 	bool valid;
1992 	//virtual int get_working_memory_size() const { return 0; }
1993 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)1994 	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) {
1995 
1996 		if (!valid) {
1997 			r_error_str = "Invalid constant name, pick a valid class constant.";
1998 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
1999 		}
2000 
2001 		*p_outputs[0] = value;
2002 		return 0;
2003 	}
2004 };
2005 
instance(VisualScriptInstance * p_instance)2006 VisualScriptNodeInstance *VisualScriptClassConstant::instance(VisualScriptInstance *p_instance) {
2007 
2008 	VisualScriptNodeInstanceClassConstant *instance = memnew(VisualScriptNodeInstanceClassConstant);
2009 	instance->value = ClassDB::get_integer_constant(base_type, name, &instance->valid);
2010 	return instance;
2011 }
2012 
_validate_property(PropertyInfo & property) const2013 void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const {
2014 
2015 	if (property.name == "constant") {
2016 
2017 		List<String> constants;
2018 		ClassDB::get_integer_constant_list(base_type, &constants, true);
2019 
2020 		property.hint_string = "";
2021 		for (List<String>::Element *E = constants.front(); E; E = E->next()) {
2022 			if (property.hint_string != String()) {
2023 				property.hint_string += ",";
2024 			}
2025 			property.hint_string += E->get();
2026 		}
2027 	}
2028 }
2029 
_bind_methods()2030 void VisualScriptClassConstant::_bind_methods() {
2031 
2032 	ClassDB::bind_method(D_METHOD("set_class_constant", "name"), &VisualScriptClassConstant::set_class_constant);
2033 	ClassDB::bind_method(D_METHOD("get_class_constant"), &VisualScriptClassConstant::get_class_constant);
2034 
2035 	ClassDB::bind_method(D_METHOD("set_base_type", "name"), &VisualScriptClassConstant::set_base_type);
2036 	ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptClassConstant::get_base_type);
2037 
2038 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
2039 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_class_constant", "get_class_constant");
2040 }
2041 
VisualScriptClassConstant()2042 VisualScriptClassConstant::VisualScriptClassConstant() {
2043 
2044 	base_type = "Object";
2045 }
2046 
2047 //////////////////////////////////////////
2048 ////////////////BASICTYPECONSTANT///////////
2049 //////////////////////////////////////////
2050 
get_output_sequence_port_count() const2051 int VisualScriptBasicTypeConstant::get_output_sequence_port_count() const {
2052 
2053 	return 0;
2054 }
2055 
has_input_sequence_port() const2056 bool VisualScriptBasicTypeConstant::has_input_sequence_port() const {
2057 
2058 	return false;
2059 }
2060 
get_input_value_port_count() const2061 int VisualScriptBasicTypeConstant::get_input_value_port_count() const {
2062 
2063 	return 0;
2064 }
get_output_value_port_count() const2065 int VisualScriptBasicTypeConstant::get_output_value_port_count() const {
2066 
2067 	return 1;
2068 }
2069 
get_output_sequence_port_text(int p_port) const2070 String VisualScriptBasicTypeConstant::get_output_sequence_port_text(int p_port) const {
2071 
2072 	return String();
2073 }
2074 
get_input_value_port_info(int p_idx) const2075 PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) const {
2076 
2077 	return PropertyInfo();
2078 }
2079 
get_output_value_port_info(int p_idx) const2080 PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const {
2081 
2082 	return PropertyInfo(type, "value");
2083 }
2084 
get_caption() const2085 String VisualScriptBasicTypeConstant::get_caption() const {
2086 
2087 	return "Basic Constant";
2088 }
2089 
get_text() const2090 String VisualScriptBasicTypeConstant::get_text() const {
2091 	if (name == "") {
2092 		return Variant::get_type_name(type);
2093 	} else {
2094 		return Variant::get_type_name(type) + "." + String(name);
2095 	}
2096 }
2097 
set_basic_type_constant(const StringName & p_which)2098 void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) {
2099 
2100 	name = p_which;
2101 	_change_notify();
2102 	ports_changed_notify();
2103 }
2104 
get_basic_type_constant() const2105 StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const {
2106 	return name;
2107 }
2108 
set_basic_type(Variant::Type p_which)2109 void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) {
2110 
2111 	type = p_which;
2112 
2113 	List<StringName> constants;
2114 	Variant::get_constants_for_type(type, &constants);
2115 	if (constants.size() > 0) {
2116 		bool found_name = false;
2117 		for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
2118 			if (E->get() == name) {
2119 				found_name = true;
2120 				break;
2121 			}
2122 		}
2123 		if (!found_name) {
2124 			name = constants[0];
2125 		}
2126 	} else {
2127 		name = "";
2128 	}
2129 	_change_notify();
2130 	ports_changed_notify();
2131 }
2132 
get_basic_type() const2133 Variant::Type VisualScriptBasicTypeConstant::get_basic_type() const {
2134 	return type;
2135 }
2136 
2137 class VisualScriptNodeInstanceBasicTypeConstant : public VisualScriptNodeInstance {
2138 public:
2139 	Variant value;
2140 	bool valid;
2141 	//virtual int get_working_memory_size() const { return 0; }
2142 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2143 	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) {
2144 
2145 		if (!valid) {
2146 			r_error_str = "Invalid constant name, pick a valid basic type constant.";
2147 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
2148 		}
2149 
2150 		*p_outputs[0] = value;
2151 		return 0;
2152 	}
2153 };
2154 
instance(VisualScriptInstance * p_instance)2155 VisualScriptNodeInstance *VisualScriptBasicTypeConstant::instance(VisualScriptInstance *p_instance) {
2156 
2157 	VisualScriptNodeInstanceBasicTypeConstant *instance = memnew(VisualScriptNodeInstanceBasicTypeConstant);
2158 	instance->value = Variant::get_constant_value(type, name, &instance->valid);
2159 	return instance;
2160 }
2161 
_validate_property(PropertyInfo & property) const2162 void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) const {
2163 
2164 	if (property.name == "constant") {
2165 
2166 		List<StringName> constants;
2167 		Variant::get_constants_for_type(type, &constants);
2168 
2169 		if (constants.size() == 0) {
2170 			property.usage = 0;
2171 			return;
2172 		}
2173 		property.hint_string = "";
2174 		for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
2175 			if (property.hint_string != String()) {
2176 				property.hint_string += ",";
2177 			}
2178 			property.hint_string += String(E->get());
2179 		}
2180 	}
2181 }
2182 
_bind_methods()2183 void VisualScriptBasicTypeConstant::_bind_methods() {
2184 
2185 	ClassDB::bind_method(D_METHOD("set_basic_type", "name"), &VisualScriptBasicTypeConstant::set_basic_type);
2186 	ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptBasicTypeConstant::get_basic_type);
2187 
2188 	ClassDB::bind_method(D_METHOD("set_basic_type_constant", "name"), &VisualScriptBasicTypeConstant::set_basic_type_constant);
2189 	ClassDB::bind_method(D_METHOD("get_basic_type_constant"), &VisualScriptBasicTypeConstant::get_basic_type_constant);
2190 
2191 	String argt = "Null";
2192 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
2193 		argt += "," + Variant::get_type_name(Variant::Type(i));
2194 	}
2195 
2196 	ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, argt), "set_basic_type", "get_basic_type");
2197 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant", PROPERTY_HINT_ENUM, ""), "set_basic_type_constant", "get_basic_type_constant");
2198 }
2199 
VisualScriptBasicTypeConstant()2200 VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() {
2201 
2202 	type = Variant::NIL;
2203 }
2204 
2205 //////////////////////////////////////////
2206 ////////////////MATHCONSTANT///////////
2207 //////////////////////////////////////////
2208 
2209 const char *VisualScriptMathConstant::const_name[MATH_CONSTANT_MAX] = {
2210 	"One",
2211 	"PI",
2212 	"PI/2",
2213 	"TAU",
2214 	"E",
2215 	"Sqrt2",
2216 	"INF",
2217 	"NAN"
2218 };
2219 
2220 double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX] = {
2221 	1.0,
2222 	Math_PI,
2223 	Math_PI * 0.5,
2224 	Math_TAU,
2225 	2.71828182845904523536,
2226 	Math::sqrt(2.0),
2227 	Math_INF,
2228 	Math_NAN
2229 };
2230 
get_output_sequence_port_count() const2231 int VisualScriptMathConstant::get_output_sequence_port_count() const {
2232 
2233 	return 0;
2234 }
2235 
has_input_sequence_port() const2236 bool VisualScriptMathConstant::has_input_sequence_port() const {
2237 
2238 	return false;
2239 }
2240 
get_input_value_port_count() const2241 int VisualScriptMathConstant::get_input_value_port_count() const {
2242 
2243 	return 0;
2244 }
get_output_value_port_count() const2245 int VisualScriptMathConstant::get_output_value_port_count() const {
2246 
2247 	return 1;
2248 }
2249 
get_output_sequence_port_text(int p_port) const2250 String VisualScriptMathConstant::get_output_sequence_port_text(int p_port) const {
2251 
2252 	return String();
2253 }
2254 
get_input_value_port_info(int p_idx) const2255 PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) const {
2256 
2257 	return PropertyInfo();
2258 }
2259 
get_output_value_port_info(int p_idx) const2260 PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const {
2261 
2262 	return PropertyInfo(Variant::REAL, const_name[constant]);
2263 }
2264 
get_caption() const2265 String VisualScriptMathConstant::get_caption() const {
2266 
2267 	return "Math Constant";
2268 }
2269 
set_math_constant(MathConstant p_which)2270 void VisualScriptMathConstant::set_math_constant(MathConstant p_which) {
2271 
2272 	constant = p_which;
2273 	_change_notify();
2274 	ports_changed_notify();
2275 }
2276 
get_math_constant()2277 VisualScriptMathConstant::MathConstant VisualScriptMathConstant::get_math_constant() {
2278 	return constant;
2279 }
2280 
2281 class VisualScriptNodeInstanceMathConstant : public VisualScriptNodeInstance {
2282 public:
2283 	float value;
2284 	//virtual int get_working_memory_size() const { return 0; }
2285 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2286 	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) {
2287 
2288 		*p_outputs[0] = value;
2289 		return 0;
2290 	}
2291 };
2292 
instance(VisualScriptInstance * p_instance)2293 VisualScriptNodeInstance *VisualScriptMathConstant::instance(VisualScriptInstance *p_instance) {
2294 
2295 	VisualScriptNodeInstanceMathConstant *instance = memnew(VisualScriptNodeInstanceMathConstant);
2296 	instance->value = const_value[constant];
2297 	return instance;
2298 }
2299 
_bind_methods()2300 void VisualScriptMathConstant::_bind_methods() {
2301 
2302 	ClassDB::bind_method(D_METHOD("set_math_constant", "which"), &VisualScriptMathConstant::set_math_constant);
2303 	ClassDB::bind_method(D_METHOD("get_math_constant"), &VisualScriptMathConstant::get_math_constant);
2304 
2305 	String cc;
2306 
2307 	for (int i = 0; i < MATH_CONSTANT_MAX; i++) {
2308 
2309 		if (i > 0)
2310 			cc += ",";
2311 		cc += const_name[i];
2312 	}
2313 	ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant");
2314 
2315 	BIND_ENUM_CONSTANT(MATH_CONSTANT_ONE);
2316 	BIND_ENUM_CONSTANT(MATH_CONSTANT_PI);
2317 	BIND_ENUM_CONSTANT(MATH_CONSTANT_HALF_PI);
2318 	BIND_ENUM_CONSTANT(MATH_CONSTANT_TAU);
2319 	BIND_ENUM_CONSTANT(MATH_CONSTANT_E);
2320 	BIND_ENUM_CONSTANT(MATH_CONSTANT_SQRT2);
2321 	BIND_ENUM_CONSTANT(MATH_CONSTANT_INF);
2322 	BIND_ENUM_CONSTANT(MATH_CONSTANT_NAN);
2323 	BIND_ENUM_CONSTANT(MATH_CONSTANT_MAX);
2324 }
2325 
VisualScriptMathConstant()2326 VisualScriptMathConstant::VisualScriptMathConstant() {
2327 
2328 	constant = MATH_CONSTANT_ONE;
2329 }
2330 
2331 //////////////////////////////////////////
2332 ////////////////ENGINESINGLETON///////////
2333 //////////////////////////////////////////
2334 
get_output_sequence_port_count() const2335 int VisualScriptEngineSingleton::get_output_sequence_port_count() const {
2336 
2337 	return 0;
2338 }
2339 
has_input_sequence_port() const2340 bool VisualScriptEngineSingleton::has_input_sequence_port() const {
2341 
2342 	return false;
2343 }
2344 
get_input_value_port_count() const2345 int VisualScriptEngineSingleton::get_input_value_port_count() const {
2346 
2347 	return 0;
2348 }
get_output_value_port_count() const2349 int VisualScriptEngineSingleton::get_output_value_port_count() const {
2350 
2351 	return 1;
2352 }
2353 
get_output_sequence_port_text(int p_port) const2354 String VisualScriptEngineSingleton::get_output_sequence_port_text(int p_port) const {
2355 
2356 	return String();
2357 }
2358 
get_input_value_port_info(int p_idx) const2359 PropertyInfo VisualScriptEngineSingleton::get_input_value_port_info(int p_idx) const {
2360 
2361 	return PropertyInfo();
2362 }
2363 
get_output_value_port_info(int p_idx) const2364 PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) const {
2365 
2366 	return PropertyInfo(Variant::OBJECT, singleton);
2367 }
2368 
get_caption() const2369 String VisualScriptEngineSingleton::get_caption() const {
2370 
2371 	return "Get Engine Singleton";
2372 }
2373 
set_singleton(const String & p_string)2374 void VisualScriptEngineSingleton::set_singleton(const String &p_string) {
2375 
2376 	singleton = p_string;
2377 
2378 	_change_notify();
2379 	ports_changed_notify();
2380 }
2381 
get_singleton()2382 String VisualScriptEngineSingleton::get_singleton() {
2383 	return singleton;
2384 }
2385 
2386 class VisualScriptNodeInstanceEngineSingleton : public VisualScriptNodeInstance {
2387 public:
2388 	Object *singleton;
2389 
2390 	//virtual int get_working_memory_size() const { return 0; }
2391 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2392 	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) {
2393 
2394 		*p_outputs[0] = singleton;
2395 		return 0;
2396 	}
2397 };
2398 
instance(VisualScriptInstance * p_instance)2399 VisualScriptNodeInstance *VisualScriptEngineSingleton::instance(VisualScriptInstance *p_instance) {
2400 
2401 	VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton);
2402 	instance->singleton = Engine::get_singleton()->get_singleton_object(singleton);
2403 	return instance;
2404 }
2405 
guess_output_type(TypeGuess * p_inputs,int p_output) const2406 VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const {
2407 
2408 	Object *obj = Engine::get_singleton()->get_singleton_object(singleton);
2409 	TypeGuess tg;
2410 	tg.type = Variant::OBJECT;
2411 	if (obj) {
2412 		tg.gdclass = obj->get_class();
2413 		tg.script = obj->get_script();
2414 	}
2415 
2416 	return tg;
2417 }
2418 
_validate_property(PropertyInfo & property) const2419 void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) const {
2420 
2421 	String cc;
2422 
2423 	List<Engine::Singleton> singletons;
2424 
2425 	Engine::get_singleton()->get_singletons(&singletons);
2426 
2427 	for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
2428 		if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D")
2429 			continue; //skip these, too simple named
2430 
2431 		if (cc != String())
2432 			cc += ",";
2433 		cc += E->get().name;
2434 	}
2435 
2436 	property.hint = PROPERTY_HINT_ENUM;
2437 	property.hint_string = cc;
2438 }
2439 
_bind_methods()2440 void VisualScriptEngineSingleton::_bind_methods() {
2441 
2442 	ClassDB::bind_method(D_METHOD("set_singleton", "name"), &VisualScriptEngineSingleton::set_singleton);
2443 	ClassDB::bind_method(D_METHOD("get_singleton"), &VisualScriptEngineSingleton::get_singleton);
2444 
2445 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "constant"), "set_singleton", "get_singleton");
2446 }
2447 
VisualScriptEngineSingleton()2448 VisualScriptEngineSingleton::VisualScriptEngineSingleton() {
2449 
2450 	singleton = String();
2451 }
2452 
2453 //////////////////////////////////////////
2454 ////////////////GETNODE///////////
2455 //////////////////////////////////////////
2456 
get_output_sequence_port_count() const2457 int VisualScriptSceneNode::get_output_sequence_port_count() const {
2458 
2459 	return 0;
2460 }
2461 
has_input_sequence_port() const2462 bool VisualScriptSceneNode::has_input_sequence_port() const {
2463 
2464 	return false;
2465 }
2466 
get_input_value_port_count() const2467 int VisualScriptSceneNode::get_input_value_port_count() const {
2468 
2469 	return 0;
2470 }
get_output_value_port_count() const2471 int VisualScriptSceneNode::get_output_value_port_count() const {
2472 
2473 	return 1;
2474 }
2475 
get_output_sequence_port_text(int p_port) const2476 String VisualScriptSceneNode::get_output_sequence_port_text(int p_port) const {
2477 
2478 	return String();
2479 }
2480 
get_input_value_port_info(int p_idx) const2481 PropertyInfo VisualScriptSceneNode::get_input_value_port_info(int p_idx) const {
2482 
2483 	return PropertyInfo();
2484 }
2485 
get_output_value_port_info(int p_idx) const2486 PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const {
2487 
2488 	return PropertyInfo(Variant::OBJECT, path.simplified());
2489 }
2490 
get_caption() const2491 String VisualScriptSceneNode::get_caption() const {
2492 
2493 	return "Get Scene Node";
2494 }
2495 
set_node_path(const NodePath & p_path)2496 void VisualScriptSceneNode::set_node_path(const NodePath &p_path) {
2497 
2498 	path = p_path;
2499 	_change_notify();
2500 	ports_changed_notify();
2501 }
2502 
get_node_path()2503 NodePath VisualScriptSceneNode::get_node_path() {
2504 	return path;
2505 }
2506 
2507 class VisualScriptNodeInstanceSceneNode : public VisualScriptNodeInstance {
2508 public:
2509 	VisualScriptSceneNode *node;
2510 	VisualScriptInstance *instance;
2511 	NodePath path;
2512 
2513 	//virtual int get_working_memory_size() const { return 0; }
2514 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2515 	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) {
2516 
2517 		Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
2518 		if (!node) {
2519 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
2520 			r_error_str = "Base object is not a Node!";
2521 			return 0;
2522 		}
2523 
2524 		Node *another = node->get_node(path);
2525 		if (!another) {
2526 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
2527 			r_error_str = "Path does not lead Node!";
2528 			return 0;
2529 		}
2530 
2531 		*p_outputs[0] = another;
2532 
2533 		return 0;
2534 	}
2535 };
2536 
instance(VisualScriptInstance * p_instance)2537 VisualScriptNodeInstance *VisualScriptSceneNode::instance(VisualScriptInstance *p_instance) {
2538 
2539 	VisualScriptNodeInstanceSceneNode *instance = memnew(VisualScriptNodeInstanceSceneNode);
2540 	instance->node = this;
2541 	instance->instance = p_instance;
2542 	instance->path = path;
2543 	return instance;
2544 }
2545 
2546 #ifdef TOOLS_ENABLED
2547 
_find_script_node(Node * p_edited_scene,Node * p_current_node,const Ref<Script> & script)2548 static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
2549 
2550 	if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
2551 		return NULL;
2552 
2553 	Ref<Script> scr = p_current_node->get_script();
2554 
2555 	if (scr.is_valid() && scr == script)
2556 		return p_current_node;
2557 
2558 	for (int i = 0; i < p_current_node->get_child_count(); i++) {
2559 		Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
2560 		if (n)
2561 			return n;
2562 	}
2563 
2564 	return NULL;
2565 }
2566 
2567 #endif
2568 
guess_output_type(TypeGuess * p_inputs,int p_output) const2569 VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {
2570 
2571 	VisualScriptSceneNode::TypeGuess tg;
2572 	tg.type = Variant::OBJECT;
2573 	tg.gdclass = "Node";
2574 
2575 #ifdef TOOLS_ENABLED
2576 	Ref<Script> script = get_visual_script();
2577 	if (!script.is_valid())
2578 		return tg;
2579 
2580 	MainLoop *main_loop = OS::get_singleton()->get_main_loop();
2581 	SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
2582 
2583 	if (!scene_tree)
2584 		return tg;
2585 
2586 	Node *edited_scene = scene_tree->get_edited_scene_root();
2587 
2588 	if (!edited_scene)
2589 		return tg;
2590 
2591 	Node *script_node = _find_script_node(edited_scene, edited_scene, script);
2592 
2593 	if (!script_node)
2594 		return tg;
2595 
2596 	Node *another = script_node->get_node(path);
2597 
2598 	if (another) {
2599 		tg.gdclass = another->get_class();
2600 		tg.script = another->get_script();
2601 	}
2602 #endif
2603 	return tg;
2604 }
2605 
_validate_property(PropertyInfo & property) const2606 void VisualScriptSceneNode::_validate_property(PropertyInfo &property) const {
2607 
2608 #ifdef TOOLS_ENABLED
2609 	if (property.name == "node_path") {
2610 
2611 		Ref<Script> script = get_visual_script();
2612 		if (!script.is_valid())
2613 			return;
2614 
2615 		MainLoop *main_loop = OS::get_singleton()->get_main_loop();
2616 		SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
2617 
2618 		if (!scene_tree)
2619 			return;
2620 
2621 		Node *edited_scene = scene_tree->get_edited_scene_root();
2622 
2623 		if (!edited_scene)
2624 			return;
2625 
2626 		Node *script_node = _find_script_node(edited_scene, edited_scene, script);
2627 
2628 		if (!script_node)
2629 			return;
2630 
2631 		property.hint_string = script_node->get_path();
2632 	}
2633 #endif
2634 }
2635 
_bind_methods()2636 void VisualScriptSceneNode::_bind_methods() {
2637 
2638 	ClassDB::bind_method(D_METHOD("set_node_path", "path"), &VisualScriptSceneNode::set_node_path);
2639 	ClassDB::bind_method(D_METHOD("get_node_path"), &VisualScriptSceneNode::get_node_path);
2640 
2641 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_node_path", "get_node_path");
2642 }
2643 
VisualScriptSceneNode()2644 VisualScriptSceneNode::VisualScriptSceneNode() {
2645 
2646 	path = String(".");
2647 }
2648 
2649 //////////////////////////////////////////
2650 ////////////////SceneTree///////////
2651 //////////////////////////////////////////
2652 
get_output_sequence_port_count() const2653 int VisualScriptSceneTree::get_output_sequence_port_count() const {
2654 
2655 	return 0;
2656 }
2657 
has_input_sequence_port() const2658 bool VisualScriptSceneTree::has_input_sequence_port() const {
2659 
2660 	return false;
2661 }
2662 
get_input_value_port_count() const2663 int VisualScriptSceneTree::get_input_value_port_count() const {
2664 
2665 	return 0;
2666 }
get_output_value_port_count() const2667 int VisualScriptSceneTree::get_output_value_port_count() const {
2668 
2669 	return 1;
2670 }
2671 
get_output_sequence_port_text(int p_port) const2672 String VisualScriptSceneTree::get_output_sequence_port_text(int p_port) const {
2673 
2674 	return String();
2675 }
2676 
get_input_value_port_info(int p_idx) const2677 PropertyInfo VisualScriptSceneTree::get_input_value_port_info(int p_idx) const {
2678 
2679 	return PropertyInfo();
2680 }
2681 
get_output_value_port_info(int p_idx) const2682 PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const {
2683 
2684 	return PropertyInfo(Variant::OBJECT, "Scene Tree", PROPERTY_HINT_TYPE_STRING, "SceneTree");
2685 }
2686 
get_caption() const2687 String VisualScriptSceneTree::get_caption() const {
2688 
2689 	return "Get Scene Tree";
2690 }
2691 
2692 class VisualScriptNodeInstanceSceneTree : public VisualScriptNodeInstance {
2693 public:
2694 	VisualScriptSceneTree *node;
2695 	VisualScriptInstance *instance;
2696 
2697 	//virtual int get_working_memory_size() const { return 0; }
2698 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2699 	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) {
2700 
2701 		Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
2702 		if (!node) {
2703 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
2704 			r_error_str = "Base object is not a Node!";
2705 			return 0;
2706 		}
2707 
2708 		SceneTree *tree = node->get_tree();
2709 		if (!tree) {
2710 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
2711 			r_error_str = "Attempt to get SceneTree while node is not in the active tree.";
2712 			return 0;
2713 		}
2714 
2715 		*p_outputs[0] = tree;
2716 
2717 		return 0;
2718 	}
2719 };
2720 
instance(VisualScriptInstance * p_instance)2721 VisualScriptNodeInstance *VisualScriptSceneTree::instance(VisualScriptInstance *p_instance) {
2722 
2723 	VisualScriptNodeInstanceSceneTree *instance = memnew(VisualScriptNodeInstanceSceneTree);
2724 	instance->node = this;
2725 	instance->instance = p_instance;
2726 	return instance;
2727 }
2728 
guess_output_type(TypeGuess * p_inputs,int p_output) const2729 VisualScriptSceneTree::TypeGuess VisualScriptSceneTree::guess_output_type(TypeGuess *p_inputs, int p_output) const {
2730 
2731 	TypeGuess tg;
2732 	tg.type = Variant::OBJECT;
2733 	tg.gdclass = "SceneTree";
2734 	return tg;
2735 }
2736 
_validate_property(PropertyInfo & property) const2737 void VisualScriptSceneTree::_validate_property(PropertyInfo &property) const {
2738 }
2739 
_bind_methods()2740 void VisualScriptSceneTree::_bind_methods() {
2741 }
2742 
VisualScriptSceneTree()2743 VisualScriptSceneTree::VisualScriptSceneTree() {
2744 }
2745 
2746 //////////////////////////////////////////
2747 ////////////////RESPATH///////////
2748 //////////////////////////////////////////
2749 
get_output_sequence_port_count() const2750 int VisualScriptResourcePath::get_output_sequence_port_count() const {
2751 
2752 	return 0;
2753 }
2754 
has_input_sequence_port() const2755 bool VisualScriptResourcePath::has_input_sequence_port() const {
2756 
2757 	return false;
2758 }
2759 
get_input_value_port_count() const2760 int VisualScriptResourcePath::get_input_value_port_count() const {
2761 
2762 	return 0;
2763 }
get_output_value_port_count() const2764 int VisualScriptResourcePath::get_output_value_port_count() const {
2765 
2766 	return 1;
2767 }
2768 
get_output_sequence_port_text(int p_port) const2769 String VisualScriptResourcePath::get_output_sequence_port_text(int p_port) const {
2770 
2771 	return String();
2772 }
2773 
get_input_value_port_info(int p_idx) const2774 PropertyInfo VisualScriptResourcePath::get_input_value_port_info(int p_idx) const {
2775 
2776 	return PropertyInfo();
2777 }
2778 
get_output_value_port_info(int p_idx) const2779 PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) const {
2780 
2781 	return PropertyInfo(Variant::STRING, path);
2782 }
2783 
get_caption() const2784 String VisualScriptResourcePath::get_caption() const {
2785 
2786 	return "Resource Path";
2787 }
2788 
set_resource_path(const String & p_path)2789 void VisualScriptResourcePath::set_resource_path(const String &p_path) {
2790 
2791 	path = p_path;
2792 	_change_notify();
2793 	ports_changed_notify();
2794 }
2795 
get_resource_path()2796 String VisualScriptResourcePath::get_resource_path() {
2797 	return path;
2798 }
2799 
2800 class VisualScriptNodeInstanceResourcePath : public VisualScriptNodeInstance {
2801 public:
2802 	String path;
2803 
2804 	//virtual int get_working_memory_size() const { return 0; }
2805 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2806 	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) {
2807 
2808 		*p_outputs[0] = path;
2809 		return 0;
2810 	}
2811 };
2812 
instance(VisualScriptInstance * p_instance)2813 VisualScriptNodeInstance *VisualScriptResourcePath::instance(VisualScriptInstance *p_instance) {
2814 
2815 	VisualScriptNodeInstanceResourcePath *instance = memnew(VisualScriptNodeInstanceResourcePath);
2816 	instance->path = path;
2817 	return instance;
2818 }
2819 
_bind_methods()2820 void VisualScriptResourcePath::_bind_methods() {
2821 
2822 	ClassDB::bind_method(D_METHOD("set_resource_path", "path"), &VisualScriptResourcePath::set_resource_path);
2823 	ClassDB::bind_method(D_METHOD("get_resource_path"), &VisualScriptResourcePath::get_resource_path);
2824 
2825 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), "set_resource_path", "get_resource_path");
2826 }
2827 
VisualScriptResourcePath()2828 VisualScriptResourcePath::VisualScriptResourcePath() {
2829 
2830 	path = "";
2831 }
2832 
2833 //////////////////////////////////////////
2834 ////////////////SELF///////////
2835 //////////////////////////////////////////
2836 
get_output_sequence_port_count() const2837 int VisualScriptSelf::get_output_sequence_port_count() const {
2838 
2839 	return 0;
2840 }
2841 
has_input_sequence_port() const2842 bool VisualScriptSelf::has_input_sequence_port() const {
2843 
2844 	return false;
2845 }
2846 
get_input_value_port_count() const2847 int VisualScriptSelf::get_input_value_port_count() const {
2848 
2849 	return 0;
2850 }
get_output_value_port_count() const2851 int VisualScriptSelf::get_output_value_port_count() const {
2852 
2853 	return 1;
2854 }
2855 
get_output_sequence_port_text(int p_port) const2856 String VisualScriptSelf::get_output_sequence_port_text(int p_port) const {
2857 
2858 	return String();
2859 }
2860 
get_input_value_port_info(int p_idx) const2861 PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const {
2862 
2863 	return PropertyInfo();
2864 }
2865 
get_output_value_port_info(int p_idx) const2866 PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const {
2867 
2868 	String type_name;
2869 	if (get_visual_script().is_valid())
2870 		type_name = get_visual_script()->get_instance_base_type();
2871 	else
2872 		type_name = "instance";
2873 
2874 	return PropertyInfo(Variant::OBJECT, type_name);
2875 }
2876 
get_caption() const2877 String VisualScriptSelf::get_caption() const {
2878 
2879 	return "Get Self";
2880 }
2881 
2882 class VisualScriptNodeInstanceSelf : public VisualScriptNodeInstance {
2883 public:
2884 	VisualScriptInstance *instance;
2885 
2886 	//virtual int get_working_memory_size() const { return 0; }
2887 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)2888 	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) {
2889 
2890 		*p_outputs[0] = instance->get_owner_ptr();
2891 		return 0;
2892 	}
2893 };
2894 
instance(VisualScriptInstance * p_instance)2895 VisualScriptNodeInstance *VisualScriptSelf::instance(VisualScriptInstance *p_instance) {
2896 
2897 	VisualScriptNodeInstanceSelf *instance = memnew(VisualScriptNodeInstanceSelf);
2898 	instance->instance = p_instance;
2899 	return instance;
2900 }
2901 
guess_output_type(TypeGuess * p_inputs,int p_output) const2902 VisualScriptSelf::TypeGuess VisualScriptSelf::guess_output_type(TypeGuess *p_inputs, int p_output) const {
2903 
2904 	VisualScriptSceneNode::TypeGuess tg;
2905 	tg.type = Variant::OBJECT;
2906 	tg.gdclass = "Object";
2907 
2908 	Ref<Script> script = get_visual_script();
2909 	if (!script.is_valid())
2910 		return tg;
2911 
2912 	tg.gdclass = script->get_instance_base_type();
2913 	tg.script = script;
2914 
2915 	return tg;
2916 }
2917 
_bind_methods()2918 void VisualScriptSelf::_bind_methods() {
2919 }
2920 
VisualScriptSelf()2921 VisualScriptSelf::VisualScriptSelf() {
2922 }
2923 
2924 //////////////////////////////////////////
2925 ////////////////CUSTOM (SCRIPTED)///////////
2926 //////////////////////////////////////////
2927 
get_output_sequence_port_count() const2928 int VisualScriptCustomNode::get_output_sequence_port_count() const {
2929 
2930 	if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) {
2931 		return get_script_instance()->call("_get_output_sequence_port_count");
2932 	}
2933 	return 0;
2934 }
2935 
has_input_sequence_port() const2936 bool VisualScriptCustomNode::has_input_sequence_port() const {
2937 
2938 	if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) {
2939 		return get_script_instance()->call("_has_input_sequence_port");
2940 	}
2941 	return false;
2942 }
2943 
get_input_value_port_count() const2944 int VisualScriptCustomNode::get_input_value_port_count() const {
2945 
2946 	if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) {
2947 		return get_script_instance()->call("_get_input_value_port_count");
2948 	}
2949 	return 0;
2950 }
get_output_value_port_count() const2951 int VisualScriptCustomNode::get_output_value_port_count() const {
2952 
2953 	if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) {
2954 		return get_script_instance()->call("_get_output_value_port_count");
2955 	}
2956 	return 0;
2957 }
2958 
get_output_sequence_port_text(int p_port) const2959 String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
2960 
2961 	if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) {
2962 		return get_script_instance()->call("_get_output_sequence_port_text", p_port);
2963 	}
2964 
2965 	return String();
2966 }
2967 
get_input_value_port_info(int p_idx) const2968 PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const {
2969 
2970 	PropertyInfo info;
2971 	if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) {
2972 		info.type = Variant::Type(int(get_script_instance()->call("_get_input_value_port_type", p_idx)));
2973 	}
2974 	if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_name")) {
2975 		info.name = get_script_instance()->call("_get_input_value_port_name", p_idx);
2976 	}
2977 	return info;
2978 }
2979 
get_output_value_port_info(int p_idx) const2980 PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const {
2981 
2982 	PropertyInfo info;
2983 	if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) {
2984 		info.type = Variant::Type(int(get_script_instance()->call("_get_output_value_port_type", p_idx)));
2985 	}
2986 	if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_name")) {
2987 		info.name = get_script_instance()->call("_get_output_value_port_name", p_idx);
2988 	}
2989 	return info;
2990 }
2991 
get_caption() const2992 String VisualScriptCustomNode::get_caption() const {
2993 
2994 	if (get_script_instance() && get_script_instance()->has_method("_get_caption")) {
2995 		return get_script_instance()->call("_get_caption");
2996 	}
2997 	return "CustomNode";
2998 }
2999 
get_text() const3000 String VisualScriptCustomNode::get_text() const {
3001 
3002 	if (get_script_instance() && get_script_instance()->has_method("_get_text")) {
3003 		return get_script_instance()->call("_get_text");
3004 	}
3005 	return "";
3006 }
3007 
get_category() const3008 String VisualScriptCustomNode::get_category() const {
3009 
3010 	if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
3011 		return get_script_instance()->call("_get_category");
3012 	}
3013 	return "Custom";
3014 }
3015 
3016 class VisualScriptNodeInstanceCustomNode : public VisualScriptNodeInstance {
3017 public:
3018 	VisualScriptInstance *instance;
3019 	VisualScriptCustomNode *node;
3020 	int in_count;
3021 	int out_count;
3022 	int work_mem_size;
3023 
get_working_memory_size() const3024 	virtual int get_working_memory_size() const { return work_mem_size; }
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3025 	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) {
3026 
3027 		if (node->get_script_instance()) {
3028 #ifdef DEBUG_ENABLED
3029 			if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
3030 				r_error_str = RTR("Custom node has no _step() method, can't process graph.");
3031 				r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
3032 				return 0;
3033 			}
3034 #endif
3035 			Array in_values;
3036 			Array out_values;
3037 			Array work_mem;
3038 
3039 			in_values.resize(in_count);
3040 
3041 			for (int i = 0; i < in_count; i++) {
3042 				in_values[i] = *p_inputs[i];
3043 			}
3044 
3045 			out_values.resize(out_count);
3046 
3047 			work_mem.resize(work_mem_size);
3048 
3049 			for (int i = 0; i < work_mem_size; i++) {
3050 				work_mem[i] = p_working_mem[i];
3051 			}
3052 
3053 			int ret_out;
3054 
3055 			Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step, in_values, out_values, p_start_mode, work_mem);
3056 			if (ret.get_type() == Variant::STRING) {
3057 				r_error_str = ret;
3058 				r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
3059 				return 0;
3060 			} else if (ret.is_num()) {
3061 				ret_out = ret;
3062 			} else {
3063 				r_error_str = RTR("Invalid return value from _step(), must be integer (seq out), or string (error).");
3064 				r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
3065 				return 0;
3066 			}
3067 
3068 			for (int i = 0; i < out_count; i++) {
3069 				if (i < out_values.size()) {
3070 					*p_outputs[i] = out_values[i];
3071 				}
3072 			}
3073 
3074 			for (int i = 0; i < work_mem_size; i++) {
3075 				if (i < work_mem.size()) {
3076 					p_working_mem[i] = work_mem[i];
3077 				}
3078 			}
3079 
3080 			return ret_out;
3081 		}
3082 
3083 		return 0;
3084 	}
3085 };
3086 
instance(VisualScriptInstance * p_instance)3087 VisualScriptNodeInstance *VisualScriptCustomNode::instance(VisualScriptInstance *p_instance) {
3088 
3089 	VisualScriptNodeInstanceCustomNode *instance = memnew(VisualScriptNodeInstanceCustomNode);
3090 	instance->instance = p_instance;
3091 	instance->node = this;
3092 	instance->in_count = get_input_value_port_count();
3093 	instance->out_count = get_output_value_port_count();
3094 
3095 	if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
3096 		instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
3097 	} else {
3098 		instance->work_mem_size = 0;
3099 	}
3100 
3101 	return instance;
3102 }
3103 
_script_changed()3104 void VisualScriptCustomNode::_script_changed() {
3105 	call_deferred("ports_changed_notify");
3106 }
3107 
_bind_methods()3108 void VisualScriptCustomNode::_bind_methods() {
3109 
3110 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_sequence_port_count"));
3111 	BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_input_sequence_port"));
3112 
3113 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_sequence_port_text", PropertyInfo(Variant::INT, "idx")));
3114 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_count"));
3115 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_count"));
3116 
3117 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_type", PropertyInfo(Variant::INT, "idx")));
3118 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_value_port_name", PropertyInfo(Variant::INT, "idx")));
3119 
3120 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_type", PropertyInfo(Variant::INT, "idx")));
3121 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_value_port_name", PropertyInfo(Variant::INT, "idx")));
3122 
3123 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_caption"));
3124 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_text"));
3125 	BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
3126 
3127 	BIND_VMETHOD(MethodInfo(Variant::INT, "_get_working_memory_size"));
3128 
3129 	MethodInfo stepmi(Variant::NIL, "_step", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem"));
3130 	stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
3131 	BIND_VMETHOD(stepmi);
3132 
3133 	ClassDB::bind_method(D_METHOD("_script_changed"), &VisualScriptCustomNode::_script_changed);
3134 
3135 	BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE);
3136 	BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE);
3137 	BIND_ENUM_CONSTANT(START_MODE_RESUME_YIELD);
3138 
3139 	BIND_CONSTANT(STEP_PUSH_STACK_BIT);
3140 	BIND_CONSTANT(STEP_GO_BACK_BIT);
3141 	BIND_CONSTANT(STEP_NO_ADVANCE_BIT);
3142 	BIND_CONSTANT(STEP_EXIT_FUNCTION_BIT);
3143 	BIND_CONSTANT(STEP_YIELD_BIT);
3144 }
3145 
VisualScriptCustomNode()3146 VisualScriptCustomNode::VisualScriptCustomNode() {
3147 	connect("script_changed", this, "_script_changed");
3148 }
3149 
3150 //////////////////////////////////////////
3151 ////////////////SUBCALL///////////
3152 //////////////////////////////////////////
3153 
get_output_sequence_port_count() const3154 int VisualScriptSubCall::get_output_sequence_port_count() const {
3155 
3156 	return 1;
3157 }
3158 
has_input_sequence_port() const3159 bool VisualScriptSubCall::has_input_sequence_port() const {
3160 
3161 	return true;
3162 }
3163 
get_input_value_port_count() const3164 int VisualScriptSubCall::get_input_value_port_count() const {
3165 
3166 	Ref<Script> script = get_script();
3167 
3168 	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
3169 
3170 		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
3171 		return mi.arguments.size();
3172 	}
3173 
3174 	return 0;
3175 }
get_output_value_port_count() const3176 int VisualScriptSubCall::get_output_value_port_count() const {
3177 
3178 	return 1;
3179 }
3180 
get_output_sequence_port_text(int p_port) const3181 String VisualScriptSubCall::get_output_sequence_port_text(int p_port) const {
3182 
3183 	return String();
3184 }
3185 
get_input_value_port_info(int p_idx) const3186 PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const {
3187 
3188 	Ref<Script> script = get_script();
3189 	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
3190 
3191 		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
3192 		return mi.arguments[p_idx];
3193 	}
3194 
3195 	return PropertyInfo();
3196 }
3197 
get_output_value_port_info(int p_idx) const3198 PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const {
3199 
3200 	Ref<Script> script = get_script();
3201 	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
3202 		MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
3203 		return mi.return_val;
3204 	}
3205 	return PropertyInfo();
3206 }
3207 
get_caption() const3208 String VisualScriptSubCall::get_caption() const {
3209 
3210 	return "SubCall";
3211 }
3212 
get_text() const3213 String VisualScriptSubCall::get_text() const {
3214 
3215 	Ref<Script> script = get_script();
3216 	if (script.is_valid()) {
3217 		if (script->get_name() != String())
3218 			return script->get_name();
3219 		if (script->get_path().is_resource_file())
3220 			return script->get_path().get_file();
3221 		return script->get_class();
3222 	}
3223 	return "";
3224 }
3225 
get_category() const3226 String VisualScriptSubCall::get_category() const {
3227 
3228 	return "custom";
3229 }
3230 
3231 class VisualScriptNodeInstanceSubCall : public VisualScriptNodeInstance {
3232 public:
3233 	VisualScriptInstance *instance;
3234 	VisualScriptSubCall *subcall;
3235 	int input_args;
3236 	bool valid;
3237 
3238 	//virtual int get_working_memory_size() const { return 0; }
3239 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3240 	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) {
3241 
3242 		if (!valid) {
3243 			r_error_str = "Node requires a script with a _subcall(<args>) method to work.";
3244 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
3245 			return 0;
3246 		}
3247 		*p_outputs[0] = subcall->call(VisualScriptLanguage::singleton->_subcall, p_inputs, input_args, r_error);
3248 		return 0;
3249 	}
3250 };
3251 
instance(VisualScriptInstance * p_instance)3252 VisualScriptNodeInstance *VisualScriptSubCall::instance(VisualScriptInstance *p_instance) {
3253 
3254 	VisualScriptNodeInstanceSubCall *instance = memnew(VisualScriptNodeInstanceSubCall);
3255 	instance->instance = p_instance;
3256 	Ref<Script> script = get_script();
3257 	if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
3258 		instance->valid = true;
3259 		instance->input_args = get_input_value_port_count();
3260 	} else {
3261 		instance->valid = false;
3262 	}
3263 	return instance;
3264 }
3265 
_bind_methods()3266 void VisualScriptSubCall::_bind_methods() {
3267 
3268 	MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments"));
3269 	scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
3270 	BIND_VMETHOD(scmi);
3271 }
3272 
VisualScriptSubCall()3273 VisualScriptSubCall::VisualScriptSubCall() {
3274 }
3275 
3276 //////////////////////////////////////////
3277 ////////////////Comment///////////
3278 //////////////////////////////////////////
3279 
get_output_sequence_port_count() const3280 int VisualScriptComment::get_output_sequence_port_count() const {
3281 
3282 	return 0;
3283 }
3284 
has_input_sequence_port() const3285 bool VisualScriptComment::has_input_sequence_port() const {
3286 
3287 	return false;
3288 }
3289 
get_input_value_port_count() const3290 int VisualScriptComment::get_input_value_port_count() const {
3291 	return 0;
3292 }
get_output_value_port_count() const3293 int VisualScriptComment::get_output_value_port_count() const {
3294 
3295 	return 0;
3296 }
3297 
get_output_sequence_port_text(int p_port) const3298 String VisualScriptComment::get_output_sequence_port_text(int p_port) const {
3299 
3300 	return String();
3301 }
3302 
get_input_value_port_info(int p_idx) const3303 PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const {
3304 
3305 	return PropertyInfo();
3306 }
3307 
get_output_value_port_info(int p_idx) const3308 PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const {
3309 
3310 	return PropertyInfo();
3311 }
3312 
get_caption() const3313 String VisualScriptComment::get_caption() const {
3314 
3315 	return title;
3316 }
3317 
get_text() const3318 String VisualScriptComment::get_text() const {
3319 
3320 	return description;
3321 }
3322 
set_title(const String & p_title)3323 void VisualScriptComment::set_title(const String &p_title) {
3324 
3325 	if (title == p_title)
3326 		return;
3327 	title = p_title;
3328 	ports_changed_notify();
3329 }
3330 
get_title() const3331 String VisualScriptComment::get_title() const {
3332 
3333 	return title;
3334 }
3335 
set_description(const String & p_description)3336 void VisualScriptComment::set_description(const String &p_description) {
3337 
3338 	if (description == p_description)
3339 		return;
3340 	description = p_description;
3341 	ports_changed_notify();
3342 }
get_description() const3343 String VisualScriptComment::get_description() const {
3344 
3345 	return description;
3346 }
3347 
set_size(const Size2 & p_size)3348 void VisualScriptComment::set_size(const Size2 &p_size) {
3349 
3350 	if (size == p_size)
3351 		return;
3352 	size = p_size;
3353 	ports_changed_notify();
3354 }
get_size() const3355 Size2 VisualScriptComment::get_size() const {
3356 
3357 	return size;
3358 }
3359 
get_category() const3360 String VisualScriptComment::get_category() const {
3361 
3362 	return "data";
3363 }
3364 
3365 class VisualScriptNodeInstanceComment : public VisualScriptNodeInstance {
3366 public:
3367 	VisualScriptInstance *instance;
3368 
3369 	//virtual int get_working_memory_size() const { return 0; }
3370 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3371 	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) {
3372 
3373 		return 0;
3374 	}
3375 };
3376 
instance(VisualScriptInstance * p_instance)3377 VisualScriptNodeInstance *VisualScriptComment::instance(VisualScriptInstance *p_instance) {
3378 
3379 	VisualScriptNodeInstanceComment *instance = memnew(VisualScriptNodeInstanceComment);
3380 	instance->instance = p_instance;
3381 	return instance;
3382 }
3383 
_bind_methods()3384 void VisualScriptComment::_bind_methods() {
3385 
3386 	ClassDB::bind_method(D_METHOD("set_title", "title"), &VisualScriptComment::set_title);
3387 	ClassDB::bind_method(D_METHOD("get_title"), &VisualScriptComment::get_title);
3388 
3389 	ClassDB::bind_method(D_METHOD("set_description", "description"), &VisualScriptComment::set_description);
3390 	ClassDB::bind_method(D_METHOD("get_description"), &VisualScriptComment::get_description);
3391 
3392 	ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualScriptComment::set_size);
3393 	ClassDB::bind_method(D_METHOD("get_size"), &VisualScriptComment::get_size);
3394 
3395 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
3396 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "description", PROPERTY_HINT_MULTILINE_TEXT), "set_description", "get_description");
3397 	ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
3398 }
3399 
VisualScriptComment()3400 VisualScriptComment::VisualScriptComment() {
3401 
3402 	title = "Comment";
3403 	size = Size2(150, 150);
3404 }
3405 
3406 //////////////////////////////////////////
3407 ////////////////Constructor///////////
3408 //////////////////////////////////////////
3409 
get_output_sequence_port_count() const3410 int VisualScriptConstructor::get_output_sequence_port_count() const {
3411 
3412 	return 0;
3413 }
3414 
has_input_sequence_port() const3415 bool VisualScriptConstructor::has_input_sequence_port() const {
3416 
3417 	return false;
3418 }
3419 
get_input_value_port_count() const3420 int VisualScriptConstructor::get_input_value_port_count() const {
3421 	return constructor.arguments.size();
3422 }
get_output_value_port_count() const3423 int VisualScriptConstructor::get_output_value_port_count() const {
3424 
3425 	return 1;
3426 }
3427 
get_output_sequence_port_text(int p_port) const3428 String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const {
3429 
3430 	return "";
3431 }
3432 
get_input_value_port_info(int p_idx) const3433 PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const {
3434 
3435 	return constructor.arguments[p_idx];
3436 }
3437 
get_output_value_port_info(int p_idx) const3438 PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const {
3439 
3440 	return PropertyInfo(type, "value");
3441 }
3442 
get_caption() const3443 String VisualScriptConstructor::get_caption() const {
3444 
3445 	return "Construct " + Variant::get_type_name(type);
3446 }
3447 
get_category() const3448 String VisualScriptConstructor::get_category() const {
3449 
3450 	return "functions";
3451 }
3452 
set_constructor_type(Variant::Type p_type)3453 void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) {
3454 
3455 	if (type == p_type)
3456 		return;
3457 
3458 	type = p_type;
3459 	ports_changed_notify();
3460 }
3461 
get_constructor_type() const3462 Variant::Type VisualScriptConstructor::get_constructor_type() const {
3463 
3464 	return type;
3465 }
3466 
set_constructor(const Dictionary & p_info)3467 void VisualScriptConstructor::set_constructor(const Dictionary &p_info) {
3468 
3469 	constructor = MethodInfo::from_dict(p_info);
3470 	ports_changed_notify();
3471 }
3472 
get_constructor() const3473 Dictionary VisualScriptConstructor::get_constructor() const {
3474 
3475 	return constructor;
3476 }
3477 
3478 class VisualScriptNodeInstanceConstructor : public VisualScriptNodeInstance {
3479 public:
3480 	VisualScriptInstance *instance;
3481 	Variant::Type type;
3482 	int argcount;
3483 
3484 	//virtual int get_working_memory_size() const { return 0; }
3485 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3486 	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) {
3487 
3488 		Variant::CallError ce;
3489 		*p_outputs[0] = Variant::construct(type, p_inputs, argcount, ce);
3490 		if (ce.error != Variant::CallError::CALL_OK) {
3491 			r_error_str = "Invalid arguments for constructor";
3492 		}
3493 
3494 		return 0;
3495 	}
3496 };
3497 
instance(VisualScriptInstance * p_instance)3498 VisualScriptNodeInstance *VisualScriptConstructor::instance(VisualScriptInstance *p_instance) {
3499 
3500 	VisualScriptNodeInstanceConstructor *instance = memnew(VisualScriptNodeInstanceConstructor);
3501 	instance->instance = p_instance;
3502 	instance->type = type;
3503 	instance->argcount = constructor.arguments.size();
3504 	return instance;
3505 }
3506 
_bind_methods()3507 void VisualScriptConstructor::_bind_methods() {
3508 
3509 	ClassDB::bind_method(D_METHOD("set_constructor_type", "type"), &VisualScriptConstructor::set_constructor_type);
3510 	ClassDB::bind_method(D_METHOD("get_constructor_type"), &VisualScriptConstructor::get_constructor_type);
3511 
3512 	ClassDB::bind_method(D_METHOD("set_constructor", "constructor"), &VisualScriptConstructor::set_constructor);
3513 	ClassDB::bind_method(D_METHOD("get_constructor"), &VisualScriptConstructor::get_constructor);
3514 
3515 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor_type", "get_constructor_type");
3516 	ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "constructor", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_constructor", "get_constructor");
3517 }
3518 
VisualScriptConstructor()3519 VisualScriptConstructor::VisualScriptConstructor() {
3520 
3521 	type = Variant::NIL;
3522 }
3523 
3524 static Map<String, Pair<Variant::Type, MethodInfo> > constructor_map;
3525 
create_constructor_node(const String & p_name)3526 static Ref<VisualScriptNode> create_constructor_node(const String &p_name) {
3527 
3528 	ERR_FAIL_COND_V(!constructor_map.has(p_name), Ref<VisualScriptNode>());
3529 
3530 	Ref<VisualScriptConstructor> vsc;
3531 	vsc.instance();
3532 	vsc->set_constructor_type(constructor_map[p_name].first);
3533 	vsc->set_constructor(constructor_map[p_name].second);
3534 
3535 	return vsc;
3536 }
3537 
3538 //////////////////////////////////////////
3539 ////////////////LocalVar///////////
3540 //////////////////////////////////////////
3541 
get_output_sequence_port_count() const3542 int VisualScriptLocalVar::get_output_sequence_port_count() const {
3543 
3544 	return 0;
3545 }
3546 
has_input_sequence_port() const3547 bool VisualScriptLocalVar::has_input_sequence_port() const {
3548 
3549 	return false;
3550 }
3551 
get_input_value_port_count() const3552 int VisualScriptLocalVar::get_input_value_port_count() const {
3553 	return 0;
3554 }
get_output_value_port_count() const3555 int VisualScriptLocalVar::get_output_value_port_count() const {
3556 
3557 	return 1;
3558 }
3559 
get_output_sequence_port_text(int p_port) const3560 String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const {
3561 
3562 	return "";
3563 }
3564 
get_input_value_port_info(int p_idx) const3565 PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const {
3566 
3567 	return PropertyInfo();
3568 }
get_output_value_port_info(int p_idx) const3569 PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const {
3570 
3571 	return PropertyInfo(type, name);
3572 }
3573 
get_caption() const3574 String VisualScriptLocalVar::get_caption() const {
3575 
3576 	return "Get Local Var";
3577 }
3578 
get_category() const3579 String VisualScriptLocalVar::get_category() const {
3580 
3581 	return "data";
3582 }
3583 
set_var_name(const StringName & p_name)3584 void VisualScriptLocalVar::set_var_name(const StringName &p_name) {
3585 
3586 	if (name == p_name)
3587 		return;
3588 
3589 	name = p_name;
3590 	ports_changed_notify();
3591 }
3592 
get_var_name() const3593 StringName VisualScriptLocalVar::get_var_name() const {
3594 
3595 	return name;
3596 }
3597 
set_var_type(Variant::Type p_type)3598 void VisualScriptLocalVar::set_var_type(Variant::Type p_type) {
3599 
3600 	type = p_type;
3601 	ports_changed_notify();
3602 }
3603 
get_var_type() const3604 Variant::Type VisualScriptLocalVar::get_var_type() const {
3605 
3606 	return type;
3607 }
3608 
3609 class VisualScriptNodeInstanceLocalVar : public VisualScriptNodeInstance {
3610 public:
3611 	VisualScriptInstance *instance;
3612 	StringName name;
3613 
get_working_memory_size() const3614 	virtual int get_working_memory_size() const { return 1; }
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3615 	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) {
3616 
3617 		*p_outputs[0] = *p_working_mem;
3618 		return 0;
3619 	}
3620 };
3621 
instance(VisualScriptInstance * p_instance)3622 VisualScriptNodeInstance *VisualScriptLocalVar::instance(VisualScriptInstance *p_instance) {
3623 
3624 	VisualScriptNodeInstanceLocalVar *instance = memnew(VisualScriptNodeInstanceLocalVar);
3625 	instance->instance = p_instance;
3626 	instance->name = name;
3627 
3628 	return instance;
3629 }
3630 
_bind_methods()3631 void VisualScriptLocalVar::_bind_methods() {
3632 
3633 	ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVar::set_var_name);
3634 	ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVar::get_var_name);
3635 
3636 	ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVar::set_var_type);
3637 	ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVar::get_var_type);
3638 
3639 	String argt = "Any";
3640 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
3641 		argt += "," + Variant::get_type_name(Variant::Type(i));
3642 	}
3643 
3644 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name");
3645 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type");
3646 }
3647 
VisualScriptLocalVar()3648 VisualScriptLocalVar::VisualScriptLocalVar() {
3649 
3650 	name = "new_local";
3651 	type = Variant::NIL;
3652 }
3653 
3654 //////////////////////////////////////////
3655 ////////////////LocalVar///////////
3656 //////////////////////////////////////////
3657 
get_output_sequence_port_count() const3658 int VisualScriptLocalVarSet::get_output_sequence_port_count() const {
3659 
3660 	return 1;
3661 }
3662 
has_input_sequence_port() const3663 bool VisualScriptLocalVarSet::has_input_sequence_port() const {
3664 
3665 	return true;
3666 }
3667 
get_input_value_port_count() const3668 int VisualScriptLocalVarSet::get_input_value_port_count() const {
3669 	return 1;
3670 }
get_output_value_port_count() const3671 int VisualScriptLocalVarSet::get_output_value_port_count() const {
3672 
3673 	return 1;
3674 }
3675 
get_output_sequence_port_text(int p_port) const3676 String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const {
3677 
3678 	return "";
3679 }
3680 
get_input_value_port_info(int p_idx) const3681 PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const {
3682 
3683 	return PropertyInfo(type, "set");
3684 }
get_output_value_port_info(int p_idx) const3685 PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const {
3686 
3687 	return PropertyInfo(type, "get");
3688 }
3689 
get_caption() const3690 String VisualScriptLocalVarSet::get_caption() const {
3691 
3692 	return "Set Local Var";
3693 }
3694 
get_text() const3695 String VisualScriptLocalVarSet::get_text() const {
3696 
3697 	return name;
3698 }
3699 
get_category() const3700 String VisualScriptLocalVarSet::get_category() const {
3701 
3702 	return "data";
3703 }
3704 
set_var_name(const StringName & p_name)3705 void VisualScriptLocalVarSet::set_var_name(const StringName &p_name) {
3706 
3707 	if (name == p_name)
3708 		return;
3709 
3710 	name = p_name;
3711 	ports_changed_notify();
3712 }
3713 
get_var_name() const3714 StringName VisualScriptLocalVarSet::get_var_name() const {
3715 
3716 	return name;
3717 }
3718 
set_var_type(Variant::Type p_type)3719 void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) {
3720 
3721 	type = p_type;
3722 	ports_changed_notify();
3723 }
3724 
get_var_type() const3725 Variant::Type VisualScriptLocalVarSet::get_var_type() const {
3726 
3727 	return type;
3728 }
3729 
3730 class VisualScriptNodeInstanceLocalVarSet : public VisualScriptNodeInstance {
3731 public:
3732 	VisualScriptInstance *instance;
3733 	StringName name;
3734 
get_working_memory_size() const3735 	virtual int get_working_memory_size() const { return 1; }
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3736 	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) {
3737 
3738 		*p_working_mem = *p_inputs[0];
3739 		*p_outputs[0] = *p_working_mem;
3740 		return 0;
3741 	}
3742 };
3743 
instance(VisualScriptInstance * p_instance)3744 VisualScriptNodeInstance *VisualScriptLocalVarSet::instance(VisualScriptInstance *p_instance) {
3745 
3746 	VisualScriptNodeInstanceLocalVarSet *instance = memnew(VisualScriptNodeInstanceLocalVarSet);
3747 	instance->instance = p_instance;
3748 	instance->name = name;
3749 
3750 	return instance;
3751 }
3752 
_bind_methods()3753 void VisualScriptLocalVarSet::_bind_methods() {
3754 
3755 	ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVarSet::set_var_name);
3756 	ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVarSet::get_var_name);
3757 
3758 	ClassDB::bind_method(D_METHOD("set_var_type", "type"), &VisualScriptLocalVarSet::set_var_type);
3759 	ClassDB::bind_method(D_METHOD("get_var_type"), &VisualScriptLocalVarSet::get_var_type);
3760 
3761 	String argt = "Any";
3762 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
3763 		argt += "," + Variant::get_type_name(Variant::Type(i));
3764 	}
3765 
3766 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "var_name"), "set_var_name", "get_var_name");
3767 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_var_type", "get_var_type");
3768 }
3769 
VisualScriptLocalVarSet()3770 VisualScriptLocalVarSet::VisualScriptLocalVarSet() {
3771 
3772 	name = "new_local";
3773 	type = Variant::NIL;
3774 }
3775 
3776 //////////////////////////////////////////
3777 ////////////////LocalVar///////////
3778 //////////////////////////////////////////
3779 
get_output_sequence_port_count() const3780 int VisualScriptInputAction::get_output_sequence_port_count() const {
3781 
3782 	return 0;
3783 }
3784 
has_input_sequence_port() const3785 bool VisualScriptInputAction::has_input_sequence_port() const {
3786 
3787 	return false;
3788 }
3789 
get_input_value_port_count() const3790 int VisualScriptInputAction::get_input_value_port_count() const {
3791 	return 0;
3792 }
get_output_value_port_count() const3793 int VisualScriptInputAction::get_output_value_port_count() const {
3794 
3795 	return 1;
3796 }
3797 
get_output_sequence_port_text(int p_port) const3798 String VisualScriptInputAction::get_output_sequence_port_text(int p_port) const {
3799 
3800 	return "";
3801 }
3802 
get_input_value_port_info(int p_idx) const3803 PropertyInfo VisualScriptInputAction::get_input_value_port_info(int p_idx) const {
3804 
3805 	return PropertyInfo();
3806 }
get_output_value_port_info(int p_idx) const3807 PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const {
3808 
3809 	String mstr;
3810 	switch (mode) {
3811 		case MODE_PRESSED: {
3812 			mstr = "pressed";
3813 		} break;
3814 		case MODE_RELEASED: {
3815 			mstr = "not pressed";
3816 		} break;
3817 		case MODE_JUST_PRESSED: {
3818 			mstr = "just pressed";
3819 		} break;
3820 		case MODE_JUST_RELEASED: {
3821 			mstr = "just released";
3822 		} break;
3823 	}
3824 
3825 	return PropertyInfo(Variant::BOOL, mstr);
3826 }
3827 
get_caption() const3828 String VisualScriptInputAction::get_caption() const {
3829 
3830 	return "Action " + name;
3831 }
3832 
get_category() const3833 String VisualScriptInputAction::get_category() const {
3834 
3835 	return "data";
3836 }
3837 
set_action_name(const StringName & p_name)3838 void VisualScriptInputAction::set_action_name(const StringName &p_name) {
3839 
3840 	if (name == p_name)
3841 		return;
3842 
3843 	name = p_name;
3844 	ports_changed_notify();
3845 }
3846 
get_action_name() const3847 StringName VisualScriptInputAction::get_action_name() const {
3848 
3849 	return name;
3850 }
3851 
set_action_mode(Mode p_mode)3852 void VisualScriptInputAction::set_action_mode(Mode p_mode) {
3853 
3854 	if (mode == p_mode)
3855 		return;
3856 
3857 	mode = p_mode;
3858 	ports_changed_notify();
3859 }
get_action_mode() const3860 VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const {
3861 
3862 	return mode;
3863 }
3864 
3865 class VisualScriptNodeInstanceInputAction : public VisualScriptNodeInstance {
3866 public:
3867 	VisualScriptInstance *instance;
3868 	StringName action;
3869 	VisualScriptInputAction::Mode mode;
3870 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)3871 	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) {
3872 
3873 		switch (mode) {
3874 			case VisualScriptInputAction::MODE_PRESSED: {
3875 				*p_outputs[0] = Input::get_singleton()->is_action_pressed(action);
3876 			} break;
3877 			case VisualScriptInputAction::MODE_RELEASED: {
3878 				*p_outputs[0] = !Input::get_singleton()->is_action_pressed(action);
3879 			} break;
3880 			case VisualScriptInputAction::MODE_JUST_PRESSED: {
3881 				*p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action);
3882 			} break;
3883 			case VisualScriptInputAction::MODE_JUST_RELEASED: {
3884 				*p_outputs[0] = Input::get_singleton()->is_action_just_released(action);
3885 			} break;
3886 		}
3887 
3888 		return 0;
3889 	}
3890 };
3891 
instance(VisualScriptInstance * p_instance)3892 VisualScriptNodeInstance *VisualScriptInputAction::instance(VisualScriptInstance *p_instance) {
3893 
3894 	VisualScriptNodeInstanceInputAction *instance = memnew(VisualScriptNodeInstanceInputAction);
3895 	instance->instance = p_instance;
3896 	instance->action = name;
3897 	instance->mode = mode;
3898 
3899 	return instance;
3900 }
3901 
_validate_property(PropertyInfo & property) const3902 void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
3903 
3904 	if (property.name == "action") {
3905 
3906 		property.hint = PROPERTY_HINT_ENUM;
3907 		String actions;
3908 
3909 		List<PropertyInfo> pinfo;
3910 		ProjectSettings::get_singleton()->get_property_list(&pinfo);
3911 		Vector<String> al;
3912 
3913 		for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
3914 			const PropertyInfo &pi = E->get();
3915 
3916 			if (!pi.name.begins_with("input/"))
3917 				continue;
3918 
3919 			String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
3920 
3921 			al.push_back(name);
3922 		}
3923 
3924 		al.sort();
3925 
3926 		for (int i = 0; i < al.size(); i++) {
3927 			if (actions != String())
3928 				actions += ",";
3929 			actions += al[i];
3930 		}
3931 
3932 		property.hint_string = actions;
3933 	}
3934 }
3935 
_bind_methods()3936 void VisualScriptInputAction::_bind_methods() {
3937 
3938 	ClassDB::bind_method(D_METHOD("set_action_name", "name"), &VisualScriptInputAction::set_action_name);
3939 	ClassDB::bind_method(D_METHOD("get_action_name"), &VisualScriptInputAction::get_action_name);
3940 
3941 	ClassDB::bind_method(D_METHOD("set_action_mode", "mode"), &VisualScriptInputAction::set_action_mode);
3942 	ClassDB::bind_method(D_METHOD("get_action_mode"), &VisualScriptInputAction::get_action_mode);
3943 
3944 	ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action_name", "get_action_name");
3945 	ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Pressed,Released,JustPressed,JustReleased"), "set_action_mode", "get_action_mode");
3946 
3947 	BIND_ENUM_CONSTANT(MODE_PRESSED);
3948 	BIND_ENUM_CONSTANT(MODE_RELEASED);
3949 	BIND_ENUM_CONSTANT(MODE_JUST_PRESSED);
3950 	BIND_ENUM_CONSTANT(MODE_JUST_RELEASED);
3951 }
3952 
VisualScriptInputAction()3953 VisualScriptInputAction::VisualScriptInputAction() {
3954 
3955 	name = "";
3956 	mode = MODE_PRESSED;
3957 }
3958 
3959 //////////////////////////////////////////
3960 ////////////////Constructor///////////
3961 //////////////////////////////////////////
3962 
get_output_sequence_port_count() const3963 int VisualScriptDeconstruct::get_output_sequence_port_count() const {
3964 
3965 	return 0;
3966 }
3967 
has_input_sequence_port() const3968 bool VisualScriptDeconstruct::has_input_sequence_port() const {
3969 
3970 	return false;
3971 }
3972 
get_input_value_port_count() const3973 int VisualScriptDeconstruct::get_input_value_port_count() const {
3974 	return 1;
3975 }
get_output_value_port_count() const3976 int VisualScriptDeconstruct::get_output_value_port_count() const {
3977 
3978 	return elements.size();
3979 }
3980 
get_output_sequence_port_text(int p_port) const3981 String VisualScriptDeconstruct::get_output_sequence_port_text(int p_port) const {
3982 
3983 	return "";
3984 }
3985 
get_input_value_port_info(int p_idx) const3986 PropertyInfo VisualScriptDeconstruct::get_input_value_port_info(int p_idx) const {
3987 
3988 	return PropertyInfo(type, "value");
3989 }
3990 
get_output_value_port_info(int p_idx) const3991 PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) const {
3992 
3993 	return PropertyInfo(elements[p_idx].type, elements[p_idx].name);
3994 }
3995 
get_caption() const3996 String VisualScriptDeconstruct::get_caption() const {
3997 
3998 	return "Deconstruct " + Variant::get_type_name(type);
3999 }
4000 
get_category() const4001 String VisualScriptDeconstruct::get_category() const {
4002 
4003 	return "functions";
4004 }
4005 
_update_elements()4006 void VisualScriptDeconstruct::_update_elements() {
4007 
4008 	elements.clear();
4009 	Variant v;
4010 	Variant::CallError ce;
4011 	v = Variant::construct(type, NULL, 0, ce);
4012 
4013 	List<PropertyInfo> pinfo;
4014 	v.get_property_list(&pinfo);
4015 
4016 	for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
4017 
4018 		Element e;
4019 		e.name = E->get().name;
4020 		e.type = E->get().type;
4021 		elements.push_back(e);
4022 	}
4023 }
4024 
set_deconstruct_type(Variant::Type p_type)4025 void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {
4026 
4027 	if (type == p_type)
4028 		return;
4029 
4030 	type = p_type;
4031 	_update_elements();
4032 	ports_changed_notify();
4033 	_change_notify(); //to make input appear/disappear
4034 }
4035 
get_deconstruct_type() const4036 Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {
4037 
4038 	return type;
4039 }
4040 
_set_elem_cache(const Array & p_elements)4041 void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) {
4042 
4043 	ERR_FAIL_COND(p_elements.size() % 2 == 1);
4044 	elements.resize(p_elements.size() / 2);
4045 	for (int i = 0; i < elements.size(); i++) {
4046 		elements.write[i].name = p_elements[i * 2 + 0];
4047 		elements.write[i].type = Variant::Type(int(p_elements[i * 2 + 1]));
4048 	}
4049 }
4050 
_get_elem_cache() const4051 Array VisualScriptDeconstruct::_get_elem_cache() const {
4052 
4053 	Array ret;
4054 	for (int i = 0; i < elements.size(); i++) {
4055 		ret.push_back(elements[i].name);
4056 		ret.push_back(elements[i].type);
4057 	}
4058 	return ret;
4059 }
4060 
4061 class VisualScriptNodeInstanceDeconstruct : public VisualScriptNodeInstance {
4062 public:
4063 	VisualScriptInstance *instance;
4064 	Vector<StringName> outputs;
4065 
4066 	//virtual int get_working_memory_size() const { return 0; }
4067 
step(const Variant ** p_inputs,Variant ** p_outputs,StartMode p_start_mode,Variant * p_working_mem,Variant::CallError & r_error,String & r_error_str)4068 	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) {
4069 
4070 		Variant in = *p_inputs[0];
4071 
4072 		for (int i = 0; i < outputs.size(); i++) {
4073 			bool valid;
4074 			*p_outputs[i] = in.get(outputs[i], &valid);
4075 			if (!valid) {
4076 				r_error_str = "Can't obtain element '" + String(outputs[i]) + "' from " + Variant::get_type_name(in.get_type());
4077 				r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
4078 				return 0;
4079 			}
4080 		}
4081 
4082 		return 0;
4083 	}
4084 };
4085 
instance(VisualScriptInstance * p_instance)4086 VisualScriptNodeInstance *VisualScriptDeconstruct::instance(VisualScriptInstance *p_instance) {
4087 
4088 	VisualScriptNodeInstanceDeconstruct *instance = memnew(VisualScriptNodeInstanceDeconstruct);
4089 	instance->instance = p_instance;
4090 	instance->outputs.resize(elements.size());
4091 	for (int i = 0; i < elements.size(); i++) {
4092 		instance->outputs.write[i] = elements[i].name;
4093 	}
4094 
4095 	return instance;
4096 }
4097 
_validate_property(PropertyInfo & property) const4098 void VisualScriptDeconstruct::_validate_property(PropertyInfo &property) const {
4099 }
4100 
_bind_methods()4101 void VisualScriptDeconstruct::_bind_methods() {
4102 
4103 	ClassDB::bind_method(D_METHOD("set_deconstruct_type", "type"), &VisualScriptDeconstruct::set_deconstruct_type);
4104 	ClassDB::bind_method(D_METHOD("get_deconstruct_type"), &VisualScriptDeconstruct::get_deconstruct_type);
4105 
4106 	ClassDB::bind_method(D_METHOD("_set_elem_cache", "_cache"), &VisualScriptDeconstruct::_set_elem_cache);
4107 	ClassDB::bind_method(D_METHOD("_get_elem_cache"), &VisualScriptDeconstruct::_get_elem_cache);
4108 
4109 	String argt = "Any";
4110 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
4111 		argt += "," + Variant::get_type_name(Variant::Type(i));
4112 	}
4113 
4114 	ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type");
4115 	ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_elem_cache", "_get_elem_cache");
4116 }
4117 
VisualScriptDeconstruct()4118 VisualScriptDeconstruct::VisualScriptDeconstruct() {
4119 
4120 	type = Variant::NIL;
4121 }
4122 
4123 template <Variant::Type T>
create_node_deconst_typed(const String & p_name)4124 static Ref<VisualScriptNode> create_node_deconst_typed(const String &p_name) {
4125 	Ref<VisualScriptDeconstruct> node;
4126 	node.instance();
4127 	node->set_deconstruct_type(T);
4128 	return node;
4129 }
4130 
register_visual_script_nodes()4131 void register_visual_script_nodes() {
4132 
4133 	VisualScriptLanguage::singleton->add_register_func("data/set_variable", create_node_generic<VisualScriptVariableSet>);
4134 	VisualScriptLanguage::singleton->add_register_func("data/get_variable", create_node_generic<VisualScriptVariableGet>);
4135 	VisualScriptLanguage::singleton->add_register_func("data/engine_singleton", create_node_generic<VisualScriptEngineSingleton>);
4136 	VisualScriptLanguage::singleton->add_register_func("data/scene_node", create_node_generic<VisualScriptSceneNode>);
4137 	VisualScriptLanguage::singleton->add_register_func("data/scene_tree", create_node_generic<VisualScriptSceneTree>);
4138 	VisualScriptLanguage::singleton->add_register_func("data/resource_path", create_node_generic<VisualScriptResourcePath>);
4139 	VisualScriptLanguage::singleton->add_register_func("data/self", create_node_generic<VisualScriptSelf>);
4140 	VisualScriptLanguage::singleton->add_register_func("data/comment", create_node_generic<VisualScriptComment>);
4141 	VisualScriptLanguage::singleton->add_register_func("data/get_local_variable", create_node_generic<VisualScriptLocalVar>);
4142 	VisualScriptLanguage::singleton->add_register_func("data/set_local_variable", create_node_generic<VisualScriptLocalVarSet>);
4143 	VisualScriptLanguage::singleton->add_register_func("data/preload", create_node_generic<VisualScriptPreload>);
4144 	VisualScriptLanguage::singleton->add_register_func("data/action", create_node_generic<VisualScriptInputAction>);
4145 
4146 	VisualScriptLanguage::singleton->add_register_func("constants/constant", create_node_generic<VisualScriptConstant>);
4147 	VisualScriptLanguage::singleton->add_register_func("constants/math_constant", create_node_generic<VisualScriptMathConstant>);
4148 	VisualScriptLanguage::singleton->add_register_func("constants/class_constant", create_node_generic<VisualScriptClassConstant>);
4149 	VisualScriptLanguage::singleton->add_register_func("constants/global_constant", create_node_generic<VisualScriptGlobalConstant>);
4150 	VisualScriptLanguage::singleton->add_register_func("constants/basic_type_constant", create_node_generic<VisualScriptBasicTypeConstant>);
4151 
4152 	VisualScriptLanguage::singleton->add_register_func("custom/custom_node", create_node_generic<VisualScriptCustomNode>);
4153 	VisualScriptLanguage::singleton->add_register_func("custom/sub_call", create_node_generic<VisualScriptSubCall>);
4154 
4155 	VisualScriptLanguage::singleton->add_register_func("index/get_index", create_node_generic<VisualScriptIndexGet>);
4156 	VisualScriptLanguage::singleton->add_register_func("index/set_index", create_node_generic<VisualScriptIndexSet>);
4157 
4158 	VisualScriptLanguage::singleton->add_register_func("operators/compare/equal", create_op_node<Variant::OP_EQUAL>);
4159 	VisualScriptLanguage::singleton->add_register_func("operators/compare/not_equal", create_op_node<Variant::OP_NOT_EQUAL>);
4160 	VisualScriptLanguage::singleton->add_register_func("operators/compare/less", create_op_node<Variant::OP_LESS>);
4161 	VisualScriptLanguage::singleton->add_register_func("operators/compare/less_equal", create_op_node<Variant::OP_LESS_EQUAL>);
4162 	VisualScriptLanguage::singleton->add_register_func("operators/compare/greater", create_op_node<Variant::OP_GREATER>);
4163 	VisualScriptLanguage::singleton->add_register_func("operators/compare/greater_equal", create_op_node<Variant::OP_GREATER_EQUAL>);
4164 	//mathematic
4165 	VisualScriptLanguage::singleton->add_register_func("operators/math/add", create_op_node<Variant::OP_ADD>);
4166 	VisualScriptLanguage::singleton->add_register_func("operators/math/subtract", create_op_node<Variant::OP_SUBTRACT>);
4167 	VisualScriptLanguage::singleton->add_register_func("operators/math/multiply", create_op_node<Variant::OP_MULTIPLY>);
4168 	VisualScriptLanguage::singleton->add_register_func("operators/math/divide", create_op_node<Variant::OP_DIVIDE>);
4169 	VisualScriptLanguage::singleton->add_register_func("operators/math/negate", create_op_node<Variant::OP_NEGATE>);
4170 	VisualScriptLanguage::singleton->add_register_func("operators/math/positive", create_op_node<Variant::OP_POSITIVE>);
4171 	VisualScriptLanguage::singleton->add_register_func("operators/math/remainder", create_op_node<Variant::OP_MODULE>);
4172 	VisualScriptLanguage::singleton->add_register_func("operators/math/string_concat", create_op_node<Variant::OP_STRING_CONCAT>);
4173 	//bitwise
4174 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_left", create_op_node<Variant::OP_SHIFT_LEFT>);
4175 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/shift_right", create_op_node<Variant::OP_SHIFT_RIGHT>);
4176 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_and", create_op_node<Variant::OP_BIT_AND>);
4177 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_or", create_op_node<Variant::OP_BIT_OR>);
4178 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_xor", create_op_node<Variant::OP_BIT_XOR>);
4179 	VisualScriptLanguage::singleton->add_register_func("operators/bitwise/bit_negate", create_op_node<Variant::OP_BIT_NEGATE>);
4180 	//logic
4181 	VisualScriptLanguage::singleton->add_register_func("operators/logic/and", create_op_node<Variant::OP_AND>);
4182 	VisualScriptLanguage::singleton->add_register_func("operators/logic/or", create_op_node<Variant::OP_OR>);
4183 	VisualScriptLanguage::singleton->add_register_func("operators/logic/xor", create_op_node<Variant::OP_XOR>);
4184 	VisualScriptLanguage::singleton->add_register_func("operators/logic/not", create_op_node<Variant::OP_NOT>);
4185 	VisualScriptLanguage::singleton->add_register_func("operators/logic/in", create_op_node<Variant::OP_IN>);
4186 	VisualScriptLanguage::singleton->add_register_func("operators/logic/select", create_node_generic<VisualScriptSelect>);
4187 
4188 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2), create_node_deconst_typed<Variant::Type::VECTOR2>);
4189 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>);
4190 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>);
4191 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>);
4192 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM2D), create_node_deconst_typed<Variant::Type::TRANSFORM2D>);
4193 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PLANE), create_node_deconst_typed<Variant::Type::PLANE>);
4194 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::QUAT), create_node_deconst_typed<Variant::Type::QUAT>);
4195 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>);
4196 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>);
4197 	VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM), create_node_deconst_typed<Variant::Type::TRANSFORM>);
4198 	VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>);
4199 
4200 	for (int i = 1; i < Variant::VARIANT_MAX; i++) {
4201 
4202 		List<MethodInfo> constructors;
4203 		Variant::get_constructor_list(Variant::Type(i), &constructors);
4204 
4205 		for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {
4206 
4207 			if (E->get().arguments.size() > 0) {
4208 				String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "(";
4209 				for (int j = 0; j < E->get().arguments.size(); j++) {
4210 					if (j > 0) {
4211 						name += ", ";
4212 					}
4213 					if (E->get().arguments.size() == 1) {
4214 						name += Variant::get_type_name(E->get().arguments[j].type);
4215 					} else {
4216 						name += E->get().arguments[j].name;
4217 					}
4218 				}
4219 				name += ")";
4220 				VisualScriptLanguage::singleton->add_register_func(name, create_constructor_node);
4221 				Pair<Variant::Type, MethodInfo> pair;
4222 				pair.first = Variant::Type(i);
4223 				pair.second = E->get();
4224 				constructor_map[name] = pair;
4225 			}
4226 		}
4227 	}
4228 }
4229 
unregister_visual_script_nodes()4230 void unregister_visual_script_nodes() {
4231 
4232 	constructor_map.clear();
4233 }
4234