visual_script_flow_control.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853
  1. /*************************************************************************/
  2. /* visual_script_flow_control.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_flow_control.h"
  31. #include "global_config.h"
  32. #include "io/resource_loader.h"
  33. #include "os/keyboard.h"
  34. //////////////////////////////////////////
  35. ////////////////RETURN////////////////////
  36. //////////////////////////////////////////
  37. int VisualScriptReturn::get_output_sequence_port_count() const {
  38. return 0;
  39. }
  40. bool VisualScriptReturn::has_input_sequence_port() const {
  41. return true;
  42. }
  43. int VisualScriptReturn::get_input_value_port_count() const {
  44. return with_value ? 1 : 0;
  45. }
  46. int VisualScriptReturn::get_output_value_port_count() const {
  47. return 0;
  48. }
  49. String VisualScriptReturn::get_output_sequence_port_text(int p_port) const {
  50. return String();
  51. }
  52. PropertyInfo VisualScriptReturn::get_input_value_port_info(int p_idx) const {
  53. PropertyInfo pinfo;
  54. pinfo.name = "result";
  55. pinfo.type = type;
  56. return pinfo;
  57. }
  58. PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const {
  59. return PropertyInfo();
  60. }
  61. String VisualScriptReturn::get_caption() const {
  62. return "Return";
  63. }
  64. String VisualScriptReturn::get_text() const {
  65. return get_name();
  66. }
  67. void VisualScriptReturn::set_return_type(Variant::Type p_type) {
  68. if (type == p_type)
  69. return;
  70. type = p_type;
  71. ports_changed_notify();
  72. }
  73. Variant::Type VisualScriptReturn::get_return_type() const {
  74. return type;
  75. }
  76. void VisualScriptReturn::set_enable_return_value(bool p_enable) {
  77. if (with_value == p_enable)
  78. return;
  79. with_value = p_enable;
  80. ports_changed_notify();
  81. }
  82. bool VisualScriptReturn::is_return_value_enabled() const {
  83. return with_value;
  84. }
  85. void VisualScriptReturn::_bind_methods() {
  86. ClassDB::bind_method(D_METHOD("set_return_type", "type"), &VisualScriptReturn::set_return_type);
  87. ClassDB::bind_method(D_METHOD("get_return_type"), &VisualScriptReturn::get_return_type);
  88. ClassDB::bind_method(D_METHOD("set_enable_return_value", "enable"), &VisualScriptReturn::set_enable_return_value);
  89. ClassDB::bind_method(D_METHOD("is_return_value_enabled"), &VisualScriptReturn::is_return_value_enabled);
  90. String argt = "Any";
  91. for (int i = 1; i < Variant::VARIANT_MAX; i++) {
  92. argt += "," + Variant::get_type_name(Variant::Type(i));
  93. }
  94. ADD_PROPERTY(PropertyInfo(Variant::BOOL, "return_enabled"), "set_enable_return_value", "is_return_value_enabled");
  95. ADD_PROPERTY(PropertyInfo(Variant::INT, "return_type", PROPERTY_HINT_ENUM, argt), "set_return_type", "get_return_type");
  96. }
  97. class VisualScriptNodeInstanceReturn : public VisualScriptNodeInstance {
  98. public:
  99. VisualScriptReturn *node;
  100. VisualScriptInstance *instance;
  101. bool with_value;
  102. virtual int get_working_memory_size() const { return 1; }
  103. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  104. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  105. 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) {
  106. if (with_value) {
  107. *p_working_mem = *p_inputs[0];
  108. } else {
  109. *p_working_mem = Variant();
  110. }
  111. return 0;
  112. }
  113. };
  114. VisualScriptNodeInstance *VisualScriptReturn::instance(VisualScriptInstance *p_instance) {
  115. VisualScriptNodeInstanceReturn *instance = memnew(VisualScriptNodeInstanceReturn);
  116. instance->node = this;
  117. instance->instance = p_instance;
  118. instance->with_value = with_value;
  119. return instance;
  120. }
  121. VisualScriptReturn::VisualScriptReturn() {
  122. with_value = false;
  123. type = Variant::NIL;
  124. }
  125. template <bool with_value>
  126. static Ref<VisualScriptNode> create_return_node(const String &p_name) {
  127. Ref<VisualScriptReturn> node;
  128. node.instance();
  129. node->set_enable_return_value(with_value);
  130. return node;
  131. }
  132. //////////////////////////////////////////
  133. ////////////////CONDITION/////////////////
  134. //////////////////////////////////////////
  135. int VisualScriptCondition::get_output_sequence_port_count() const {
  136. return 3;
  137. }
  138. bool VisualScriptCondition::has_input_sequence_port() const {
  139. return true;
  140. }
  141. int VisualScriptCondition::get_input_value_port_count() const {
  142. return 1;
  143. }
  144. int VisualScriptCondition::get_output_value_port_count() const {
  145. return 0;
  146. }
  147. String VisualScriptCondition::get_output_sequence_port_text(int p_port) const {
  148. if (p_port == 0)
  149. return "true";
  150. else if (p_port == 1)
  151. return "false";
  152. else
  153. return "done";
  154. }
  155. PropertyInfo VisualScriptCondition::get_input_value_port_info(int p_idx) const {
  156. PropertyInfo pinfo;
  157. pinfo.name = "cond";
  158. pinfo.type = Variant::BOOL;
  159. return pinfo;
  160. }
  161. PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const {
  162. return PropertyInfo();
  163. }
  164. String VisualScriptCondition::get_caption() const {
  165. return "Condition";
  166. }
  167. String VisualScriptCondition::get_text() const {
  168. return "if (cond) is: ";
  169. }
  170. void VisualScriptCondition::_bind_methods() {
  171. }
  172. class VisualScriptNodeInstanceCondition : public VisualScriptNodeInstance {
  173. public:
  174. VisualScriptCondition *node;
  175. VisualScriptInstance *instance;
  176. //virtual int get_working_memory_size() const { return 1; }
  177. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  178. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  179. 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) {
  180. if (p_start_mode == START_MODE_CONTINUE_SEQUENCE)
  181. return 2;
  182. else if (p_inputs[0]->operator bool())
  183. return 0 | STEP_FLAG_PUSH_STACK_BIT;
  184. else
  185. return 1 | STEP_FLAG_PUSH_STACK_BIT;
  186. }
  187. };
  188. VisualScriptNodeInstance *VisualScriptCondition::instance(VisualScriptInstance *p_instance) {
  189. VisualScriptNodeInstanceCondition *instance = memnew(VisualScriptNodeInstanceCondition);
  190. instance->node = this;
  191. instance->instance = p_instance;
  192. return instance;
  193. }
  194. VisualScriptCondition::VisualScriptCondition() {
  195. }
  196. //////////////////////////////////////////
  197. ////////////////WHILE/////////////////
  198. //////////////////////////////////////////
  199. int VisualScriptWhile::get_output_sequence_port_count() const {
  200. return 2;
  201. }
  202. bool VisualScriptWhile::has_input_sequence_port() const {
  203. return true;
  204. }
  205. int VisualScriptWhile::get_input_value_port_count() const {
  206. return 1;
  207. }
  208. int VisualScriptWhile::get_output_value_port_count() const {
  209. return 0;
  210. }
  211. String VisualScriptWhile::get_output_sequence_port_text(int p_port) const {
  212. if (p_port == 0)
  213. return "repeat";
  214. else
  215. return "exit";
  216. }
  217. PropertyInfo VisualScriptWhile::get_input_value_port_info(int p_idx) const {
  218. PropertyInfo pinfo;
  219. pinfo.name = "cond";
  220. pinfo.type = Variant::BOOL;
  221. return pinfo;
  222. }
  223. PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const {
  224. return PropertyInfo();
  225. }
  226. String VisualScriptWhile::get_caption() const {
  227. return "While";
  228. }
  229. String VisualScriptWhile::get_text() const {
  230. return "while (cond): ";
  231. }
  232. void VisualScriptWhile::_bind_methods() {
  233. }
  234. class VisualScriptNodeInstanceWhile : public VisualScriptNodeInstance {
  235. public:
  236. VisualScriptWhile *node;
  237. VisualScriptInstance *instance;
  238. //virtual int get_working_memory_size() const { return 1; }
  239. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  240. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  241. 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) {
  242. bool keep_going = p_inputs[0]->operator bool();
  243. if (keep_going)
  244. return 0 | STEP_FLAG_PUSH_STACK_BIT;
  245. else
  246. return 1;
  247. }
  248. };
  249. VisualScriptNodeInstance *VisualScriptWhile::instance(VisualScriptInstance *p_instance) {
  250. VisualScriptNodeInstanceWhile *instance = memnew(VisualScriptNodeInstanceWhile);
  251. instance->node = this;
  252. instance->instance = p_instance;
  253. return instance;
  254. }
  255. VisualScriptWhile::VisualScriptWhile() {
  256. }
  257. //////////////////////////////////////////
  258. ////////////////ITERATOR/////////////////
  259. //////////////////////////////////////////
  260. int VisualScriptIterator::get_output_sequence_port_count() const {
  261. return 2;
  262. }
  263. bool VisualScriptIterator::has_input_sequence_port() const {
  264. return true;
  265. }
  266. int VisualScriptIterator::get_input_value_port_count() const {
  267. return 1;
  268. }
  269. int VisualScriptIterator::get_output_value_port_count() const {
  270. return 1;
  271. }
  272. String VisualScriptIterator::get_output_sequence_port_text(int p_port) const {
  273. if (p_port == 0)
  274. return "each";
  275. else
  276. return "exit";
  277. }
  278. PropertyInfo VisualScriptIterator::get_input_value_port_info(int p_idx) const {
  279. PropertyInfo pinfo;
  280. pinfo.name = "input";
  281. pinfo.type = Variant::NIL;
  282. return pinfo;
  283. }
  284. PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const {
  285. PropertyInfo pinfo;
  286. pinfo.name = "elem";
  287. pinfo.type = Variant::NIL;
  288. return pinfo;
  289. }
  290. String VisualScriptIterator::get_caption() const {
  291. return "Iterator";
  292. }
  293. String VisualScriptIterator::get_text() const {
  294. return "for (elem) in (input): ";
  295. }
  296. void VisualScriptIterator::_bind_methods() {
  297. }
  298. class VisualScriptNodeInstanceIterator : public VisualScriptNodeInstance {
  299. public:
  300. VisualScriptIterator *node;
  301. VisualScriptInstance *instance;
  302. virtual int get_working_memory_size() const { return 2; }
  303. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  304. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  305. 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) {
  306. if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
  307. p_working_mem[0] = *p_inputs[0];
  308. bool valid;
  309. bool can_iter = p_inputs[0]->iter_init(p_working_mem[1], valid);
  310. if (!valid) {
  311. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  312. r_error_str = RTR("Input type not iterable: ") + Variant::get_type_name(p_inputs[0]->get_type());
  313. return 0;
  314. }
  315. if (!can_iter)
  316. return 1; //nothing to iterate
  317. *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
  318. if (!valid) {
  319. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  320. r_error_str = RTR("Iterator became invalid");
  321. return 0;
  322. }
  323. } else { //continue sequence
  324. bool valid;
  325. bool can_iter = p_working_mem[0].iter_next(p_working_mem[1], valid);
  326. if (!valid) {
  327. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  328. r_error_str = RTR("Iterator became invalid: ") + Variant::get_type_name(p_inputs[0]->get_type());
  329. return 0;
  330. }
  331. if (!can_iter)
  332. return 1; //nothing to iterate
  333. *p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
  334. if (!valid) {
  335. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  336. r_error_str = RTR("Iterator became invalid");
  337. return 0;
  338. }
  339. }
  340. return 0 | STEP_FLAG_PUSH_STACK_BIT; //go around
  341. }
  342. };
  343. VisualScriptNodeInstance *VisualScriptIterator::instance(VisualScriptInstance *p_instance) {
  344. VisualScriptNodeInstanceIterator *instance = memnew(VisualScriptNodeInstanceIterator);
  345. instance->node = this;
  346. instance->instance = p_instance;
  347. return instance;
  348. }
  349. VisualScriptIterator::VisualScriptIterator() {
  350. }
  351. //////////////////////////////////////////
  352. ////////////////SEQUENCE/////////////////
  353. //////////////////////////////////////////
  354. int VisualScriptSequence::get_output_sequence_port_count() const {
  355. return steps;
  356. }
  357. bool VisualScriptSequence::has_input_sequence_port() const {
  358. return true;
  359. }
  360. int VisualScriptSequence::get_input_value_port_count() const {
  361. return 0;
  362. }
  363. int VisualScriptSequence::get_output_value_port_count() const {
  364. return 1;
  365. }
  366. String VisualScriptSequence::get_output_sequence_port_text(int p_port) const {
  367. return itos(p_port + 1);
  368. }
  369. PropertyInfo VisualScriptSequence::get_input_value_port_info(int p_idx) const {
  370. return PropertyInfo();
  371. }
  372. PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const {
  373. return PropertyInfo(Variant::INT, "current");
  374. }
  375. String VisualScriptSequence::get_caption() const {
  376. return "Sequence";
  377. }
  378. String VisualScriptSequence::get_text() const {
  379. return "in order: ";
  380. }
  381. void VisualScriptSequence::set_steps(int p_steps) {
  382. ERR_FAIL_COND(p_steps < 1);
  383. if (steps == p_steps)
  384. return;
  385. steps = p_steps;
  386. ports_changed_notify();
  387. }
  388. int VisualScriptSequence::get_steps() const {
  389. return steps;
  390. }
  391. void VisualScriptSequence::_bind_methods() {
  392. ClassDB::bind_method(D_METHOD("set_steps", "steps"), &VisualScriptSequence::set_steps);
  393. ClassDB::bind_method(D_METHOD("get_steps"), &VisualScriptSequence::get_steps);
  394. ADD_PROPERTY(PropertyInfo(Variant::INT, "steps", PROPERTY_HINT_RANGE, "1,64,1"), "set_steps", "get_steps");
  395. }
  396. class VisualScriptNodeInstanceSequence : public VisualScriptNodeInstance {
  397. public:
  398. VisualScriptSequence *node;
  399. VisualScriptInstance *instance;
  400. int steps;
  401. virtual int get_working_memory_size() const { return 1; }
  402. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  403. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
  404. 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) {
  405. if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
  406. p_working_mem[0] = 0;
  407. }
  408. int step = p_working_mem[0];
  409. *p_outputs[0] = step;
  410. if (step + 1 == steps)
  411. return step;
  412. else {
  413. p_working_mem[0] = step + 1;
  414. return step | STEP_FLAG_PUSH_STACK_BIT;
  415. }
  416. }
  417. };
  418. VisualScriptNodeInstance *VisualScriptSequence::instance(VisualScriptInstance *p_instance) {
  419. VisualScriptNodeInstanceSequence *instance = memnew(VisualScriptNodeInstanceSequence);
  420. instance->node = this;
  421. instance->instance = p_instance;
  422. instance->steps = steps;
  423. return instance;
  424. }
  425. VisualScriptSequence::VisualScriptSequence() {
  426. steps = 1;
  427. }
  428. //////////////////////////////////////////
  429. ////////////////EVENT TYPE FILTER///////////
  430. //////////////////////////////////////////
  431. int VisualScriptSwitch::get_output_sequence_port_count() const {
  432. return case_values.size() + 1;
  433. }
  434. bool VisualScriptSwitch::has_input_sequence_port() const {
  435. return true;
  436. }
  437. int VisualScriptSwitch::get_input_value_port_count() const {
  438. return case_values.size() + 1;
  439. }
  440. int VisualScriptSwitch::get_output_value_port_count() const {
  441. return 0;
  442. }
  443. String VisualScriptSwitch::get_output_sequence_port_text(int p_port) const {
  444. if (p_port == case_values.size())
  445. return "done";
  446. return String();
  447. }
  448. PropertyInfo VisualScriptSwitch::get_input_value_port_info(int p_idx) const {
  449. if (p_idx < case_values.size()) {
  450. return PropertyInfo(case_values[p_idx].type, " =");
  451. } else
  452. return PropertyInfo(Variant::NIL, "input");
  453. }
  454. PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const {
  455. return PropertyInfo();
  456. }
  457. String VisualScriptSwitch::get_caption() const {
  458. return "Switch";
  459. }
  460. String VisualScriptSwitch::get_text() const {
  461. return "'input' is:";
  462. }
  463. class VisualScriptNodeInstanceSwitch : public VisualScriptNodeInstance {
  464. public:
  465. VisualScriptInstance *instance;
  466. int case_count;
  467. //virtual int get_working_memory_size() const { return 0; }
  468. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  469. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
  470. 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) {
  471. if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) {
  472. return case_count; //exit
  473. }
  474. for (int i = 0; i < case_count; i++) {
  475. if (*p_inputs[i] == *p_inputs[case_count]) {
  476. return i | STEP_FLAG_PUSH_STACK_BIT;
  477. }
  478. }
  479. return case_count;
  480. }
  481. };
  482. VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_instance) {
  483. VisualScriptNodeInstanceSwitch *instance = memnew(VisualScriptNodeInstanceSwitch);
  484. instance->instance = p_instance;
  485. instance->case_count = case_values.size();
  486. return instance;
  487. }
  488. bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) {
  489. if (String(p_name) == "case_count") {
  490. case_values.resize(p_value);
  491. _change_notify();
  492. ports_changed_notify();
  493. return true;
  494. }
  495. if (String(p_name).begins_with("case/")) {
  496. int idx = String(p_name).get_slice("/", 1).to_int();
  497. ERR_FAIL_INDEX_V(idx, case_values.size(), false);
  498. case_values[idx].type = Variant::Type(int(p_value));
  499. _change_notify();
  500. ports_changed_notify();
  501. return true;
  502. }
  503. return false;
  504. }
  505. bool VisualScriptSwitch::_get(const StringName &p_name, Variant &r_ret) const {
  506. if (String(p_name) == "case_count") {
  507. r_ret = case_values.size();
  508. return true;
  509. }
  510. if (String(p_name).begins_with("case/")) {
  511. int idx = String(p_name).get_slice("/", 1).to_int();
  512. ERR_FAIL_INDEX_V(idx, case_values.size(), false);
  513. r_ret = case_values[idx].type;
  514. return true;
  515. }
  516. return false;
  517. }
  518. void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const {
  519. p_list->push_back(PropertyInfo(Variant::INT, "case_count", PROPERTY_HINT_RANGE, "0,128"));
  520. String argt = "Any";
  521. for (int i = 1; i < Variant::VARIANT_MAX; i++) {
  522. argt += "," + Variant::get_type_name(Variant::Type(i));
  523. }
  524. for (int i = 0; i < case_values.size(); i++) {
  525. p_list->push_back(PropertyInfo(Variant::INT, "case/" + itos(i), PROPERTY_HINT_ENUM, argt));
  526. }
  527. }
  528. void VisualScriptSwitch::_bind_methods() {
  529. }
  530. VisualScriptSwitch::VisualScriptSwitch() {
  531. }
  532. //////////////////////////////////////////
  533. ////////////////EVENT ACTION FILTER///////////
  534. //////////////////////////////////////////
  535. #if 0
  536. int VisualScriptInputFilter::get_output_sequence_port_count() const {
  537. return filters.size();
  538. }
  539. bool VisualScriptInputFilter::has_input_sequence_port() const {
  540. return true;
  541. }
  542. int VisualScriptInputFilter::get_input_value_port_count() const {
  543. return 1;
  544. }
  545. int VisualScriptInputFilter::get_output_value_port_count() const {
  546. return 1;
  547. }
  548. String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const {
  549. String text;
  550. switch (filters[p_port].type) {
  551. case Ref<InputEvent>::NONE: {
  552. text = "None";
  553. } break;
  554. case Ref<InputEvent>::KEY: {
  555. InputEventKey k = filters[p_port].key;
  556. if (k->get_scancode() == 0 && k.unicode == 0) {
  557. text = "No Key";
  558. } else {
  559. if (k->get_scancode() != 0) {
  560. text = "KeyCode: " + keycode_get_string(k->get_scancode());
  561. } else if (k.unicode != 0) {
  562. text = "Uniode: " + String::chr(k.unicode);
  563. }
  564. if (k->is_pressed())
  565. text += ", Pressed";
  566. else
  567. text += ", Released";
  568. if (k.echo)
  569. text += ", Echo";
  570. if (k->get_alt())
  571. text = "Alt+" + text;
  572. if (k->get_shift())
  573. text = "Shift+" + text;
  574. if (k->get_control())
  575. text = "Ctrl+" + text;
  576. if (k->get_metakey())
  577. text = "Meta+" + text;
  578. }
  579. } break;
  580. case Ref<InputEvent>::MOUSE_MOTION: {
  581. InputEventMouseMotion mm = filters[p_port].mouse_motion;
  582. text = "Mouse Motion";
  583. String b = "Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight";
  584. for (int i = 0; i < 7; i++) {
  585. if (mm->get_button_mask() & (1 << i)) {
  586. text = b.get_slice(",", i) + "+" + text;
  587. }
  588. }
  589. if (mm->get_alt())
  590. text = "Alt+" + text;
  591. if (mm->get_shift())
  592. text = "Shift+" + text;
  593. if (mm->get_control())
  594. text = "Ctrl+" + text;
  595. if (mm->get_metakey())
  596. text = "Meta+" + text;
  597. } break;
  598. case Ref<InputEvent>::MOUSE_BUTTON: {
  599. InputEventMouseButton mb = filters[p_port].mouse_button;
  600. String b = "Any,Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight";
  601. text = b.get_slice(",", mb->get_button_index()) + " Mouse Button";
  602. if (mb->is_pressed())
  603. text += ", Pressed";
  604. else
  605. text += ", Released";
  606. if (mb.doubleclick)
  607. text += ", DblClick";
  608. if (mb->get_alt())
  609. text = "Alt+" + text;
  610. if (mb->get_shift())
  611. text = "Shift+" + text;
  612. if (mb->get_control())
  613. text = "Ctrl+" + text;
  614. if (mb->get_metakey())
  615. text = "Meta+" + text;
  616. } break;
  617. case Ref<InputEvent>::JOYPAD_MOTION: {
  618. InputEventJoypadMotion jm = filters[p_port].joy_motion;
  619. text = "JoyMotion Axis " + itos(jm.axis >> 1);
  620. if (jm.axis & 1)
  621. text += " > " + rtos(jm.axis_value);
  622. else
  623. text += " < " + rtos(-jm.axis_value);
  624. } break;
  625. case Ref<InputEvent>::JOYPAD_BUTTON: {
  626. InputEventJoypadButton jb = filters[p_port].joy_button;
  627. text = "JoyButton " + itos(jb->get_button_index());
  628. if (jb->is_pressed())
  629. text += ", Pressed";
  630. else
  631. text += ", Released";
  632. } break;
  633. case Ref<InputEvent>::SCREEN_TOUCH: {
  634. InputEventScreenTouch sd = filters[p_port].screen_touch;
  635. text = "Touch Finger " + itos(sd.index);
  636. if (sd->is_pressed())
  637. text += ", Pressed";
  638. else
  639. text += ", Released";
  640. } break;
  641. case Ref<InputEvent>::SCREEN_DRAG: {
  642. InputEventScreenDrag sd = filters[p_port].screen_drag;
  643. text = "Drag Finger " + itos(sd.index);
  644. } break;
  645. case Ref<InputEvent>::ACTION: {
  646. List<PropertyInfo> pinfo;
  647. GlobalConfig::get_singleton()->get_property_list(&pinfo);
  648. int index = 1;
  649. text = "No Action";
  650. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  651. const PropertyInfo &pi = E->get();
  652. if (!pi.name.begins_with("input/"))
  653. continue;
  654. if (filters[p_port].action.action == index) {
  655. text = "Action " + pi.name.substr(pi.name.find("/") + 1, pi.name.length());
  656. break;
  657. }
  658. index++;
  659. }
  660. if (filters[p_port].action->is_pressed())
  661. text += ", Pressed";
  662. else
  663. text += ", Released";
  664. } break;
  665. }
  666. return text + " - " + itos(p_port);
  667. }
  668. PropertyInfo VisualScriptInputFilter::get_input_value_port_info(int p_idx) const {
  669. return PropertyInfo(Variant::INPUT_EVENT, "event");
  670. }
  671. PropertyInfo VisualScriptInputFilter::get_output_value_port_info(int p_idx) const {
  672. return PropertyInfo(Variant::INPUT_EVENT, "");
  673. }
  674. String VisualScriptInputFilter::get_caption() const {
  675. return "InputFilter";
  676. }
  677. String VisualScriptInputFilter::get_text() const {
  678. return "";
  679. }
  680. bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_value) {
  681. if (p_name == "filter_count") {
  682. filters.resize(p_value);
  683. _change_notify();
  684. ports_changed_notify();
  685. return true;
  686. }
  687. if (String(p_name).begins_with("filter_")) {
  688. int idx = String(p_name).replace_first("filters_", "").get_slice("/", 0).to_int();
  689. ERR_FAIL_INDEX_V(idx, filters.size(), false);
  690. String what = String(p_name).get_slice("/", 1);
  691. if (what == "type") {
  692. filters[idx] = Ref<InputEvent>();
  693. filters[idx].type = Ref<InputEvent>::Type(int(p_value));
  694. if (filters[idx].type == Ref<InputEvent>::JOYPAD_MOTION) {
  695. filters[idx].joy_motion.axis_value = 0.5; //for threshold
  696. } else if (filters[idx].type == Ref<InputEvent>::KEY) {
  697. filters[idx]->is_pressed() = true; //put these as true to make it more user friendly
  698. } else if (filters[idx].type == Ref<InputEvent>::MOUSE_BUTTON) {
  699. filters[idx]->is_pressed() = true;
  700. } else if (filters[idx].type == Ref<InputEvent>::JOYPAD_BUTTON) {
  701. filters[idx].joy_button->is_pressed() = true;
  702. } else if (filters[idx].type == Ref<InputEvent>::SCREEN_TOUCH) {
  703. filters[idx].screen_touch->is_pressed() = true;
  704. } else if (filters[idx].type == Ref<InputEvent>::ACTION) {
  705. filters[idx].action->is_pressed() = true;
  706. }
  707. _change_notify();
  708. ports_changed_notify();
  709. return true;
  710. }
  711. if (what == "device") {
  712. filters[idx].device = p_value;
  713. ports_changed_notify();
  714. return true;
  715. }
  716. switch (filters[idx].type) {
  717. case Ref<InputEvent>::KEY: {
  718. if (what == "scancode") {
  719. String sc = p_value;
  720. if (sc == String()) {
  721. filters[idx]->get_scancode() = 0;
  722. } else {
  723. filters[idx]->get_scancode() = find_keycode(p_value);
  724. }
  725. } else if (what == "unicode") {
  726. String uc = p_value;
  727. if (uc == String()) {
  728. filters[idx].key.unicode = 0;
  729. } else {
  730. filters[idx].key.unicode = uc[0];
  731. }
  732. } else if (what == "pressed") {
  733. filters[idx]->is_pressed() = p_value;
  734. } else if (what == "echo") {
  735. filters[idx]->is_echo() = p_value;
  736. } else if (what == "mod_alt") {
  737. filters[idx]->get_alt() = p_value;
  738. } else if (what == "mod_shift") {
  739. filters[idx]->get_shift() = p_value;
  740. } else if (what == "mod_ctrl") {
  741. filters[idx]->get_control() = p_value;
  742. } else if (what == "mod_meta") {
  743. filters[idx]->get_metakey() = p_value;
  744. } else {
  745. return false;
  746. }
  747. ports_changed_notify();
  748. return true;
  749. } break;
  750. case Ref<InputEvent>::MOUSE_MOTION: {
  751. if (what == "button_mask") {
  752. filters[idx]->get_button_mask() = p_value;
  753. } else if (what == "mod_alt") {
  754. filters[idx].mouse_motion->get_alt() = p_value;
  755. } else if (what == "mod_shift") {
  756. filters[idx].mouse_motion->get_shift() = p_value;
  757. } else if (what == "mod_ctrl") {
  758. filters[idx].mouse_motion->get_control() = p_value;
  759. } else if (what == "mod_meta") {
  760. filters[idx].mouse_motion->get_metakey() = p_value;
  761. } else {
  762. return false;
  763. }
  764. ports_changed_notify();
  765. return true;
  766. } break;
  767. case Ref<InputEvent>::MOUSE_BUTTON: {
  768. if (what == "button_index") {
  769. filters[idx]->get_button_index() = p_value;
  770. } else if (what == "pressed") {
  771. filters[idx]->is_pressed() = p_value;
  772. } else if (what == "doubleclicked") {
  773. filters[idx].mouse_button.doubleclick = p_value;
  774. } else if (what == "mod_alt") {
  775. filters[idx].mouse_button->get_alt() = p_value;
  776. } else if (what == "mod_shift") {
  777. filters[idx].mouse_button->get_shift() = p_value;
  778. } else if (what == "mod_ctrl") {
  779. filters[idx].mouse_button->get_control() = p_value;
  780. } else if (what == "mod_meta") {
  781. filters[idx].mouse_button->get_metakey() = p_value;
  782. } else {
  783. return false;
  784. }
  785. ports_changed_notify();
  786. return true;
  787. } break;
  788. case Ref<InputEvent>::JOYPAD_MOTION: {
  789. if (what == "axis") {
  790. filters[idx].joy_motion.axis = int(p_value) << 1 | filters[idx].joy_motion.axis;
  791. } else if (what == "mode") {
  792. filters[idx].joy_motion.axis |= int(p_value);
  793. } else if (what == "threshold") {
  794. filters[idx].joy_motion.axis_value = p_value;
  795. } else {
  796. return false;
  797. }
  798. ports_changed_notify();
  799. return true;
  800. } break;
  801. case Ref<InputEvent>::JOYPAD_BUTTON: {
  802. if (what == "button_index") {
  803. filters[idx].joy_button->get_button_index() = p_value;
  804. } else if (what == "pressed") {
  805. filters[idx].joy_button->is_pressed() = p_value;
  806. } else {
  807. return false;
  808. }
  809. ports_changed_notify();
  810. return true;
  811. } break;
  812. case Ref<InputEvent>::SCREEN_TOUCH: {
  813. if (what == "finger_index") {
  814. filters[idx].screen_touch.index = p_value;
  815. } else if (what == "pressed") {
  816. filters[idx].screen_touch->is_pressed() = p_value;
  817. } else {
  818. return false;
  819. }
  820. ports_changed_notify();
  821. return true;
  822. } break;
  823. case Ref<InputEvent>::SCREEN_DRAG: {
  824. if (what == "finger_index") {
  825. filters[idx].screen_drag.index = p_value;
  826. } else {
  827. return false;
  828. }
  829. ports_changed_notify();
  830. return true;
  831. } break;
  832. case Ref<InputEvent>::ACTION: {
  833. if (what == "action_name") {
  834. List<PropertyInfo> pinfo;
  835. GlobalConfig::get_singleton()->get_property_list(&pinfo);
  836. int index = 1;
  837. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  838. const PropertyInfo &pi = E->get();
  839. if (!pi.name.begins_with("input/"))
  840. continue;
  841. String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
  842. if (name == String(p_value)) {
  843. filters[idx].action.action = index;
  844. ports_changed_notify();
  845. return true;
  846. }
  847. index++;
  848. }
  849. filters[idx].action.action = 0;
  850. ports_changed_notify();
  851. return false;
  852. } else if (what == "pressed") {
  853. filters[idx].action->is_pressed() = p_value;
  854. ports_changed_notify();
  855. return true;
  856. }
  857. } break;
  858. }
  859. }
  860. return false;
  861. }
  862. bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) const {
  863. if (p_name == "filter_count") {
  864. r_ret = filters.size();
  865. return true;
  866. }
  867. if (String(p_name).begins_with("filter_")) {
  868. int idx = String(p_name).replace_first("filters_", "").get_slice("/", 0).to_int();
  869. ERR_FAIL_INDEX_V(idx, filters.size(), false);
  870. String what = String(p_name).get_slice("/", 1);
  871. if (what == "type") {
  872. r_ret = filters[idx].type;
  873. return true;
  874. }
  875. if (what == "device") {
  876. r_ret = filters[idx].device;
  877. return true;
  878. }
  879. switch (filters[idx].type) {
  880. case Ref<InputEvent>::KEY: {
  881. if (what == "scancode") {
  882. if (filters[idx]->get_scancode() == 0)
  883. r_ret = String();
  884. else {
  885. r_ret = keycode_get_string(filters[idx]->get_scancode());
  886. }
  887. } else if (what == "unicode") {
  888. if (filters[idx].key.unicode == 0) {
  889. r_ret = String();
  890. } else {
  891. CharType str[2] = { (CharType)filters[idx].key.unicode, 0 };
  892. r_ret = String(str);
  893. }
  894. } else if (what == "pressed") {
  895. r_ret = filters[idx]->is_pressed();
  896. } else if (what == "echo") {
  897. r_ret = filters[idx]->is_echo();
  898. } else if (what == "mod_alt") {
  899. r_ret = filters[idx]->get_alt();
  900. } else if (what == "mod_shift") {
  901. r_ret = filters[idx]->get_shift();
  902. } else if (what == "mod_ctrl") {
  903. r_ret = filters[idx]->get_control();
  904. } else if (what == "mod_meta") {
  905. r_ret = filters[idx]->get_metakey();
  906. } else {
  907. return false;
  908. }
  909. return true;
  910. } break;
  911. case Ref<InputEvent>::MOUSE_MOTION: {
  912. if (what == "button_mask") {
  913. r_ret = filters[idx]->get_button_mask();
  914. } else if (what == "mod_alt") {
  915. r_ret = filters[idx].mouse_motion->get_alt();
  916. } else if (what == "mod_shift") {
  917. r_ret = filters[idx].mouse_motion->get_shift();
  918. } else if (what == "mod_ctrl") {
  919. r_ret = filters[idx].mouse_motion->get_control();
  920. } else if (what == "mod_meta") {
  921. r_ret = filters[idx].mouse_motion->get_metakey();
  922. } else {
  923. return false;
  924. }
  925. return true;
  926. } break;
  927. case Ref<InputEvent>::MOUSE_BUTTON: {
  928. if (what == "button_index") {
  929. r_ret = filters[idx]->get_button_index();
  930. } else if (what == "pressed") {
  931. r_ret = filters[idx]->is_pressed();
  932. } else if (what == "doubleclicked") {
  933. r_ret = filters[idx].mouse_button.doubleclick;
  934. } else if (what == "mod_alt") {
  935. r_ret = filters[idx].mouse_button->get_alt();
  936. } else if (what == "mod_shift") {
  937. r_ret = filters[idx].mouse_button->get_shift();
  938. } else if (what == "mod_ctrl") {
  939. r_ret = filters[idx].mouse_button->get_control();
  940. } else if (what == "mod_meta") {
  941. r_ret = filters[idx].mouse_button->get_metakey();
  942. } else {
  943. return false;
  944. }
  945. return true;
  946. } break;
  947. case Ref<InputEvent>::JOYPAD_MOTION: {
  948. if (what == "axis_index") {
  949. r_ret = filters[idx].joy_motion.axis >> 1;
  950. } else if (what == "mode") {
  951. r_ret = filters[idx].joy_motion.axis & 1;
  952. } else if (what == "threshold") {
  953. r_ret = filters[idx].joy_motion.axis_value;
  954. } else {
  955. return false;
  956. }
  957. return true;
  958. } break;
  959. case Ref<InputEvent>::JOYPAD_BUTTON: {
  960. if (what == "button_index") {
  961. r_ret = filters[idx].joy_button->get_button_index();
  962. } else if (what == "pressed") {
  963. r_ret = filters[idx].joy_button->is_pressed();
  964. } else {
  965. return false;
  966. }
  967. return true;
  968. } break;
  969. case Ref<InputEvent>::SCREEN_TOUCH: {
  970. if (what == "finger_index") {
  971. r_ret = filters[idx].screen_touch.index;
  972. } else if (what == "pressed") {
  973. r_ret = filters[idx].screen_touch->is_pressed();
  974. } else {
  975. return false;
  976. }
  977. return true;
  978. } break;
  979. case Ref<InputEvent>::SCREEN_DRAG: {
  980. if (what == "finger_index") {
  981. r_ret = filters[idx].screen_drag.index;
  982. } else {
  983. return false;
  984. }
  985. return true;
  986. } break;
  987. case Ref<InputEvent>::ACTION: {
  988. if (what == "action_name") {
  989. List<PropertyInfo> pinfo;
  990. GlobalConfig::get_singleton()->get_property_list(&pinfo);
  991. int index = 1;
  992. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  993. const PropertyInfo &pi = E->get();
  994. if (!pi.name.begins_with("input/"))
  995. continue;
  996. if (filters[idx].action.action == index) {
  997. r_ret = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
  998. return true;
  999. }
  1000. index++;
  1001. }
  1002. r_ret = "None"; //no index
  1003. return false;
  1004. } else if (what == "pressed") {
  1005. r_ret = filters[idx].action->is_pressed();
  1006. return true;
  1007. }
  1008. } break;
  1009. }
  1010. }
  1011. return false;
  1012. }
  1013. static const char *event_type_names[Ref<InputEvent>::TYPE_MAX] = {
  1014. "None",
  1015. "Key",
  1016. "MouseMotion",
  1017. "MouseButton",
  1018. "JoypadMotion",
  1019. "JoypadButton",
  1020. "ScreenTouch",
  1021. "ScreenDrag",
  1022. "Action"
  1023. };
  1024. void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) const {
  1025. p_list->push_back(PropertyInfo(Variant::INT, "filter_count", PROPERTY_HINT_RANGE, "0,64"));
  1026. String et;
  1027. for (int i = 0; i < Ref<InputEvent>::TYPE_MAX; i++) {
  1028. if (i > 0)
  1029. et += ",";
  1030. et += event_type_names[i];
  1031. }
  1032. String kc;
  1033. String actions;
  1034. for (int i = 0; i < filters.size(); i++) {
  1035. String base = "filter_" + itos(i) + "/";
  1036. p_list->push_back(PropertyInfo(Variant::INT, base + "type", PROPERTY_HINT_ENUM, et));
  1037. p_list->push_back(PropertyInfo(Variant::INT, base + "device"));
  1038. switch (filters[i].type) {
  1039. case Ref<InputEvent>::NONE: {
  1040. } break;
  1041. case Ref<InputEvent>::KEY: {
  1042. if (kc == String()) {
  1043. int kcc = keycode_get_count();
  1044. kc = "None";
  1045. for (int i = 0; i < kcc; i++) {
  1046. kc += ",";
  1047. kc += String(keycode_get_name_by_index(i));
  1048. }
  1049. }
  1050. p_list->push_back(PropertyInfo(Variant::STRING, base + "scancode", PROPERTY_HINT_ENUM, kc));
  1051. p_list->push_back(PropertyInfo(Variant::STRING, base + "unicode"));
  1052. p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
  1053. p_list->push_back(PropertyInfo(Variant::BOOL, base + "echo"));
  1054. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_alt"));
  1055. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_shift"));
  1056. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_ctrl"));
  1057. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
  1058. } break;
  1059. case Ref<InputEvent>::MOUSE_MOTION: {
  1060. p_list->push_back(PropertyInfo(Variant::INT, base + "button_mask", PROPERTY_HINT_FLAGS, "Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"));
  1061. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_alt"));
  1062. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_shift"));
  1063. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_ctrl"));
  1064. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
  1065. } break;
  1066. case Ref<InputEvent>::MOUSE_BUTTON: {
  1067. p_list->push_back(PropertyInfo(Variant::INT, base + "button_index", PROPERTY_HINT_ENUM, "Any,Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"));
  1068. p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
  1069. p_list->push_back(PropertyInfo(Variant::BOOL, base + "doubleclicked"));
  1070. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_alt"));
  1071. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_shift"));
  1072. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_ctrl"));
  1073. p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
  1074. } break;
  1075. case Ref<InputEvent>::JOYPAD_MOTION: {
  1076. p_list->push_back(PropertyInfo(Variant::INT, base + "axis_index"));
  1077. p_list->push_back(PropertyInfo(Variant::INT, base + "mode", PROPERTY_HINT_ENUM, "Min,Max"));
  1078. p_list->push_back(PropertyInfo(Variant::REAL, base + "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"));
  1079. } break;
  1080. case Ref<InputEvent>::JOYPAD_BUTTON: {
  1081. p_list->push_back(PropertyInfo(Variant::INT, base + "button_index"));
  1082. p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
  1083. } break;
  1084. case Ref<InputEvent>::SCREEN_TOUCH: {
  1085. p_list->push_back(PropertyInfo(Variant::INT, base + "finger_index"));
  1086. p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
  1087. } break;
  1088. case Ref<InputEvent>::SCREEN_DRAG: {
  1089. p_list->push_back(PropertyInfo(Variant::INT, base + "finger_index"));
  1090. } break;
  1091. case Ref<InputEvent>::ACTION: {
  1092. if (actions == String()) {
  1093. actions = "None";
  1094. List<PropertyInfo> pinfo;
  1095. GlobalConfig::get_singleton()->get_property_list(&pinfo);
  1096. Vector<String> al;
  1097. for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
  1098. const PropertyInfo &pi = E->get();
  1099. if (!pi.name.begins_with("input/"))
  1100. continue;
  1101. String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
  1102. al.push_back(name);
  1103. }
  1104. for (int i = 0; i < al.size(); i++) {
  1105. actions += ",";
  1106. actions += al[i];
  1107. }
  1108. }
  1109. p_list->push_back(PropertyInfo(Variant::STRING, base + "action_name", PROPERTY_HINT_ENUM, actions));
  1110. p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
  1111. } break;
  1112. }
  1113. }
  1114. }
  1115. class VisualScriptNodeInstanceInputFilter : public VisualScriptNodeInstance {
  1116. public:
  1117. VisualScriptInstance *instance;
  1118. Vector<Ref<InputEvent>> filters;
  1119. //virtual int get_working_memory_size() const { return 0; }
  1120. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  1121. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
  1122. 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) {
  1123. if (p_inputs[0]->get_type() != Variant::INPUT_EVENT) {
  1124. r_error_str = "Input value not of type event";
  1125. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1126. return 0;
  1127. }
  1128. Ref<InputEvent> event = *p_inputs[0];
  1129. for (int i = 0; i < filters.size(); i++) {
  1130. const Ref<InputEvent> &ie = filters[i];
  1131. if (ie.type != event.type)
  1132. continue;
  1133. bool match = false;
  1134. switch (ie.type) {
  1135. case Ref<InputEvent>::NONE: {
  1136. match = true;
  1137. } break;
  1138. case Ref<InputEvent>::KEY: {
  1139. InputEventKey k = ie.key;
  1140. InputEventKey k2 = event.key;
  1141. if (k->get_scancode() == 0 && k.unicode == 0 && k2->get_scancode() == 0 && k2.unicode == 0) {
  1142. match = true;
  1143. } else {
  1144. if ((k->get_scancode() != 0 && k->get_scancode() == k2->get_scancode()) || (k.unicode != 0 && k.unicode == k2.unicode)) {
  1145. //key valid
  1146. if (
  1147. k->is_pressed() == k2->is_pressed() &&
  1148. k.echo == k2.echo &&
  1149. k.mod == k2.mod) {
  1150. match = true;
  1151. }
  1152. }
  1153. }
  1154. } break;
  1155. case Ref<InputEvent>::MOUSE_MOTION: {
  1156. InputEventMouseMotion mm = ie.mouse_motion;
  1157. InputEventMouseMotion mm2 = event.mouse_motion;
  1158. if (mm->get_button_mask() == mm2->get_button_mask() &&
  1159. mm.mod == mm2.mod) {
  1160. match = true;
  1161. }
  1162. } break;
  1163. case Ref<InputEvent>::MOUSE_BUTTON: {
  1164. InputEventMouseButton mb = ie.mouse_button;
  1165. InputEventMouseButton mb2 = event.mouse_button;
  1166. if (mb->get_button_index() == mb2->get_button_index() &&
  1167. mb->is_pressed() == mb2->is_pressed() &&
  1168. mb.doubleclick == mb2.doubleclick &&
  1169. mb.mod == mb2.mod) {
  1170. match = true;
  1171. }
  1172. } break;
  1173. case Ref<InputEvent>::JOYPAD_MOTION: {
  1174. InputEventJoypadMotion jm = ie.joy_motion;
  1175. InputEventJoypadMotion jm2 = event.joy_motion;
  1176. int axis = jm.axis >> 1;
  1177. if (axis == jm2.axis) {
  1178. if (jm.axis & 1) {
  1179. //greater
  1180. if (jm2.axis_value > jm.axis_value) {
  1181. match = true;
  1182. }
  1183. } else {
  1184. //less
  1185. if (jm2.axis_value < -jm.axis_value) {
  1186. match = true;
  1187. }
  1188. }
  1189. }
  1190. } break;
  1191. case Ref<InputEvent>::JOYPAD_BUTTON: {
  1192. InputEventJoypadButton jb = ie.joy_button;
  1193. InputEventJoypadButton jb2 = event.joy_button;
  1194. if (jb->get_button_index() == jb2->get_button_index() &&
  1195. jb->is_pressed() == jb2->is_pressed()) {
  1196. match = true;
  1197. }
  1198. } break;
  1199. case Ref<InputEvent>::SCREEN_TOUCH: {
  1200. InputEventScreenTouch st = ie.screen_touch;
  1201. InputEventScreenTouch st2 = event.screen_touch;
  1202. if (st.index == st2.index &&
  1203. st->is_pressed() == st2->is_pressed()) {
  1204. match = true;
  1205. }
  1206. } break;
  1207. case Ref<InputEvent>::SCREEN_DRAG: {
  1208. InputEventScreenDrag sd = ie.screen_drag;
  1209. InputEventScreenDrag sd2 = event.screen_drag;
  1210. if (sd.index == sd2.index) {
  1211. match = true;
  1212. }
  1213. } break;
  1214. case Ref<InputEvent>::ACTION: {
  1215. InputEventAction ia = ie.action;
  1216. InputEventAction ia2 = event.action;
  1217. if (ia.action == ia2.action &&
  1218. ia->is_pressed() == ia2->is_pressed()) {
  1219. match = true;
  1220. }
  1221. } break;
  1222. }
  1223. *p_outputs[0] = event;
  1224. if (match)
  1225. return i; //go through match output
  1226. }
  1227. return STEP_NO_ADVANCE_BIT; //none found, don't advance
  1228. }
  1229. };
  1230. VisualScriptNodeInstance *VisualScriptInputFilter::instance(VisualScriptInstance *p_instance) {
  1231. VisualScriptNodeInstanceInputFilter *instance = memnew(VisualScriptNodeInstanceInputFilter);
  1232. instance->instance = p_instance;
  1233. instance->filters = filters;
  1234. return instance;
  1235. }
  1236. VisualScriptInputFilter::VisualScriptInputFilter() {
  1237. }
  1238. #endif
  1239. //////////////////////////////////////////
  1240. ////////////////TYPE CAST///////////
  1241. //////////////////////////////////////////
  1242. int VisualScriptTypeCast::get_output_sequence_port_count() const {
  1243. return 2;
  1244. }
  1245. bool VisualScriptTypeCast::has_input_sequence_port() const {
  1246. return true;
  1247. }
  1248. int VisualScriptTypeCast::get_input_value_port_count() const {
  1249. return 1;
  1250. }
  1251. int VisualScriptTypeCast::get_output_value_port_count() const {
  1252. return 1;
  1253. }
  1254. String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const {
  1255. return p_port == 0 ? "yes" : "no";
  1256. }
  1257. PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const {
  1258. return PropertyInfo(Variant::OBJECT, "instance");
  1259. }
  1260. PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const {
  1261. return PropertyInfo(Variant::OBJECT, "");
  1262. }
  1263. String VisualScriptTypeCast::get_caption() const {
  1264. return "TypeCast";
  1265. }
  1266. String VisualScriptTypeCast::get_text() const {
  1267. if (script != String())
  1268. return "Is " + script.get_file() + "?";
  1269. else
  1270. return "Is " + base_type + "?";
  1271. }
  1272. void VisualScriptTypeCast::set_base_type(const StringName &p_type) {
  1273. if (base_type == p_type)
  1274. return;
  1275. base_type = p_type;
  1276. _change_notify();
  1277. ports_changed_notify();
  1278. }
  1279. StringName VisualScriptTypeCast::get_base_type() const {
  1280. return base_type;
  1281. }
  1282. void VisualScriptTypeCast::set_base_script(const String &p_path) {
  1283. if (script == p_path)
  1284. return;
  1285. script = p_path;
  1286. _change_notify();
  1287. ports_changed_notify();
  1288. }
  1289. String VisualScriptTypeCast::get_base_script() const {
  1290. return script;
  1291. }
  1292. VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const {
  1293. TypeGuess tg;
  1294. tg.type = Variant::OBJECT;
  1295. if (script != String()) {
  1296. tg.script = ResourceLoader::load(script);
  1297. }
  1298. //if (!tg.script.is_valid()) {
  1299. // tg.gdclass = base_type;
  1300. //}
  1301. return tg;
  1302. }
  1303. class VisualScriptNodeInstanceTypeCast : public VisualScriptNodeInstance {
  1304. public:
  1305. VisualScriptInstance *instance;
  1306. StringName base_type;
  1307. String script;
  1308. //virtual int get_working_memory_size() const { return 0; }
  1309. //virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
  1310. //virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
  1311. 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) {
  1312. Object *obj = *p_inputs[0];
  1313. *p_outputs[0] = Variant();
  1314. if (!obj) {
  1315. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1316. r_error_str = "Instance is null";
  1317. return 0;
  1318. }
  1319. if (script != String()) {
  1320. Ref<Script> obj_script = obj->get_script();
  1321. if (!obj_script.is_valid()) {
  1322. return 1; //well, definitely not the script because object we got has no script.
  1323. }
  1324. if (!ResourceCache::has(script)) {
  1325. //if the script is not in use by anyone, we can safely assume whathever we got is not casting to it.
  1326. return 1;
  1327. }
  1328. Ref<Script> cast_script = Ref<Resource>(ResourceCache::get(script));
  1329. if (!cast_script.is_valid()) {
  1330. r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
  1331. r_error_str = "Script path is not a script: " + script;
  1332. return 1;
  1333. }
  1334. while (obj_script.is_valid()) {
  1335. if (cast_script == obj_script) {
  1336. *p_outputs[0] = *p_inputs[0]; //copy
  1337. return 0; // it is the script, yey
  1338. }
  1339. obj_script = obj_script->get_base_script();
  1340. }
  1341. return 1; //not found sorry
  1342. }
  1343. if (ClassDB::is_parent_class(obj->get_class_name(), base_type)) {
  1344. *p_outputs[0] = *p_inputs[0]; //copy
  1345. return 0;
  1346. } else
  1347. return 1;
  1348. }
  1349. };
  1350. VisualScriptNodeInstance *VisualScriptTypeCast::instance(VisualScriptInstance *p_instance) {
  1351. VisualScriptNodeInstanceTypeCast *instance = memnew(VisualScriptNodeInstanceTypeCast);
  1352. instance->instance = p_instance;
  1353. instance->base_type = base_type;
  1354. instance->script = script;
  1355. return instance;
  1356. }
  1357. void VisualScriptTypeCast::_bind_methods() {
  1358. ClassDB::bind_method(D_METHOD("set_base_type", "type"), &VisualScriptTypeCast::set_base_type);
  1359. ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptTypeCast::get_base_type);
  1360. ClassDB::bind_method(D_METHOD("set_base_script", "path"), &VisualScriptTypeCast::set_base_script);
  1361. ClassDB::bind_method(D_METHOD("get_base_script"), &VisualScriptTypeCast::get_base_script);
  1362. List<String> script_extensions;
  1363. for (int i = 0; i > ScriptServer::get_language_count(); i++) {
  1364. ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
  1365. }
  1366. String script_ext_hint;
  1367. for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
  1368. if (script_ext_hint != String())
  1369. script_ext_hint += ",";
  1370. script_ext_hint += "*." + E->get();
  1371. }
  1372. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_type", PROPERTY_HINT_TYPE_STRING, "Object"), "set_base_type", "get_base_type");
  1373. ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
  1374. }
  1375. VisualScriptTypeCast::VisualScriptTypeCast() {
  1376. base_type = "Object";
  1377. }
  1378. void register_visual_script_flow_control_nodes() {
  1379. VisualScriptLanguage::singleton->add_register_func("flow_control/return", create_return_node<false>);
  1380. VisualScriptLanguage::singleton->add_register_func("flow_control/return_with_value", create_return_node<true>);
  1381. VisualScriptLanguage::singleton->add_register_func("flow_control/condition", create_node_generic<VisualScriptCondition>);
  1382. VisualScriptLanguage::singleton->add_register_func("flow_control/while", create_node_generic<VisualScriptWhile>);
  1383. VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>);
  1384. VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>);
  1385. VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>);
  1386. //VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>);
  1387. VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>);
  1388. }