visual_script_func_nodes.cpp 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515
  1. /*************************************************************************/
  2. /* visual_script_func_nodes.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2017 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. #include "visual_script_func_nodes.h"
  31. #include "io/resource_loader.h"
  32. #include "os/os.h"
  33. #include "project_settings.h"
  34. #include "scene/main/node.h"
  35. #include "scene/main/scene_tree.h"
  36. #include "visual_script_nodes.h"
  37. //////////////////////////////////////////
  38. ////////////////CALL//////////////////////
  39. //////////////////////////////////////////
  40. int VisualScriptFunctionCall::get_output_sequence_port_count() const {
  41. if (method_cache.flags & METHOD_FLAG_CONST || call_mode == CALL_MODE_BASIC_TYPE)
  42. return 0;
  43. else
  44. return 1;
  45. }
  46. bool VisualScriptFunctionCall::has_input_sequence_port() const {
  47. if (method_cache.flags & METHOD_FLAG_CONST || call_mode == CALL_MODE_BASIC_TYPE)
  48. return false;
  49. else
  50. return true;
  51. }
  52. #ifdef TOOLS_ENABLED
  53. static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
  54. if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
  55. return NULL;
  56. Ref<Script> scr = p_current_node->get_script();
  57. if (scr.is_valid() && scr == script)
  58. return p_current_node;
  59. for (int i = 0; i < p_current_node->get_child_count(); i++) {
  60. Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
  61. if (n)
  62. return n;
  63. }
  64. return NULL;
  65. }
  66. #endif
  67. Node *VisualScriptFunctionCall::_get_base_node() const {
  68. #ifdef TOOLS_ENABLED
  69. Ref<Script> script = get_visual_script();
  70. if (!script.is_valid())
  71. return NULL;
  72. MainLoop *main_loop = OS::get_singleton()->get_main_loop();
  73. SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
  74. if (!scene_tree)
  75. return NULL;
  76. Node *edited_scene = scene_tree->get_edited_scene_root();
  77. if (!edited_scene)
  78. return NULL;
  79. Node *script_node = _find_script_node(edited_scene, edited_scene, script);
  80. if (!script_node)
  81. return NULL;
  82. if (!script_node->has_node(base_path))
  83. return NULL;
  84. Node *path_to = script_node->get_node(base_path);
  85. return path_to;
  86. #else
  87. return NULL;
  88. #endif
  89. }
  90. StringName VisualScriptFunctionCall::_get_base_type() const {
  91. if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
  92. return get_visual_script()->get_instance_base_type();
  93. else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
  94. Node *path = _get_base_node();
  95. if (path)
  96. return path->get_class();
  97. }
  98. return base_type;
  99. }
  100. int VisualScriptFunctionCall::get_input_value_port_count() const {
  101. if (call_mode == CALL_MODE_BASIC_TYPE) {
  102. Vector<StringName> names = Variant::get_method_argument_names(basic_type, function);
  103. return names.size() + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) + 1;
  104. } else {
  105. MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
  106. if (mb) {
  107. return mb->get_argument_count() + (call_mode == CALL_MODE_INSTANCE ? 1 : 0) + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) - use_default_args;
  108. }
  109. return method_cache.arguments.size() + (call_mode == CALL_MODE_INSTANCE ? 1 : 0) + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) - use_default_args;
  110. }
  111. }
  112. int VisualScriptFunctionCall::get_output_value_port_count() const {
  113. if (call_mode == CALL_MODE_BASIC_TYPE) {
  114. bool returns = false;
  115. Variant::get_method_return_type(basic_type, function, &returns);
  116. return returns ? 1 : 0;
  117. } else {
  118. int ret;
  119. MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
  120. if (mb) {
  121. ret = mb->has_return() ? 1 : 0;
  122. } else
  123. ret = 1; //it is assumed that script always returns something
  124. if (call_mode == CALL_MODE_INSTANCE) {
  125. ret++;
  126. }
  127. return ret;
  128. }
  129. }
  130. String VisualScriptFunctionCall::get_output_sequence_port_text(int p_port) const {
  131. return String();
  132. }
  133. PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) const {
  134. if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
  135. if (p_idx == 0) {
  136. PropertyInfo pi;
  137. pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type);
  138. pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower());
  139. return pi;
  140. } else {
  141. p_idx--;
  142. }
  143. }
  144. if (rpc_call_mode >= RPC_RELIABLE_TO_ID) {
  145. if (p_idx == 0) {
  146. return PropertyInfo(Variant::INT, "peer_id");
  147. } else {
  148. p_idx--;
  149. }
  150. }
  151. #ifdef DEBUG_METHODS_ENABLED
  152. if (call_mode == CALL_MODE_BASIC_TYPE) {
  153. Vector<StringName> names = Variant::get_method_argument_names(basic_type, function);
  154. Vector<Variant::Type> types = Variant::get_method_argument_types(basic_type, function);
  155. return PropertyInfo(types[p_idx], names[p_idx]);
  156. } else {
  157. MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
  158. if (mb) {
  159. return mb->get_argument_info(p_idx);
  160. }
  161. if (p_idx >= 0 && p_idx < method_cache.arguments.size()) {
  162. return method_cache.arguments[p_idx];
  163. }
  164. return PropertyInfo();
  165. }
  166. #else
  167. return PropertyInfo();
  168. #endif
  169. }
  170. PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) const {
  171. #ifdef DEBUG_METHODS_ENABLED
  172. if (call_mode == CALL_MODE_BASIC_TYPE) {
  173. return PropertyInfo(Variant::get_method_return_type(basic_type, function), "");
  174. } else {
  175. if (call_mode == CALL_MODE_INSTANCE) {
  176. if (p_idx == 0) {
  177. return PropertyInfo(Variant::OBJECT, "pass");
  178. } else {
  179. p_idx--;
  180. }
  181. }
  182. PropertyInfo ret;
  183. /*MethodBind *mb = ClassDB::get_method(_get_base_type(),function);
  184. if (mb) {
  185. ret = mb->get_argument_info(-1);
  186. } else {*/
  187. ret = method_cache.return_val;
  188. //}
  189. if (call_mode == CALL_MODE_INSTANCE) {
  190. ret.name = "return";
  191. } else {
  192. ret.name = "";
  193. }
  194. return ret;
  195. }
  196. #else
  197. return PropertyInfo();
  198. #endif
  199. }
  200. String VisualScriptFunctionCall::get_caption() const {
  201. static const char *cname[5] = {
  202. "CallSelf",
  203. "CallNode",
  204. "CallInstance",
  205. "CallBasic",
  206. "CallSingleton"
  207. };
  208. String caption = cname[call_mode];
  209. if (rpc_call_mode) {
  210. caption += " (RPC)";
  211. }
  212. return caption;
  213. }
  214. String VisualScriptFunctionCall::get_text() const {
  215. if (call_mode == CALL_MODE_SELF)
  216. return " " + String(function) + "()";
  217. if (call_mode == CALL_MODE_SINGLETON)
  218. return String(singleton) + ":" + String(function) + "()";
  219. else if (call_mode == CALL_MODE_BASIC_TYPE)
  220. return Variant::get_type_name(basic_type) + "." + String(function) + "()";
  221. else if (call_mode == CALL_MODE_NODE_PATH)
  222. return " [" + String(base_path.simplified()) + "]." + String(function) + "()";
  223. else
  224. return " " + base_type + "." + String(function) + "()";
  225. }
  226. void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
  227. if (basic_type == p_type)
  228. return;
  229. basic_type = p_type;
  230. _change_notify();
  231. ports_changed_notify();
  232. }
  233. Variant::Type VisualScriptFunctionCall::get_basic_type() const {
  234. return basic_type;
  235. }
  236. void VisualScriptFunctionCall::set_base_type(const StringName &p_type) {
  237. if (base_type == p_type)
  238. return;
  239. base_type = p_type;
  240. _change_notify();
  241. ports_changed_notify();
  242. }
  243. StringName VisualScriptFunctionCall::get_base_type() const {
  244. return base_type;
  245. }
  246. void VisualScriptFunctionCall::set_base_script(const String &p_path) {
  247. if (base_script == p_path)
  248. return;
  249. base_script = p_path;
  250. _change_notify();
  251. ports_changed_notify();
  252. }
  253. String VisualScriptFunctionCall::get_base_script() const {
  254. return base_script;
  255. }
  256. void VisualScriptFunctionCall::set_singleton(const StringName &p_type) {
  257. if (singleton == p_type)
  258. return;
  259. singleton = p_type;
  260. Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
  261. if (obj) {
  262. base_type = obj->get_class();
  263. }
  264. _change_notify();
  265. ports_changed_notify();
  266. }
  267. StringName VisualScriptFunctionCall::get_singleton() const {
  268. return singleton;
  269. }
  270. void VisualScriptFunctionCall::_update_method_cache() {
  271. StringName type;
  272. Ref<Script> script;
  273. if (call_mode == CALL_MODE_NODE_PATH) {
  274. Node *node = _get_base_node();
  275. if (node) {
  276. type = node->get_class();
  277. base_type = type; //cache, too
  278. script = node->get_script();
  279. }
  280. } else if (call_mode == CALL_MODE_SELF) {
  281. if (get_visual_script().is_valid()) {
  282. type = get_visual_script()->get_instance_base_type();
  283. base_type = type; //cache, too
  284. script = get_visual_script();
  285. }
  286. } else if (call_mode == CALL_MODE_SINGLETON) {
  287. Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
  288. if (obj) {
  289. type = obj->get_class();
  290. script = obj->get_script();
  291. }
  292. } else if (call_mode == CALL_MODE_INSTANCE) {
  293. type = base_type;
  294. if (base_script != String()) {
  295. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  296. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  297. }
  298. if (ResourceCache::has(base_script)) {
  299. script = Ref<Resource>(ResourceCache::get(base_script));
  300. } else {
  301. return;
  302. }
  303. }
  304. }
  305. //print_line("BASE: "+String(type)+" FUNC: "+String(function));
  306. MethodBind *mb = ClassDB::get_method(type, function);
  307. if (mb) {
  308. use_default_args = mb->get_default_argument_count();
  309. method_cache = MethodInfo();
  310. for (int i = 0; i < mb->get_argument_count(); i++) {
  311. #ifdef DEBUG_METHODS_ENABLED
  312. method_cache.arguments.push_back(mb->get_argument_info(i));
  313. #else
  314. method_cache.arguments.push_back(PropertyInfo());
  315. #endif
  316. }
  317. if (mb->is_const()) {
  318. method_cache.flags |= METHOD_FLAG_CONST;
  319. }
  320. #ifdef DEBUG_METHODS_ENABLED
  321. method_cache.return_val = mb->get_argument_info(-1);
  322. #endif
  323. if (mb->is_vararg()) {
  324. //for vararg just give it 10 arguments (should be enough for most use cases)
  325. for (int i = 0; i < 10; i++) {
  326. method_cache.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
  327. use_default_args++;
  328. }
  329. }
  330. } else if (script.is_valid() && script->has_method(function)) {
  331. method_cache = script->get_method_info(function);
  332. use_default_args = method_cache.default_arguments.size();
  333. }
  334. }
  335. void VisualScriptFunctionCall::set_function(const StringName &p_type) {
  336. if (function == p_type)
  337. return;
  338. function = p_type;
  339. if (call_mode == CALL_MODE_BASIC_TYPE) {
  340. use_default_args = Variant::get_method_default_arguments(basic_type, function).size();
  341. } else {
  342. //update all caches
  343. _update_method_cache();
  344. }
  345. _change_notify();
  346. ports_changed_notify();
  347. }
  348. StringName VisualScriptFunctionCall::get_function() const {
  349. return function;
  350. }
  351. void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) {
  352. if (base_path == p_type)
  353. return;
  354. base_path = p_type;
  355. _change_notify();
  356. ports_changed_notify();
  357. }
  358. NodePath VisualScriptFunctionCall::get_base_path() const {
  359. return base_path;
  360. }
  361. void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) {
  362. if (call_mode == p_mode)
  363. return;
  364. call_mode = p_mode;
  365. _change_notify();
  366. ports_changed_notify();
  367. }
  368. VisualScriptFunctionCall::CallMode VisualScriptFunctionCall::get_call_mode() const {
  369. return call_mode;
  370. }
  371. void VisualScriptFunctionCall::set_use_default_args(int p_amount) {
  372. if (use_default_args == p_amount)
  373. return;
  374. use_default_args = p_amount;
  375. ports_changed_notify();
  376. }
  377. void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCallMode p_mode) {
  378. if (rpc_call_mode == p_mode)
  379. return;
  380. rpc_call_mode = p_mode;
  381. ports_changed_notify();
  382. _change_notify();
  383. }
  384. VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const {
  385. return rpc_call_mode;
  386. }
  387. int VisualScriptFunctionCall::get_use_default_args() const {
  388. return use_default_args;
  389. }
  390. void VisualScriptFunctionCall::set_validate(bool p_amount) {
  391. validate = p_amount;
  392. }
  393. bool VisualScriptFunctionCall::get_validate() const {
  394. return validate;
  395. }
  396. void VisualScriptFunctionCall::_set_argument_cache(const Dictionary &p_cache) {
  397. //so everything works in case all else fails
  398. method_cache = MethodInfo::from_dict(p_cache);
  399. }
  400. Dictionary VisualScriptFunctionCall::_get_argument_cache() const {
  401. return method_cache;
  402. }
  403. void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const {
  404. if (property.name == "base_type") {
  405. if (call_mode != CALL_MODE_INSTANCE) {
  406. property.usage = PROPERTY_USAGE_NOEDITOR;
  407. }
  408. }
  409. if (property.name == "base_script") {
  410. if (call_mode != CALL_MODE_INSTANCE) {
  411. property.usage = 0;
  412. }
  413. }
  414. if (property.name == "basic_type") {
  415. if (call_mode != CALL_MODE_BASIC_TYPE) {
  416. property.usage = 0;
  417. }
  418. }
  419. if (property.name == "singleton") {
  420. if (call_mode != CALL_MODE_SINGLETON) {
  421. property.usage = 0;
  422. } else {
  423. List<ProjectSettings::Singleton> names;
  424. ProjectSettings::get_singleton()->get_singletons(&names);
  425. property.hint = PROPERTY_HINT_ENUM;
  426. String sl;
  427. for (List<ProjectSettings::Singleton>::Element *E = names.front(); E; E = E->next()) {
  428. if (sl != String())
  429. sl += ",";
  430. sl += E->get().name;
  431. }
  432. property.hint_string = sl;
  433. }
  434. }
  435. if (property.name == "node_path") {
  436. if (call_mode != CALL_MODE_NODE_PATH) {
  437. property.usage = 0;
  438. } else {
  439. Node *bnode = _get_base_node();
  440. if (bnode) {
  441. property.hint_string = bnode->get_path(); //convert to loong string
  442. } else {
  443. }
  444. }
  445. }
  446. if (property.name == "function") {
  447. if (call_mode == CALL_MODE_BASIC_TYPE) {
  448. property.hint = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE;
  449. property.hint_string = Variant::get_type_name(basic_type);
  450. } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
  451. property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT;
  452. property.hint_string = itos(get_visual_script()->get_instance_id());
  453. } else if (call_mode == CALL_MODE_SINGLETON) {
  454. Object *obj = ProjectSettings::get_singleton()->get_singleton_object(singleton);
  455. if (obj) {
  456. property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE;
  457. property.hint_string = itos(obj->get_instance_id());
  458. } else {
  459. property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE;
  460. property.hint_string = base_type; //should be cached
  461. }
  462. } else if (call_mode == CALL_MODE_INSTANCE) {
  463. property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE;
  464. property.hint_string = base_type;
  465. if (base_script != String()) {
  466. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  467. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  468. }
  469. if (ResourceCache::has(base_script)) {
  470. Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
  471. if (script.is_valid()) {
  472. property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT;
  473. property.hint_string = itos(script->get_instance_id());
  474. }
  475. }
  476. }
  477. } else if (call_mode == CALL_MODE_NODE_PATH) {
  478. Node *node = _get_base_node();
  479. if (node) {
  480. property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE;
  481. property.hint_string = itos(node->get_instance_id());
  482. } else {
  483. property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE;
  484. property.hint_string = get_base_type();
  485. }
  486. }
  487. }
  488. if (property.name == "use_default_args") {
  489. property.hint = PROPERTY_HINT_RANGE;
  490. int mc = 0;
  491. if (call_mode == CALL_MODE_BASIC_TYPE) {
  492. mc = Variant::get_method_default_arguments(basic_type, function).size();
  493. } else {
  494. MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
  495. if (mb) {
  496. mc = mb->get_default_argument_count();
  497. }
  498. }
  499. if (mc == 0) {
  500. property.usage = 0; //do not show
  501. } else {
  502. property.hint_string = "0," + itos(mc) + ",1";
  503. }
  504. }
  505. if (property.name == "rpc_call_mode") {
  506. if (call_mode == CALL_MODE_BASIC_TYPE) {
  507. property.usage = 0;
  508. }
  509. }
  510. }
  511. void VisualScriptFunctionCall::_bind_methods() {
  512. ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptFunctionCall::set_base_type);
  513. ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptFunctionCall::get_base_type);
  514. ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptFunctionCall::set_base_script);
  515. ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptFunctionCall::get_base_script);
  516. ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptFunctionCall::set_basic_type);
  517. ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptFunctionCall::get_basic_type);
  518. ClassDB::bind_method(D_METHOD("set_singleton", "singleton"), &VisualScriptFunctionCall::set_singleton);
  519. ClassDB::bind_method(D_METHOD("get_singleton"), &VisualScriptFunctionCall::get_singleton);
  520. ClassDB::bind_method(D_METHOD("set_function", "function"), &VisualScriptFunctionCall::set_function);
  521. ClassDB::bind_method(D_METHOD("get_function"), &VisualScriptFunctionCall::get_function);
  522. ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptFunctionCall::set_call_mode);
  523. ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptFunctionCall::get_call_mode);
  524. ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptFunctionCall::set_base_path);
  525. ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptFunctionCall::get_base_path);
  526. ClassDB::bind_method(D_METHOD("set_use_default_args", "amount"), &VisualScriptFunctionCall::set_use_default_args);
  527. ClassDB::bind_method(D_METHOD("get_use_default_args"), &VisualScriptFunctionCall::get_use_default_args);
  528. ClassDB::bind_method(D_METHOD("_set_argument_cache", "argument_cache"), &VisualScriptFunctionCall::_set_argument_cache);
  529. ClassDB::bind_method(D_METHOD("_get_argument_cache"), &VisualScriptFunctionCall::_get_argument_cache);
  530. ClassDB::bind_method(D_METHOD("set_rpc_call_mode", "mode"), &VisualScriptFunctionCall::set_rpc_call_mode);
  531. ClassDB::bind_method(D_METHOD("get_rpc_call_mode"), &VisualScriptFunctionCall::get_rpc_call_mode);
  532. ClassDB::bind_method(D_METHOD("set_validate", "enable"), &VisualScriptFunctionCall::set_validate);
  533. ClassDB::bind_method(D_METHOD("get_validate"), &VisualScriptFunctionCall::get_validate);
  534. String bt;
  535. for (int i = 0; i < Variant::VARIANT_MAX; i++) {
  536. if (i > 0)
  537. bt += ",";
  538. bt += Variant::get_type_name(Variant::Type(i));
  539. }
  540. List<String> script_extensions;
  541. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  542. ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
  543. }
  544. String script_ext_hint;
  545. for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
  546. if (script_ext_hint != String())
  547. script_ext_hint += ",";
  548. script_ext_hint += "*." + E->get();
  549. }
  550. ADD_PROPERTY(PropertyInfo(Variant::INT, "call_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type,Singleton"), "set_call_mode", "get_call_mode");
  551. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
  552. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
  553. ADD_PROPERTY(PropertyInfo(Variant::STRING, "singleton"), "set_singleton", "get_singleton");
  554. ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type");
  555. ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path");
  556. ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "argument_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_argument_cache", "_get_argument_cache");
  557. ADD_PROPERTY(PropertyInfo(Variant::STRING, "function"), "set_function", "get_function"); //when set, if loaded properly, will override argument count.
  558. ADD_PROPERTY(PropertyInfo(Variant::INT, "use_default_args"), "set_use_default_args", "get_use_default_args");
  559. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "validate"), "set_validate", "get_validate");
  560. ADD_PROPERTY(PropertyInfo(Variant::INT, "rpc_call_mode", PROPERTY_HINT_ENUM, "Disabled,Reliable,Unreliable,ReliableToID,UnreliableToID"), "set_rpc_call_mode", "get_rpc_call_mode"); //when set, if loaded properly, will override argument count.
  561. BIND_ENUM_CONSTANT(CALL_MODE_SELF);
  562. BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH);
  563. BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE);
  564. BIND_ENUM_CONSTANT(CALL_MODE_BASIC_TYPE);
  565. }
  566. class VisualScriptNodeInstanceFunctionCall : public VisualScriptNodeInstance {
  567. public:
  568. VisualScriptFunctionCall::CallMode call_mode;
  569. NodePath node_path;
  570. int input_args;
  571. bool validate;
  572. bool returns;
  573. VisualScriptFunctionCall::RPCCallMode rpc_mode;
  574. StringName function;
  575. StringName singleton;
  576. VisualScriptFunctionCall *node;
  577. VisualScriptInstance *instance;
  578. //virtual int get_working_memory_size() const { return 0; }
  579. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  580. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  581. _FORCE_INLINE_ bool call_rpc(Object *p_base, const Variant **p_args, int p_argcount) {
  582. if (!p_base)
  583. return false;
  584. Node *node = Object::cast_to<Node>(p_base);
  585. if (!node)
  586. return false;
  587. int to_id = 0;
  588. bool reliable = true;
  589. if (rpc_mode >= VisualScriptFunctionCall::RPC_RELIABLE_TO_ID) {
  590. to_id = *p_args[0];
  591. p_args += 1;
  592. p_argcount -= 1;
  593. if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE_TO_ID) {
  594. reliable = false;
  595. }
  596. } else if (rpc_mode == VisualScriptFunctionCall::RPC_UNRELIABLE) {
  597. reliable = false;
  598. }
  599. node->rpcp(to_id, !reliable, function, p_args, p_argcount);
  600. return true;
  601. }
  602. 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) {
  603. switch (call_mode) {
  604. case VisualScriptFunctionCall::CALL_MODE_SELF: {
  605. Object *object = instance->get_owner_ptr();
  606. if (rpc_mode) {
  607. call_rpc(object, p_inputs, input_args);
  608. } else if (returns) {
  609. *p_outputs[0] = object->call(function, p_inputs, input_args, r_error);
  610. } else {
  611. object->call(function, p_inputs, input_args, r_error);
  612. }
  613. } break;
  614. case VisualScriptFunctionCall::CALL_MODE_NODE_PATH: {
  615. Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
  616. if (!node) {
  617. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  618. r_error_str = "Base object is not a Node!";
  619. return 0;
  620. }
  621. Node *another = node->get_node(node_path);
  622. if (!another) {
  623. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  624. r_error_str = "Path does not lead Node!";
  625. return 0;
  626. }
  627. if (rpc_mode) {
  628. call_rpc(node, p_inputs, input_args);
  629. } else if (returns) {
  630. *p_outputs[0] = another->call(function, p_inputs, input_args, r_error);
  631. } else {
  632. another->call(function, p_inputs, input_args, r_error);
  633. }
  634. } break;
  635. case VisualScriptFunctionCall::CALL_MODE_INSTANCE:
  636. case VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE: {
  637. Variant v = *p_inputs[0];
  638. if (rpc_mode) {
  639. Object *obj = v;
  640. if (obj) {
  641. call_rpc(obj, p_inputs + 1, input_args - 1);
  642. }
  643. } else if (returns) {
  644. if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
  645. *p_outputs[1] = v.call(function, p_inputs + 1, input_args, r_error);
  646. } else {
  647. *p_outputs[0] = v.call(function, p_inputs + 1, input_args, r_error);
  648. }
  649. } else {
  650. v.call(function, p_inputs + 1, input_args, r_error);
  651. }
  652. if (call_mode == VisualScriptFunctionCall::CALL_MODE_INSTANCE) {
  653. *p_outputs[0] = *p_inputs[0];
  654. }
  655. } break;
  656. case VisualScriptFunctionCall::CALL_MODE_SINGLETON: {
  657. Object *object = ProjectSettings::get_singleton()->get_singleton_object(singleton);
  658. if (!object) {
  659. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  660. r_error_str = "Invalid singleton name: '" + String(singleton) + "'";
  661. return 0;
  662. }
  663. if (rpc_mode) {
  664. call_rpc(object, p_inputs, input_args);
  665. } else if (returns) {
  666. *p_outputs[0] = object->call(function, p_inputs, input_args, r_error);
  667. } else {
  668. object->call(function, p_inputs, input_args, r_error);
  669. }
  670. } break;
  671. }
  672. if (!validate) {
  673. //ignore call errors if validation is disabled
  674. r_error.error = Variant::CallError::CALL_OK;
  675. r_error_str = String();
  676. }
  677. return 0;
  678. }
  679. };
  680. VisualScriptNodeInstance *VisualScriptFunctionCall::instance(VisualScriptInstance *p_instance) {
  681. VisualScriptNodeInstanceFunctionCall *instance = memnew(VisualScriptNodeInstanceFunctionCall);
  682. instance->node = this;
  683. instance->instance = p_instance;
  684. instance->singleton = singleton;
  685. instance->function = function;
  686. instance->call_mode = call_mode;
  687. instance->returns = get_output_value_port_count();
  688. instance->node_path = base_path;
  689. instance->input_args = get_input_value_port_count() - ((call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0);
  690. instance->rpc_mode = rpc_call_mode;
  691. instance->validate = validate;
  692. return instance;
  693. }
  694. VisualScriptFunctionCall::TypeGuess VisualScriptFunctionCall::guess_output_type(TypeGuess *p_inputs, int p_output) const {
  695. if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) {
  696. return p_inputs[0];
  697. }
  698. return VisualScriptNode::guess_output_type(p_inputs, p_output);
  699. }
  700. VisualScriptFunctionCall::VisualScriptFunctionCall() {
  701. validate = true;
  702. call_mode = CALL_MODE_SELF;
  703. basic_type = Variant::NIL;
  704. use_default_args = 0;
  705. base_type = "Object";
  706. rpc_call_mode = RPC_DISABLED;
  707. }
  708. template <VisualScriptFunctionCall::CallMode cmode>
  709. static Ref<VisualScriptNode> create_function_call_node(const String &p_name) {
  710. Ref<VisualScriptFunctionCall> node;
  711. node.instance();
  712. node->set_call_mode(cmode);
  713. return node;
  714. }
  715. //////////////////////////////////////////
  716. ////////////////SET//////////////////////
  717. //////////////////////////////////////////
  718. int VisualScriptPropertySet::get_output_sequence_port_count() const {
  719. return call_mode != CALL_MODE_BASIC_TYPE ? 1 : 0;
  720. }
  721. bool VisualScriptPropertySet::has_input_sequence_port() const {
  722. return call_mode != CALL_MODE_BASIC_TYPE ? true : false;
  723. }
  724. Node *VisualScriptPropertySet::_get_base_node() const {
  725. #ifdef TOOLS_ENABLED
  726. Ref<Script> script = get_visual_script();
  727. if (!script.is_valid())
  728. return NULL;
  729. MainLoop *main_loop = OS::get_singleton()->get_main_loop();
  730. SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
  731. if (!scene_tree)
  732. return NULL;
  733. Node *edited_scene = scene_tree->get_edited_scene_root();
  734. if (!edited_scene)
  735. return NULL;
  736. Node *script_node = _find_script_node(edited_scene, edited_scene, script);
  737. if (!script_node)
  738. return NULL;
  739. if (!script_node->has_node(base_path))
  740. return NULL;
  741. Node *path_to = script_node->get_node(base_path);
  742. return path_to;
  743. #else
  744. return NULL;
  745. #endif
  746. }
  747. StringName VisualScriptPropertySet::_get_base_type() const {
  748. if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
  749. return get_visual_script()->get_instance_base_type();
  750. else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
  751. Node *path = _get_base_node();
  752. if (path)
  753. return path->get_class();
  754. }
  755. return base_type;
  756. }
  757. int VisualScriptPropertySet::get_input_value_port_count() const {
  758. int pc = (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 2 : 1;
  759. return pc;
  760. }
  761. int VisualScriptPropertySet::get_output_value_port_count() const {
  762. return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0;
  763. }
  764. String VisualScriptPropertySet::get_output_sequence_port_text(int p_port) const {
  765. return String();
  766. }
  767. void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const {
  768. if (index != StringName()) {
  769. Variant v;
  770. Variant::CallError ce;
  771. v = Variant::construct(pinfo.type, NULL, 0, ce);
  772. Variant i = v.get(index);
  773. pinfo.type = i.get_type();
  774. }
  775. }
  776. PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const {
  777. if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
  778. if (p_idx == 0) {
  779. PropertyInfo pi;
  780. pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type);
  781. pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower());
  782. _adjust_input_index(pi);
  783. return pi;
  784. } else {
  785. p_idx--;
  786. }
  787. }
  788. PropertyInfo pinfo = type_cache;
  789. pinfo.name = "value";
  790. _adjust_input_index(pinfo);
  791. return pinfo;
  792. }
  793. PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) const {
  794. if (call_mode == CALL_MODE_BASIC_TYPE) {
  795. return PropertyInfo(basic_type, "out");
  796. } else if (call_mode == CALL_MODE_INSTANCE) {
  797. return PropertyInfo(Variant::OBJECT, "pass");
  798. } else {
  799. return PropertyInfo();
  800. }
  801. }
  802. String VisualScriptPropertySet::get_caption() const {
  803. static const char *cname[4] = {
  804. "Self",
  805. "Node",
  806. "Instance",
  807. "Basic"
  808. };
  809. static const char *opname[ASSIGN_OP_MAX] = {
  810. "Set", "Add", "Sub", "Mul", "Div", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor"
  811. };
  812. return String(cname[call_mode]) + opname[assign_op];
  813. }
  814. String VisualScriptPropertySet::get_text() const {
  815. String prop;
  816. if (call_mode == CALL_MODE_BASIC_TYPE)
  817. prop = Variant::get_type_name(basic_type) + "." + property;
  818. else if (call_mode == CALL_MODE_NODE_PATH)
  819. prop = String(base_path) + ":" + property;
  820. else if (call_mode == CALL_MODE_SELF)
  821. prop = property;
  822. else if (call_mode == CALL_MODE_INSTANCE)
  823. prop = String(base_type) + ":" + property;
  824. if (index != StringName()) {
  825. prop += "." + String(index);
  826. }
  827. return prop;
  828. }
  829. void VisualScriptPropertySet::_update_base_type() {
  830. //cache it because this information may not be available on load
  831. if (call_mode == CALL_MODE_NODE_PATH) {
  832. Node *node = _get_base_node();
  833. if (node) {
  834. base_type = node->get_class();
  835. }
  836. } else if (call_mode == CALL_MODE_SELF) {
  837. if (get_visual_script().is_valid()) {
  838. base_type = get_visual_script()->get_instance_base_type();
  839. }
  840. }
  841. }
  842. void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
  843. if (basic_type == p_type)
  844. return;
  845. basic_type = p_type;
  846. _change_notify();
  847. _update_base_type();
  848. ports_changed_notify();
  849. }
  850. Variant::Type VisualScriptPropertySet::get_basic_type() const {
  851. return basic_type;
  852. }
  853. void VisualScriptPropertySet::set_base_type(const StringName &p_type) {
  854. if (base_type == p_type)
  855. return;
  856. base_type = p_type;
  857. _change_notify();
  858. ports_changed_notify();
  859. }
  860. StringName VisualScriptPropertySet::get_base_type() const {
  861. return base_type;
  862. }
  863. void VisualScriptPropertySet::set_base_script(const String &p_path) {
  864. if (base_script == p_path)
  865. return;
  866. base_script = p_path;
  867. _change_notify();
  868. ports_changed_notify();
  869. }
  870. String VisualScriptPropertySet::get_base_script() const {
  871. return base_script;
  872. }
  873. void VisualScriptPropertySet::_update_cache() {
  874. if (!Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()))
  875. return;
  876. if (!Engine::get_singleton()->is_editor_hint()) //only update cache if editor exists, it's pointless otherwise
  877. return;
  878. if (call_mode == CALL_MODE_BASIC_TYPE) {
  879. //not super efficient..
  880. Variant v;
  881. Variant::CallError ce;
  882. v = Variant::construct(basic_type, NULL, 0, ce);
  883. List<PropertyInfo> pinfo;
  884. v.get_property_list(&pinfo);
  885. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  886. if (E->get().name == property) {
  887. type_cache = E->get();
  888. }
  889. }
  890. } else {
  891. StringName type;
  892. Ref<Script> script;
  893. Node *node = NULL;
  894. if (call_mode == CALL_MODE_NODE_PATH) {
  895. node = _get_base_node();
  896. if (node) {
  897. type = node->get_class();
  898. base_type = type; //cache, too
  899. script = node->get_script();
  900. }
  901. } else if (call_mode == CALL_MODE_SELF) {
  902. if (get_visual_script().is_valid()) {
  903. type = get_visual_script()->get_instance_base_type();
  904. base_type = type; //cache, too
  905. script = get_visual_script();
  906. }
  907. } else if (call_mode == CALL_MODE_INSTANCE) {
  908. type = base_type;
  909. if (base_script != String()) {
  910. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  911. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  912. }
  913. if (ResourceCache::has(base_script)) {
  914. script = Ref<Resource>(ResourceCache::get(base_script));
  915. } else {
  916. return;
  917. }
  918. }
  919. }
  920. List<PropertyInfo> pinfo;
  921. if (node) {
  922. node->get_property_list(&pinfo);
  923. } else {
  924. ClassDB::get_property_list(type, &pinfo);
  925. }
  926. if (script.is_valid()) {
  927. script->get_script_property_list(&pinfo);
  928. }
  929. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  930. if (E->get().name == property) {
  931. type_cache = E->get();
  932. return;
  933. }
  934. }
  935. }
  936. }
  937. void VisualScriptPropertySet::set_property(const StringName &p_type) {
  938. if (property == p_type)
  939. return;
  940. property = p_type;
  941. index = StringName();
  942. _update_cache();
  943. _change_notify();
  944. ports_changed_notify();
  945. }
  946. StringName VisualScriptPropertySet::get_property() const {
  947. return property;
  948. }
  949. void VisualScriptPropertySet::set_base_path(const NodePath &p_type) {
  950. if (base_path == p_type)
  951. return;
  952. base_path = p_type;
  953. _update_base_type();
  954. _change_notify();
  955. ports_changed_notify();
  956. }
  957. NodePath VisualScriptPropertySet::get_base_path() const {
  958. return base_path;
  959. }
  960. void VisualScriptPropertySet::set_call_mode(CallMode p_mode) {
  961. if (call_mode == p_mode)
  962. return;
  963. call_mode = p_mode;
  964. _update_base_type();
  965. _change_notify();
  966. ports_changed_notify();
  967. }
  968. VisualScriptPropertySet::CallMode VisualScriptPropertySet::get_call_mode() const {
  969. return call_mode;
  970. }
  971. void VisualScriptPropertySet::_set_type_cache(const Dictionary &p_type) {
  972. type_cache = PropertyInfo::from_dict(p_type);
  973. }
  974. Dictionary VisualScriptPropertySet::_get_type_cache() const {
  975. return type_cache;
  976. }
  977. void VisualScriptPropertySet::set_index(const StringName &p_type) {
  978. if (index == p_type)
  979. return;
  980. index = p_type;
  981. _update_cache();
  982. _change_notify();
  983. ports_changed_notify();
  984. }
  985. StringName VisualScriptPropertySet::get_index() const {
  986. return index;
  987. }
  988. void VisualScriptPropertySet::set_assign_op(AssignOp p_op) {
  989. ERR_FAIL_INDEX(p_op, ASSIGN_OP_MAX);
  990. if (assign_op == p_op)
  991. return;
  992. assign_op = p_op;
  993. _update_cache();
  994. _change_notify();
  995. ports_changed_notify();
  996. }
  997. VisualScriptPropertySet::AssignOp VisualScriptPropertySet::get_assign_op() const {
  998. return assign_op;
  999. }
  1000. void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
  1001. if (property.name == "base_type") {
  1002. if (call_mode != CALL_MODE_INSTANCE) {
  1003. property.usage = PROPERTY_USAGE_NOEDITOR;
  1004. }
  1005. }
  1006. if (property.name == "base_script") {
  1007. if (call_mode != CALL_MODE_INSTANCE) {
  1008. property.usage = 0;
  1009. }
  1010. }
  1011. if (property.name == "basic_type") {
  1012. if (call_mode != CALL_MODE_BASIC_TYPE) {
  1013. property.usage = 0;
  1014. }
  1015. }
  1016. if (property.name == "node_path") {
  1017. if (call_mode != CALL_MODE_NODE_PATH) {
  1018. property.usage = 0;
  1019. } else {
  1020. Node *bnode = _get_base_node();
  1021. if (bnode) {
  1022. property.hint_string = bnode->get_path(); //convert to loong string
  1023. } else {
  1024. }
  1025. }
  1026. }
  1027. if (property.name == "property") {
  1028. if (call_mode == CALL_MODE_BASIC_TYPE) {
  1029. property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
  1030. property.hint_string = Variant::get_type_name(basic_type);
  1031. } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
  1032. property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
  1033. property.hint_string = itos(get_visual_script()->get_instance_id());
  1034. } else if (call_mode == CALL_MODE_INSTANCE) {
  1035. property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
  1036. property.hint_string = base_type;
  1037. if (base_script != String()) {
  1038. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  1039. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  1040. }
  1041. if (ResourceCache::has(base_script)) {
  1042. Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
  1043. if (script.is_valid()) {
  1044. property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
  1045. property.hint_string = itos(script->get_instance_id());
  1046. }
  1047. }
  1048. }
  1049. } else if (call_mode == CALL_MODE_NODE_PATH) {
  1050. Node *node = _get_base_node();
  1051. if (node) {
  1052. property.hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE;
  1053. property.hint_string = itos(node->get_instance_id());
  1054. } else {
  1055. property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
  1056. property.hint_string = get_base_type();
  1057. }
  1058. }
  1059. }
  1060. if (property.name == "index") {
  1061. Variant::CallError ce;
  1062. Variant v = Variant::construct(type_cache.type, NULL, 0, ce);
  1063. List<PropertyInfo> plist;
  1064. v.get_property_list(&plist);
  1065. String options = "";
  1066. for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
  1067. options += "," + E->get().name;
  1068. }
  1069. property.hint = PROPERTY_HINT_ENUM;
  1070. property.hint_string = options;
  1071. property.type = Variant::STRING;
  1072. if (options == "")
  1073. property.usage = 0; //hide if type has no usable index
  1074. }
  1075. }
  1076. void VisualScriptPropertySet::_bind_methods() {
  1077. ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertySet::set_base_type);
  1078. ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertySet::get_base_type);
  1079. ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptPropertySet::set_base_script);
  1080. ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptPropertySet::get_base_script);
  1081. ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptPropertySet::set_basic_type);
  1082. ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptPropertySet::get_basic_type);
  1083. ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertySet::_set_type_cache);
  1084. ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertySet::_get_type_cache);
  1085. ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertySet::set_property);
  1086. ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertySet::get_property);
  1087. ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptPropertySet::set_call_mode);
  1088. ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptPropertySet::get_call_mode);
  1089. ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptPropertySet::set_base_path);
  1090. ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptPropertySet::get_base_path);
  1091. ClassDB::bind_method(D_METHOD("set_index", "index"), &VisualScriptPropertySet::set_index);
  1092. ClassDB::bind_method(D_METHOD("get_index"), &VisualScriptPropertySet::get_index);
  1093. ClassDB::bind_method(D_METHOD("set_assign_op", "assign_op"), &VisualScriptPropertySet::set_assign_op);
  1094. ClassDB::bind_method(D_METHOD("get_assign_op"), &VisualScriptPropertySet::get_assign_op);
  1095. String bt;
  1096. for (int i = 0; i < Variant::VARIANT_MAX; i++) {
  1097. if (i > 0)
  1098. bt += ",";
  1099. bt += Variant::get_type_name(Variant::Type(i));
  1100. }
  1101. List<String> script_extensions;
  1102. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  1103. ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
  1104. }
  1105. String script_ext_hint;
  1106. for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
  1107. if (script_ext_hint != String())
  1108. script_ext_hint += ",";
  1109. script_ext_hint += "*." + E->get();
  1110. }
  1111. ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode");
  1112. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
  1113. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
  1114. ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache");
  1115. ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type");
  1116. ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path");
  1117. ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property");
  1118. ADD_PROPERTY(PropertyInfo(Variant::STRING, "index"), "set_index", "get_index");
  1119. ADD_PROPERTY(PropertyInfo(Variant::INT, "assign_op", PROPERTY_HINT_ENUM, "Assign,Add,Sub,Mul,Div,Mod,ShiftLeft,ShiftRight,BitAnd,BitOr,Bitxor"), "set_assign_op", "get_assign_op");
  1120. BIND_ENUM_CONSTANT(CALL_MODE_SELF);
  1121. BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH);
  1122. BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE);
  1123. }
  1124. class VisualScriptNodeInstancePropertySet : public VisualScriptNodeInstance {
  1125. public:
  1126. VisualScriptPropertySet::CallMode call_mode;
  1127. NodePath node_path;
  1128. StringName property;
  1129. VisualScriptPropertySet *node;
  1130. VisualScriptInstance *instance;
  1131. VisualScriptPropertySet::AssignOp assign_op;
  1132. StringName index;
  1133. bool needs_get;
  1134. //virtual int get_working_memory_size() const { return 0; }
  1135. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  1136. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  1137. _FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) {
  1138. if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) {
  1139. source.set_named(index, p_argument, &valid);
  1140. } else {
  1141. Variant value;
  1142. if (index != StringName()) {
  1143. value = source.get_named(index, &valid);
  1144. } else {
  1145. value = source;
  1146. }
  1147. switch (assign_op) {
  1148. case VisualScriptPropertySet::ASSIGN_OP_NONE: {
  1149. //should never get here
  1150. } break;
  1151. case VisualScriptPropertySet::ASSIGN_OP_ADD: {
  1152. value = Variant::evaluate(Variant::OP_ADD, value, p_argument);
  1153. } break;
  1154. case VisualScriptPropertySet::ASSIGN_OP_SUB: {
  1155. value = Variant::evaluate(Variant::OP_SUBSTRACT, value, p_argument);
  1156. } break;
  1157. case VisualScriptPropertySet::ASSIGN_OP_MUL: {
  1158. value = Variant::evaluate(Variant::OP_MULTIPLY, value, p_argument);
  1159. } break;
  1160. case VisualScriptPropertySet::ASSIGN_OP_DIV: {
  1161. value = Variant::evaluate(Variant::OP_DIVIDE, value, p_argument);
  1162. } break;
  1163. case VisualScriptPropertySet::ASSIGN_OP_MOD: {
  1164. value = Variant::evaluate(Variant::OP_MODULE, value, p_argument);
  1165. } break;
  1166. case VisualScriptPropertySet::ASSIGN_OP_SHIFT_LEFT: {
  1167. value = Variant::evaluate(Variant::OP_SHIFT_LEFT, value, p_argument);
  1168. } break;
  1169. case VisualScriptPropertySet::ASSIGN_OP_SHIFT_RIGHT: {
  1170. value = Variant::evaluate(Variant::OP_SHIFT_RIGHT, value, p_argument);
  1171. } break;
  1172. case VisualScriptPropertySet::ASSIGN_OP_BIT_AND: {
  1173. value = Variant::evaluate(Variant::OP_BIT_AND, value, p_argument);
  1174. } break;
  1175. case VisualScriptPropertySet::ASSIGN_OP_BIT_OR: {
  1176. value = Variant::evaluate(Variant::OP_BIT_OR, value, p_argument);
  1177. } break;
  1178. case VisualScriptPropertySet::ASSIGN_OP_BIT_XOR: {
  1179. value = Variant::evaluate(Variant::OP_BIT_XOR, value, p_argument);
  1180. } break;
  1181. default: {}
  1182. }
  1183. if (index != StringName()) {
  1184. source.set_named(index, value, &valid);
  1185. } else {
  1186. source = value;
  1187. }
  1188. }
  1189. }
  1190. 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) {
  1191. switch (call_mode) {
  1192. case VisualScriptPropertySet::CALL_MODE_SELF: {
  1193. Object *object = instance->get_owner_ptr();
  1194. bool valid;
  1195. if (needs_get) {
  1196. Variant value = object->get(property, &valid);
  1197. _process_get(value, *p_inputs[0], valid);
  1198. object->set(property, value, &valid);
  1199. } else {
  1200. object->set(property, *p_inputs[0], &valid);
  1201. }
  1202. if (!valid) {
  1203. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1204. r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + object->get_class();
  1205. }
  1206. } break;
  1207. case VisualScriptPropertySet::CALL_MODE_NODE_PATH: {
  1208. Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
  1209. if (!node) {
  1210. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1211. r_error_str = "Base object is not a Node!";
  1212. return 0;
  1213. }
  1214. Node *another = node->get_node(node_path);
  1215. if (!another) {
  1216. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1217. r_error_str = "Path does not lead Node!";
  1218. return 0;
  1219. }
  1220. bool valid;
  1221. if (needs_get) {
  1222. Variant value = another->get(property, &valid);
  1223. _process_get(value, *p_inputs[0], valid);
  1224. another->set(property, value, &valid);
  1225. } else {
  1226. another->set(property, *p_inputs[0], &valid);
  1227. }
  1228. if (!valid) {
  1229. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1230. r_error_str = "Invalid set value '" + String(*p_inputs[0]) + "' on property '" + String(property) + "' of type " + another->get_class();
  1231. }
  1232. } break;
  1233. case VisualScriptPropertySet::CALL_MODE_INSTANCE:
  1234. case VisualScriptPropertySet::CALL_MODE_BASIC_TYPE: {
  1235. Variant v = *p_inputs[0];
  1236. bool valid;
  1237. if (needs_get) {
  1238. Variant value = v.get_named(property, &valid);
  1239. _process_get(value, *p_inputs[1], valid);
  1240. v.set_named(property, value, &valid);
  1241. } else {
  1242. v.set_named(property, *p_inputs[1], &valid);
  1243. }
  1244. if (!valid) {
  1245. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1246. r_error_str = "Invalid set value '" + String(*p_inputs[1]) + "' (" + Variant::get_type_name(p_inputs[1]->get_type()) + ") on property '" + String(property) + "' of type " + Variant::get_type_name(v.get_type());
  1247. }
  1248. *p_outputs[0] = v;
  1249. } break;
  1250. }
  1251. return 0;
  1252. }
  1253. };
  1254. VisualScriptNodeInstance *VisualScriptPropertySet::instance(VisualScriptInstance *p_instance) {
  1255. VisualScriptNodeInstancePropertySet *instance = memnew(VisualScriptNodeInstancePropertySet);
  1256. instance->node = this;
  1257. instance->instance = p_instance;
  1258. instance->property = property;
  1259. instance->call_mode = call_mode;
  1260. instance->node_path = base_path;
  1261. instance->assign_op = assign_op;
  1262. instance->index = index;
  1263. instance->needs_get = index != StringName() || assign_op != ASSIGN_OP_NONE;
  1264. return instance;
  1265. }
  1266. VisualScriptPropertySet::TypeGuess VisualScriptPropertySet::guess_output_type(TypeGuess *p_inputs, int p_output) const {
  1267. if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) {
  1268. return p_inputs[0];
  1269. }
  1270. return VisualScriptNode::guess_output_type(p_inputs, p_output);
  1271. }
  1272. VisualScriptPropertySet::VisualScriptPropertySet() {
  1273. assign_op = ASSIGN_OP_NONE;
  1274. call_mode = CALL_MODE_SELF;
  1275. base_type = "Object";
  1276. basic_type = Variant::NIL;
  1277. }
  1278. template <VisualScriptPropertySet::CallMode cmode>
  1279. static Ref<VisualScriptNode> create_property_set_node(const String &p_name) {
  1280. Ref<VisualScriptPropertySet> node;
  1281. node.instance();
  1282. node->set_call_mode(cmode);
  1283. return node;
  1284. }
  1285. //////////////////////////////////////////
  1286. ////////////////GET//////////////////////
  1287. //////////////////////////////////////////
  1288. int VisualScriptPropertyGet::get_output_sequence_port_count() const {
  1289. return 0; // (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
  1290. }
  1291. bool VisualScriptPropertyGet::has_input_sequence_port() const {
  1292. return false; //(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
  1293. }
  1294. void VisualScriptPropertyGet::_update_base_type() {
  1295. //cache it because this information may not be available on load
  1296. if (call_mode == CALL_MODE_NODE_PATH) {
  1297. Node *node = _get_base_node();
  1298. if (node) {
  1299. base_type = node->get_class();
  1300. }
  1301. } else if (call_mode == CALL_MODE_SELF) {
  1302. if (get_visual_script().is_valid()) {
  1303. base_type = get_visual_script()->get_instance_base_type();
  1304. }
  1305. }
  1306. }
  1307. Node *VisualScriptPropertyGet::_get_base_node() const {
  1308. #ifdef TOOLS_ENABLED
  1309. Ref<Script> script = get_visual_script();
  1310. if (!script.is_valid())
  1311. return NULL;
  1312. MainLoop *main_loop = OS::get_singleton()->get_main_loop();
  1313. SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
  1314. if (!scene_tree)
  1315. return NULL;
  1316. Node *edited_scene = scene_tree->get_edited_scene_root();
  1317. if (!edited_scene)
  1318. return NULL;
  1319. Node *script_node = _find_script_node(edited_scene, edited_scene, script);
  1320. if (!script_node)
  1321. return NULL;
  1322. if (!script_node->has_node(base_path))
  1323. return NULL;
  1324. Node *path_to = script_node->get_node(base_path);
  1325. return path_to;
  1326. #else
  1327. return NULL;
  1328. #endif
  1329. }
  1330. StringName VisualScriptPropertyGet::_get_base_type() const {
  1331. if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
  1332. return get_visual_script()->get_instance_base_type();
  1333. else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
  1334. Node *path = _get_base_node();
  1335. if (path)
  1336. return path->get_class();
  1337. }
  1338. return base_type;
  1339. }
  1340. int VisualScriptPropertyGet::get_input_value_port_count() const {
  1341. return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0;
  1342. }
  1343. int VisualScriptPropertyGet::get_output_value_port_count() const {
  1344. return 1;
  1345. }
  1346. String VisualScriptPropertyGet::get_output_sequence_port_text(int p_port) const {
  1347. return String();
  1348. }
  1349. PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const {
  1350. if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
  1351. if (p_idx == 0) {
  1352. PropertyInfo pi;
  1353. pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type);
  1354. pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower());
  1355. return pi;
  1356. } else {
  1357. p_idx--;
  1358. }
  1359. }
  1360. return PropertyInfo();
  1361. }
  1362. PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) const {
  1363. if (index != StringName()) {
  1364. Variant v;
  1365. Variant::CallError ce;
  1366. v = Variant::construct(type_cache, NULL, 0, ce);
  1367. Variant i = v.get(index);
  1368. return PropertyInfo(i.get_type(), "value." + String(index));
  1369. }
  1370. return PropertyInfo(type_cache, "value");
  1371. }
  1372. String VisualScriptPropertyGet::get_caption() const {
  1373. static const char *cname[4] = {
  1374. "SelfGet",
  1375. "NodeGet",
  1376. "InstanceGet",
  1377. "BasicGet"
  1378. };
  1379. return cname[call_mode];
  1380. }
  1381. String VisualScriptPropertyGet::get_text() const {
  1382. String prop;
  1383. if (call_mode == CALL_MODE_BASIC_TYPE)
  1384. prop = Variant::get_type_name(basic_type) + "." + property;
  1385. else if (call_mode == CALL_MODE_NODE_PATH)
  1386. prop = String(base_path) + ":" + property;
  1387. else if (call_mode == CALL_MODE_SELF)
  1388. prop = property;
  1389. else if (call_mode == CALL_MODE_INSTANCE)
  1390. prop = String(base_type) + ":" + property;
  1391. return prop;
  1392. }
  1393. void VisualScriptPropertyGet::set_base_type(const StringName &p_type) {
  1394. if (base_type == p_type)
  1395. return;
  1396. base_type = p_type;
  1397. _change_notify();
  1398. ports_changed_notify();
  1399. }
  1400. StringName VisualScriptPropertyGet::get_base_type() const {
  1401. return base_type;
  1402. }
  1403. void VisualScriptPropertyGet::set_base_script(const String &p_path) {
  1404. if (base_script == p_path)
  1405. return;
  1406. base_script = p_path;
  1407. _change_notify();
  1408. ports_changed_notify();
  1409. }
  1410. String VisualScriptPropertyGet::get_base_script() const {
  1411. return base_script;
  1412. }
  1413. void VisualScriptPropertyGet::_update_cache() {
  1414. if (call_mode == CALL_MODE_BASIC_TYPE) {
  1415. //not super efficient..
  1416. Variant v;
  1417. Variant::CallError ce;
  1418. v = Variant::construct(basic_type, NULL, 0, ce);
  1419. List<PropertyInfo> pinfo;
  1420. v.get_property_list(&pinfo);
  1421. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  1422. if (E->get().name == property) {
  1423. type_cache = E->get().type;
  1424. return;
  1425. }
  1426. }
  1427. } else {
  1428. StringName type;
  1429. Ref<Script> script;
  1430. Node *node = NULL;
  1431. if (call_mode == CALL_MODE_NODE_PATH) {
  1432. node = _get_base_node();
  1433. if (node) {
  1434. type = node->get_class();
  1435. base_type = type; //cache, too
  1436. script = node->get_script();
  1437. }
  1438. } else if (call_mode == CALL_MODE_SELF) {
  1439. if (get_visual_script().is_valid()) {
  1440. type = get_visual_script()->get_instance_base_type();
  1441. base_type = type; //cache, too
  1442. script = get_visual_script();
  1443. }
  1444. } else if (call_mode == CALL_MODE_INSTANCE) {
  1445. type = base_type;
  1446. if (base_script != String()) {
  1447. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  1448. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  1449. }
  1450. if (ResourceCache::has(base_script)) {
  1451. script = Ref<Resource>(ResourceCache::get(base_script));
  1452. } else {
  1453. return;
  1454. }
  1455. }
  1456. }
  1457. bool valid = false;
  1458. Variant::Type type_ret;
  1459. type_ret = ClassDB::get_property_type(base_type, property, &valid);
  1460. if (valid) {
  1461. type_cache = type_ret;
  1462. return; //all dandy
  1463. }
  1464. if (node) {
  1465. Variant prop = node->get(property, &valid);
  1466. if (valid) {
  1467. type_cache = prop.get_type();
  1468. return; //all dandy again
  1469. }
  1470. }
  1471. if (script.is_valid()) {
  1472. type_ret = script->get_static_property_type(property, &valid);
  1473. if (valid) {
  1474. type_cache = type_ret;
  1475. return; //all dandy
  1476. }
  1477. }
  1478. }
  1479. }
  1480. void VisualScriptPropertyGet::set_property(const StringName &p_type) {
  1481. if (property == p_type)
  1482. return;
  1483. property = p_type;
  1484. _update_cache();
  1485. _change_notify();
  1486. ports_changed_notify();
  1487. }
  1488. StringName VisualScriptPropertyGet::get_property() const {
  1489. return property;
  1490. }
  1491. void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) {
  1492. if (base_path == p_type)
  1493. return;
  1494. base_path = p_type;
  1495. _change_notify();
  1496. _update_base_type();
  1497. ports_changed_notify();
  1498. }
  1499. NodePath VisualScriptPropertyGet::get_base_path() const {
  1500. return base_path;
  1501. }
  1502. void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) {
  1503. if (call_mode == p_mode)
  1504. return;
  1505. call_mode = p_mode;
  1506. _change_notify();
  1507. _update_base_type();
  1508. ports_changed_notify();
  1509. }
  1510. VisualScriptPropertyGet::CallMode VisualScriptPropertyGet::get_call_mode() const {
  1511. return call_mode;
  1512. }
  1513. void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) {
  1514. if (basic_type == p_type)
  1515. return;
  1516. basic_type = p_type;
  1517. _change_notify();
  1518. ports_changed_notify();
  1519. }
  1520. Variant::Type VisualScriptPropertyGet::get_basic_type() const {
  1521. return basic_type;
  1522. }
  1523. void VisualScriptPropertyGet::_set_type_cache(Variant::Type p_type) {
  1524. type_cache = p_type;
  1525. }
  1526. Variant::Type VisualScriptPropertyGet::_get_type_cache() const {
  1527. return type_cache;
  1528. }
  1529. void VisualScriptPropertyGet::set_index(const StringName &p_type) {
  1530. if (index == p_type)
  1531. return;
  1532. index = p_type;
  1533. _update_cache();
  1534. _change_notify();
  1535. ports_changed_notify();
  1536. }
  1537. StringName VisualScriptPropertyGet::get_index() const {
  1538. return index;
  1539. }
  1540. void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
  1541. if (property.name == "base_type") {
  1542. if (call_mode != CALL_MODE_INSTANCE) {
  1543. property.usage = PROPERTY_USAGE_NOEDITOR;
  1544. }
  1545. }
  1546. if (property.name == "base_script") {
  1547. if (call_mode != CALL_MODE_INSTANCE) {
  1548. property.usage = 0;
  1549. }
  1550. }
  1551. if (property.name == "basic_type") {
  1552. if (call_mode != CALL_MODE_BASIC_TYPE) {
  1553. property.usage = 0;
  1554. }
  1555. }
  1556. if (property.name == "node_path") {
  1557. if (call_mode != CALL_MODE_NODE_PATH) {
  1558. property.usage = 0;
  1559. } else {
  1560. Node *bnode = _get_base_node();
  1561. if (bnode) {
  1562. property.hint_string = bnode->get_path(); //convert to loong string
  1563. } else {
  1564. }
  1565. }
  1566. }
  1567. if (property.name == "property") {
  1568. if (call_mode == CALL_MODE_BASIC_TYPE) {
  1569. property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
  1570. property.hint_string = Variant::get_type_name(basic_type);
  1571. } else if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
  1572. property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
  1573. property.hint_string = itos(get_visual_script()->get_instance_id());
  1574. } else if (call_mode == CALL_MODE_INSTANCE) {
  1575. property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
  1576. property.hint_string = base_type;
  1577. if (base_script != String()) {
  1578. if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
  1579. ScriptServer::edit_request_func(base_script); //make sure it's loaded
  1580. }
  1581. if (ResourceCache::has(base_script)) {
  1582. Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
  1583. if (script.is_valid()) {
  1584. property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
  1585. property.hint_string = itos(script->get_instance_id());
  1586. }
  1587. }
  1588. }
  1589. } else if (call_mode == CALL_MODE_NODE_PATH) {
  1590. Node *node = _get_base_node();
  1591. if (node) {
  1592. property.hint = PROPERTY_HINT_PROPERTY_OF_INSTANCE;
  1593. property.hint_string = itos(node->get_instance_id());
  1594. } else {
  1595. property.hint = PROPERTY_HINT_PROPERTY_OF_BASE_TYPE;
  1596. property.hint_string = get_base_type();
  1597. }
  1598. }
  1599. }
  1600. if (property.name == "index") {
  1601. Variant::CallError ce;
  1602. Variant v = Variant::construct(type_cache, NULL, 0, ce);
  1603. List<PropertyInfo> plist;
  1604. v.get_property_list(&plist);
  1605. String options = "";
  1606. for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
  1607. options += "," + E->get().name;
  1608. }
  1609. property.hint = PROPERTY_HINT_ENUM;
  1610. property.hint_string = options;
  1611. property.type = Variant::STRING;
  1612. if (options == "")
  1613. property.usage = 0; //hide if type has no usable index
  1614. }
  1615. }
  1616. void VisualScriptPropertyGet::_bind_methods() {
  1617. ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertyGet::set_base_type);
  1618. ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertyGet::get_base_type);
  1619. ClassDB::bind_method(D_METHOD("set_base_script", "base_script"), &VisualScriptPropertyGet::set_base_script);
  1620. ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptPropertyGet::get_base_script);
  1621. ClassDB::bind_method(D_METHOD("set_basic_type", "basic_type"), &VisualScriptPropertyGet::set_basic_type);
  1622. ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptPropertyGet::get_basic_type);
  1623. ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertyGet::_set_type_cache);
  1624. ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertyGet::_get_type_cache);
  1625. ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertyGet::set_property);
  1626. ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertyGet::get_property);
  1627. ClassDB::bind_method(D_METHOD("set_call_mode", "mode"), &VisualScriptPropertyGet::set_call_mode);
  1628. ClassDB::bind_method(D_METHOD("get_call_mode"), &VisualScriptPropertyGet::get_call_mode);
  1629. ClassDB::bind_method(D_METHOD("set_base_path", "base_path"), &VisualScriptPropertyGet::set_base_path);
  1630. ClassDB::bind_method(D_METHOD("get_base_path"), &VisualScriptPropertyGet::get_base_path);
  1631. ClassDB::bind_method(D_METHOD("set_index", "index"), &VisualScriptPropertyGet::set_index);
  1632. ClassDB::bind_method(D_METHOD("get_index"), &VisualScriptPropertyGet::get_index);
  1633. String bt;
  1634. for (int i = 0; i < Variant::VARIANT_MAX; i++) {
  1635. if (i > 0)
  1636. bt += ",";
  1637. bt += Variant::get_type_name(Variant::Type(i));
  1638. }
  1639. List<String> script_extensions;
  1640. for (int i = 0; i < ScriptServer::get_language_count(); i++) {
  1641. ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
  1642. }
  1643. String script_ext_hint;
  1644. for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
  1645. if (script_ext_hint != String())
  1646. script_ext_hint += ",";
  1647. script_ext_hint += "." + E->get();
  1648. }
  1649. ADD_PROPERTY(PropertyInfo(Variant::INT, "set_mode", PROPERTY_HINT_ENUM, "Self,Node Path,Instance,Basic Type"), "set_call_mode", "get_call_mode");
  1650. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
  1651. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
  1652. ADD_PROPERTY(PropertyInfo(Variant::INT, "type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache");
  1653. ADD_PROPERTY(PropertyInfo(Variant::INT, "basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type");
  1654. ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path");
  1655. ADD_PROPERTY(PropertyInfo(Variant::STRING, "property"), "set_property", "get_property");
  1656. ADD_PROPERTY(PropertyInfo(Variant::STRING, "index", PROPERTY_HINT_ENUM), "set_index", "get_index");
  1657. BIND_ENUM_CONSTANT(CALL_MODE_SELF);
  1658. BIND_ENUM_CONSTANT(CALL_MODE_NODE_PATH);
  1659. BIND_ENUM_CONSTANT(CALL_MODE_INSTANCE);
  1660. }
  1661. class VisualScriptNodeInstancePropertyGet : public VisualScriptNodeInstance {
  1662. public:
  1663. VisualScriptPropertyGet::CallMode call_mode;
  1664. NodePath node_path;
  1665. StringName property;
  1666. StringName index;
  1667. VisualScriptPropertyGet *node;
  1668. VisualScriptInstance *instance;
  1669. 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) {
  1670. switch (call_mode) {
  1671. case VisualScriptPropertyGet::CALL_MODE_SELF: {
  1672. Object *object = instance->get_owner_ptr();
  1673. bool valid;
  1674. *p_outputs[0] = object->get(property, &valid);
  1675. if (index != StringName()) {
  1676. *p_outputs[0] = p_outputs[0]->get_named(index);
  1677. }
  1678. if (!valid) {
  1679. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1680. r_error_str = RTR("Invalid index property name.");
  1681. return 0;
  1682. }
  1683. } break;
  1684. case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: {
  1685. Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
  1686. if (!node) {
  1687. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1688. r_error_str = RTR("Base object is not a Node!");
  1689. return 0;
  1690. }
  1691. Node *another = node->get_node(node_path);
  1692. if (!another) {
  1693. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1694. r_error_str = RTR("Path does not lead Node!");
  1695. return 0;
  1696. }
  1697. bool valid;
  1698. *p_outputs[0] = another->get(property, &valid);
  1699. if (index != StringName()) {
  1700. *p_outputs[0] = p_outputs[0]->get_named(index);
  1701. }
  1702. if (!valid) {
  1703. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1704. r_error_str = vformat(RTR("Invalid index property name '%s' in node %s."), String(property), another->get_name());
  1705. return 0;
  1706. }
  1707. } break;
  1708. default: {
  1709. bool valid;
  1710. Variant v = *p_inputs[0];
  1711. *p_outputs[0] = v.get(property, &valid);
  1712. if (index != StringName()) {
  1713. *p_outputs[0] = p_outputs[0]->get_named(index);
  1714. }
  1715. if (!valid) {
  1716. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1717. r_error_str = RTR("Invalid index property name.");
  1718. }
  1719. };
  1720. }
  1721. return 0;
  1722. }
  1723. };
  1724. VisualScriptNodeInstance *VisualScriptPropertyGet::instance(VisualScriptInstance *p_instance) {
  1725. VisualScriptNodeInstancePropertyGet *instance = memnew(VisualScriptNodeInstancePropertyGet);
  1726. instance->node = this;
  1727. instance->instance = p_instance;
  1728. instance->property = property;
  1729. instance->call_mode = call_mode;
  1730. instance->node_path = base_path;
  1731. instance->index = index;
  1732. return instance;
  1733. }
  1734. VisualScriptPropertyGet::VisualScriptPropertyGet() {
  1735. call_mode = CALL_MODE_SELF;
  1736. base_type = "Object";
  1737. basic_type = Variant::NIL;
  1738. type_cache = Variant::NIL;
  1739. }
  1740. template <VisualScriptPropertyGet::CallMode cmode>
  1741. static Ref<VisualScriptNode> create_property_get_node(const String &p_name) {
  1742. Ref<VisualScriptPropertyGet> node;
  1743. node.instance();
  1744. node->set_call_mode(cmode);
  1745. return node;
  1746. }
  1747. //////////////////////////////////////////
  1748. ////////////////EMIT//////////////////////
  1749. //////////////////////////////////////////
  1750. int VisualScriptEmitSignal::get_output_sequence_port_count() const {
  1751. return 1;
  1752. }
  1753. bool VisualScriptEmitSignal::has_input_sequence_port() const {
  1754. return true;
  1755. }
  1756. int VisualScriptEmitSignal::get_input_value_port_count() const {
  1757. Ref<VisualScript> vs = get_visual_script();
  1758. if (vs.is_valid()) {
  1759. if (!vs->has_custom_signal(name))
  1760. return 0;
  1761. return vs->custom_signal_get_argument_count(name);
  1762. }
  1763. return 0;
  1764. }
  1765. int VisualScriptEmitSignal::get_output_value_port_count() const {
  1766. return 0;
  1767. }
  1768. String VisualScriptEmitSignal::get_output_sequence_port_text(int p_port) const {
  1769. return String();
  1770. }
  1771. PropertyInfo VisualScriptEmitSignal::get_input_value_port_info(int p_idx) const {
  1772. Ref<VisualScript> vs = get_visual_script();
  1773. if (vs.is_valid()) {
  1774. if (!vs->has_custom_signal(name))
  1775. return PropertyInfo();
  1776. return PropertyInfo(vs->custom_signal_get_argument_type(name, p_idx), vs->custom_signal_get_argument_name(name, p_idx));
  1777. }
  1778. return PropertyInfo();
  1779. }
  1780. PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const {
  1781. return PropertyInfo();
  1782. }
  1783. String VisualScriptEmitSignal::get_caption() const {
  1784. return "EmitSignal";
  1785. }
  1786. String VisualScriptEmitSignal::get_text() const {
  1787. return "emit " + String(name);
  1788. }
  1789. void VisualScriptEmitSignal::set_signal(const StringName &p_type) {
  1790. if (name == p_type)
  1791. return;
  1792. name = p_type;
  1793. _change_notify();
  1794. ports_changed_notify();
  1795. }
  1796. StringName VisualScriptEmitSignal::get_signal() const {
  1797. return name;
  1798. }
  1799. void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const {
  1800. if (property.name == "signal") {
  1801. property.hint = PROPERTY_HINT_ENUM;
  1802. List<StringName> sigs;
  1803. Ref<VisualScript> vs = get_visual_script();
  1804. if (vs.is_valid()) {
  1805. vs->get_custom_signal_list(&sigs);
  1806. }
  1807. String ml;
  1808. for (List<StringName>::Element *E = sigs.front(); E; E = E->next()) {
  1809. if (ml != String())
  1810. ml += ",";
  1811. ml += E->get();
  1812. }
  1813. property.hint_string = ml;
  1814. }
  1815. }
  1816. void VisualScriptEmitSignal::_bind_methods() {
  1817. ClassDB::bind_method(D_METHOD("set_signal", "name"), &VisualScriptEmitSignal::set_signal);
  1818. ClassDB::bind_method(D_METHOD("get_signal"), &VisualScriptEmitSignal::get_signal);
  1819. ADD_PROPERTY(PropertyInfo(Variant::STRING, "signal"), "set_signal", "get_signal");
  1820. }
  1821. class VisualScriptNodeInstanceEmitSignal : public VisualScriptNodeInstance {
  1822. public:
  1823. VisualScriptEmitSignal *node;
  1824. VisualScriptInstance *instance;
  1825. int argcount;
  1826. StringName name;
  1827. //virtual int get_working_memory_size() const { return 0; }
  1828. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  1829. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  1830. 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) {
  1831. Object *obj = instance->get_owner_ptr();
  1832. obj->emit_signal(name, p_inputs, argcount);
  1833. return 0;
  1834. }
  1835. };
  1836. VisualScriptNodeInstance *VisualScriptEmitSignal::instance(VisualScriptInstance *p_instance) {
  1837. VisualScriptNodeInstanceEmitSignal *instance = memnew(VisualScriptNodeInstanceEmitSignal);
  1838. instance->node = this;
  1839. instance->instance = p_instance;
  1840. instance->name = name;
  1841. instance->argcount = get_input_value_port_count();
  1842. return instance;
  1843. }
  1844. VisualScriptEmitSignal::VisualScriptEmitSignal() {
  1845. }
  1846. static Ref<VisualScriptNode> create_basic_type_call_node(const String &p_name) {
  1847. Vector<String> path = p_name.split("/");
  1848. ERR_FAIL_COND_V(path.size() < 4, Ref<VisualScriptNode>());
  1849. String base_type = path[2];
  1850. String method = path[3];
  1851. Ref<VisualScriptFunctionCall> node;
  1852. node.instance();
  1853. Variant::Type type = Variant::VARIANT_MAX;
  1854. for (int i = 0; i < Variant::VARIANT_MAX; i++) {
  1855. if (Variant::get_type_name(Variant::Type(i)) == base_type) {
  1856. type = Variant::Type(i);
  1857. break;
  1858. }
  1859. }
  1860. ERR_FAIL_COND_V(type == Variant::VARIANT_MAX, Ref<VisualScriptNode>());
  1861. node->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE);
  1862. node->set_basic_type(type);
  1863. node->set_function(method);
  1864. return node;
  1865. }
  1866. void register_visual_script_func_nodes() {
  1867. VisualScriptLanguage::singleton->add_register_func("functions/call", create_node_generic<VisualScriptFunctionCall>);
  1868. VisualScriptLanguage::singleton->add_register_func("functions/set", create_node_generic<VisualScriptPropertySet>);
  1869. VisualScriptLanguage::singleton->add_register_func("functions/get", create_node_generic<VisualScriptPropertyGet>);
  1870. //VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_self",create_script_call_node<VisualScriptScriptCall::CALL_MODE_SELF>);
  1871. //VisualScriptLanguage::singleton->add_register_func("functions/call_script/call_node",create_script_call_node<VisualScriptScriptCall::CALL_MODE_NODE_PATH>);
  1872. VisualScriptLanguage::singleton->add_register_func("functions/emit_signal", create_node_generic<VisualScriptEmitSignal>);
  1873. for (int i = 0; i < Variant::VARIANT_MAX; i++) {
  1874. Variant::Type t = Variant::Type(i);
  1875. String type_name = Variant::get_type_name(t);
  1876. Variant::CallError ce;
  1877. Variant vt = Variant::construct(t, NULL, 0, ce);
  1878. List<MethodInfo> ml;
  1879. vt.get_method_list(&ml);
  1880. for (List<MethodInfo>::Element *E = ml.front(); E; E = E->next()) {
  1881. VisualScriptLanguage::singleton->add_register_func("functions/by_type/" + type_name + "/" + E->get().name, create_basic_type_call_node);
  1882. }
  1883. }
  1884. }