visual_script_func_nodes.cpp 62 KB

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