visual_script_flow_control.cpp 47 KB

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