gd_functions.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218
  1. /*************************************************************************/
  2. /* gd_functions.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2014 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 "gd_functions.h"
  30. #include "math_funcs.h"
  31. #include "object_type_db.h"
  32. #include "reference.h"
  33. #include "gd_script.h"
  34. #include "os/os.h"
  35. const char *GDFunctions::get_func_name(Function p_func) {
  36. ERR_FAIL_INDEX_V(p_func,FUNC_MAX,"");
  37. static const char *_names[FUNC_MAX]={
  38. "sin",
  39. "cos",
  40. "tan",
  41. "sinh",
  42. "cosh",
  43. "tanh",
  44. "asin",
  45. "acos",
  46. "atan",
  47. "atan2",
  48. "sqrt",
  49. "fmod",
  50. "fposmod",
  51. "floor",
  52. "ceil",
  53. "round",
  54. "abs",
  55. "sign",
  56. "pow",
  57. "log",
  58. "exp",
  59. "is_nan",
  60. "is_inf",
  61. "ease",
  62. "decimals",
  63. "stepify",
  64. "lerp",
  65. "dectime",
  66. "randomize",
  67. "randi",
  68. "randf",
  69. "rand_range",
  70. "rand_seed",
  71. "deg2rad",
  72. "rad2deg",
  73. "linear2db",
  74. "db2linear",
  75. "max",
  76. "min",
  77. "clamp",
  78. "nearest_po2",
  79. "weakref",
  80. "convert",
  81. "typeof",
  82. "str",
  83. "print",
  84. "printt",
  85. "printerr",
  86. "printraw",
  87. "range",
  88. "load",
  89. "inst2dict",
  90. "dict2inst",
  91. "print_stack",
  92. };
  93. return _names[p_func];
  94. }
  95. void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Variant &r_ret,Variant::CallError &r_error) {
  96. r_error.error=Variant::CallError::CALL_OK;
  97. #ifdef DEBUG_ENABLED
  98. #define VALIDATE_ARG_COUNT(m_count) \
  99. if (p_arg_count<m_count) {\
  100. r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;\
  101. r_error.argument=m_count;\
  102. return;\
  103. }\
  104. if (p_arg_count>m_count) {\
  105. r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;\
  106. r_error.argument=m_count;\
  107. return;\
  108. }
  109. #define VALIDATE_ARG_NUM(m_arg) \
  110. if (!p_args[m_arg]->is_num()) {\
  111. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;\
  112. r_error.argument=m_arg;\
  113. r_error.expected=Variant::REAL;\
  114. return;\
  115. }
  116. #else
  117. #define VALIDATE_ARG_COUNT(m_count)
  118. #define VALIDATE_ARG_NUM(m_arg)
  119. #endif
  120. //using a switch, so the compiler generates a jumptable
  121. switch(p_func) {
  122. case MATH_SIN: {
  123. VALIDATE_ARG_COUNT(1);
  124. VALIDATE_ARG_NUM(0);
  125. r_ret=Math::sin(*p_args[0]);
  126. } break;
  127. case MATH_COS: {
  128. VALIDATE_ARG_COUNT(1);
  129. VALIDATE_ARG_NUM(0);
  130. r_ret=Math::cos(*p_args[0]);
  131. } break;
  132. case MATH_TAN: {
  133. VALIDATE_ARG_COUNT(1);
  134. VALIDATE_ARG_NUM(0);
  135. r_ret=Math::tan(*p_args[0]);
  136. } break;
  137. case MATH_SINH: {
  138. VALIDATE_ARG_COUNT(1);
  139. VALIDATE_ARG_NUM(0);
  140. r_ret=Math::sinh(*p_args[0]);
  141. } break;
  142. case MATH_COSH: {
  143. VALIDATE_ARG_COUNT(1);
  144. VALIDATE_ARG_NUM(0);
  145. r_ret=Math::cosh(*p_args[0]);
  146. } break;
  147. case MATH_TANH: {
  148. VALIDATE_ARG_COUNT(1);
  149. VALIDATE_ARG_NUM(0);
  150. r_ret=Math::tanh(*p_args[0]);
  151. } break;
  152. case MATH_ASIN: {
  153. VALIDATE_ARG_COUNT(1);
  154. VALIDATE_ARG_NUM(0);
  155. r_ret=Math::asin(*p_args[0]);
  156. } break;
  157. case MATH_ACOS: {
  158. VALIDATE_ARG_COUNT(1);
  159. VALIDATE_ARG_NUM(0);
  160. r_ret=Math::acos(*p_args[0]);
  161. } break;
  162. case MATH_ATAN: {
  163. VALIDATE_ARG_COUNT(1);
  164. VALIDATE_ARG_NUM(0);
  165. r_ret=Math::atan(*p_args[0]);
  166. } break;
  167. case MATH_ATAN2: {
  168. VALIDATE_ARG_COUNT(2);
  169. VALIDATE_ARG_NUM(0);
  170. VALIDATE_ARG_NUM(1);
  171. r_ret=Math::atan2(*p_args[0],*p_args[1]);
  172. } break;
  173. case MATH_SQRT: {
  174. VALIDATE_ARG_COUNT(1);
  175. VALIDATE_ARG_NUM(0);
  176. r_ret=Math::sqrt(*p_args[0]);
  177. } break;
  178. case MATH_FMOD: {
  179. VALIDATE_ARG_COUNT(2);
  180. VALIDATE_ARG_NUM(0);
  181. VALIDATE_ARG_NUM(1);
  182. r_ret=Math::fmod(*p_args[0],*p_args[1]);
  183. } break;
  184. case MATH_FPOSMOD: {
  185. VALIDATE_ARG_COUNT(2);
  186. VALIDATE_ARG_NUM(0);
  187. VALIDATE_ARG_NUM(1);
  188. r_ret=Math::fposmod(*p_args[0],*p_args[1]);
  189. } break;
  190. case MATH_FLOOR: {
  191. VALIDATE_ARG_COUNT(1);
  192. VALIDATE_ARG_NUM(0);
  193. r_ret=Math::floor(*p_args[0]);
  194. } break;
  195. case MATH_CEIL: {
  196. VALIDATE_ARG_COUNT(1);
  197. VALIDATE_ARG_NUM(0);
  198. r_ret=Math::ceil(*p_args[0]);
  199. } break;
  200. case MATH_ROUND: {
  201. VALIDATE_ARG_COUNT(1);
  202. VALIDATE_ARG_NUM(0);
  203. r_ret=Math::round(*p_args[0]);
  204. } break;
  205. case MATH_ABS: {
  206. VALIDATE_ARG_COUNT(1);
  207. if (p_args[0]->get_type()==Variant::INT) {
  208. int64_t i = *p_args[0];
  209. r_ret=ABS(i);
  210. } else if (p_args[0]->get_type()==Variant::REAL) {
  211. real_t r = *p_args[0];
  212. r_ret=Math::abs(r);
  213. } else {
  214. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  215. r_error.argument=0;
  216. r_error.expected=Variant::REAL;
  217. }
  218. } break;
  219. case MATH_SIGN: {
  220. VALIDATE_ARG_COUNT(1);
  221. if (p_args[0]->get_type()==Variant::INT) {
  222. int64_t i = *p_args[0];
  223. r_ret= i < 0 ? -1 : ( i > 0 ? +1 : 0);
  224. } else if (p_args[0]->get_type()==Variant::REAL) {
  225. real_t r = *p_args[0];
  226. r_ret= r < 0.0 ? -1.0 : ( r > 0.0 ? +1.0 : 0.0);
  227. } else {
  228. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  229. r_error.argument=0;
  230. r_error.expected=Variant::REAL;
  231. }
  232. } break;
  233. case MATH_POW: {
  234. VALIDATE_ARG_COUNT(2);
  235. VALIDATE_ARG_NUM(0);
  236. VALIDATE_ARG_NUM(1);
  237. r_ret=Math::pow(*p_args[0],*p_args[1]);
  238. } break;
  239. case MATH_LOG: {
  240. VALIDATE_ARG_COUNT(1);
  241. VALIDATE_ARG_NUM(0);
  242. r_ret=Math::log(*p_args[0]);
  243. } break;
  244. case MATH_EXP: {
  245. VALIDATE_ARG_COUNT(1);
  246. VALIDATE_ARG_NUM(0);
  247. r_ret=Math::exp(*p_args[0]);
  248. } break;
  249. case MATH_ISNAN: {
  250. VALIDATE_ARG_COUNT(1);
  251. VALIDATE_ARG_NUM(0);
  252. r_ret=Math::is_nan(*p_args[0]);
  253. } break;
  254. case MATH_ISINF: {
  255. VALIDATE_ARG_COUNT(1);
  256. VALIDATE_ARG_NUM(0);
  257. r_ret=Math::is_inf(*p_args[0]);
  258. } break;
  259. case MATH_EASE: {
  260. VALIDATE_ARG_COUNT(2);
  261. VALIDATE_ARG_NUM(0);
  262. VALIDATE_ARG_NUM(1);
  263. r_ret=Math::ease(*p_args[0],*p_args[1]);
  264. } break;
  265. case MATH_DECIMALS: {
  266. VALIDATE_ARG_COUNT(1);
  267. VALIDATE_ARG_NUM(0);
  268. r_ret=Math::decimals(*p_args[0]);
  269. } break;
  270. case MATH_STEPIFY: {
  271. VALIDATE_ARG_COUNT(2);
  272. VALIDATE_ARG_NUM(0);
  273. VALIDATE_ARG_NUM(1);
  274. r_ret=Math::stepify(*p_args[0],*p_args[1]);
  275. } break;
  276. case MATH_LERP: {
  277. VALIDATE_ARG_COUNT(3);
  278. VALIDATE_ARG_NUM(0);
  279. VALIDATE_ARG_NUM(1);
  280. VALIDATE_ARG_NUM(2);
  281. r_ret=Math::lerp(*p_args[0],*p_args[1],*p_args[2]);
  282. } break;
  283. case MATH_DECTIME: {
  284. VALIDATE_ARG_COUNT(3);
  285. VALIDATE_ARG_NUM(0);
  286. VALIDATE_ARG_NUM(1);
  287. VALIDATE_ARG_NUM(2);
  288. r_ret=Math::dectime(*p_args[0],*p_args[1],*p_args[2]);
  289. } break;
  290. case MATH_RANDOMIZE: {
  291. Math::randomize();
  292. r_ret=Variant();
  293. } break;
  294. case MATH_RAND: {
  295. r_ret=Math::rand();
  296. } break;
  297. case MATH_RANDF: {
  298. r_ret=Math::randf();
  299. } break;
  300. case MATH_RANDOM: {
  301. VALIDATE_ARG_COUNT(2);
  302. VALIDATE_ARG_NUM(0);
  303. VALIDATE_ARG_NUM(1);
  304. r_ret=Math::random(*p_args[0],*p_args[1]);
  305. } break;
  306. case MATH_RANDSEED: {
  307. VALIDATE_ARG_COUNT(1);
  308. VALIDATE_ARG_NUM(0);
  309. uint32_t seed=*p_args[0];
  310. int ret = Math::rand_from_seed(&seed);
  311. Array reta;
  312. reta.push_back(ret);
  313. reta.push_back(seed);
  314. r_ret=reta;
  315. } break;
  316. case MATH_DEG2RAD: {
  317. VALIDATE_ARG_COUNT(1);
  318. VALIDATE_ARG_NUM(0);
  319. r_ret=Math::deg2rad(*p_args[0]);
  320. } break;
  321. case MATH_RAD2DEG: {
  322. VALIDATE_ARG_COUNT(1);
  323. VALIDATE_ARG_NUM(0);
  324. r_ret=Math::rad2deg(*p_args[0]);
  325. } break;
  326. case MATH_LINEAR2DB: {
  327. VALIDATE_ARG_COUNT(1);
  328. VALIDATE_ARG_NUM(0);
  329. r_ret=Math::linear2db(*p_args[0]);
  330. } break;
  331. case MATH_DB2LINEAR: {
  332. VALIDATE_ARG_COUNT(1);
  333. VALIDATE_ARG_NUM(0);
  334. r_ret=Math::db2linear(*p_args[0]);
  335. } break;
  336. case LOGIC_MAX: {
  337. VALIDATE_ARG_COUNT(2);
  338. if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) {
  339. int64_t a = *p_args[0];
  340. int64_t b = *p_args[1];
  341. r_ret=MAX(a,b);
  342. } else {
  343. VALIDATE_ARG_NUM(0);
  344. VALIDATE_ARG_NUM(1);
  345. real_t a = *p_args[0];
  346. real_t b = *p_args[1];
  347. r_ret=MAX(a,b);
  348. }
  349. } break;
  350. case LOGIC_MIN: {
  351. VALIDATE_ARG_COUNT(2);
  352. if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT) {
  353. int64_t a = *p_args[0];
  354. int64_t b = *p_args[1];
  355. r_ret=MIN(a,b);
  356. } else {
  357. VALIDATE_ARG_NUM(0);
  358. VALIDATE_ARG_NUM(1);
  359. real_t a = *p_args[0];
  360. real_t b = *p_args[1];
  361. r_ret=MIN(a,b);
  362. }
  363. } break;
  364. case LOGIC_CLAMP: {
  365. VALIDATE_ARG_COUNT(3);
  366. if (p_args[0]->get_type()==Variant::INT && p_args[1]->get_type()==Variant::INT && p_args[2]->get_type()==Variant::INT) {
  367. int64_t a = *p_args[0];
  368. int64_t b = *p_args[1];
  369. int64_t c = *p_args[2];
  370. r_ret=CLAMP(a,b,c);
  371. } else {
  372. VALIDATE_ARG_NUM(0);
  373. VALIDATE_ARG_NUM(1);
  374. VALIDATE_ARG_NUM(2);
  375. real_t a = *p_args[0];
  376. real_t b = *p_args[1];
  377. real_t c = *p_args[2];
  378. r_ret=CLAMP(a,b,c);
  379. }
  380. } break;
  381. case LOGIC_NEAREST_PO2: {
  382. VALIDATE_ARG_COUNT(1);
  383. VALIDATE_ARG_NUM(0);
  384. int64_t num = *p_args[0];
  385. r_ret = nearest_power_of_2(num);
  386. } break;
  387. case OBJ_WEAKREF: {
  388. VALIDATE_ARG_COUNT(1);
  389. if (p_args[0]->get_type()!=Variant::OBJECT) {
  390. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  391. r_error.argument=0;
  392. r_error.expected=Variant::OBJECT;
  393. return;
  394. }
  395. if (p_args[0]->is_ref()) {
  396. REF r = *p_args[0];
  397. if (!r.is_valid()) {
  398. r_ret=Variant();
  399. return;
  400. }
  401. Ref<WeakRef> wref = memnew( WeakRef );
  402. wref->set_ref(r);
  403. r_ret=wref;
  404. } else {
  405. Object *obj = *p_args[0];
  406. if (!obj) {
  407. r_ret=Variant();
  408. return;
  409. }
  410. Ref<WeakRef> wref = memnew( WeakRef );
  411. wref->set_obj(obj);
  412. r_ret=wref;
  413. }
  414. } break;
  415. case TYPE_CONVERT: {
  416. VALIDATE_ARG_COUNT(2);
  417. VALIDATE_ARG_NUM(1);
  418. int type=*p_args[1];
  419. if (type<0 || type>=Variant::VARIANT_MAX) {
  420. ERR_PRINT("Invalid type argument to convert()");
  421. r_ret=Variant::NIL;
  422. } else {
  423. r_ret=Variant::construct(Variant::Type(type),p_args,1,r_error);
  424. }
  425. } break;
  426. case TYPE_OF: {
  427. VALIDATE_ARG_COUNT(1);
  428. r_ret = p_args[0]->get_type();
  429. } break;
  430. case TEXT_STR: {
  431. String str;
  432. for(int i=0;i<p_arg_count;i++) {
  433. String os = p_args[i]->operator String();;
  434. if (i==0)
  435. str=os;
  436. else
  437. str+=os;
  438. }
  439. r_ret=str;
  440. } break;
  441. case TEXT_PRINT: {
  442. String str;
  443. for(int i=0;i<p_arg_count;i++) {
  444. str+=p_args[i]->operator String();
  445. }
  446. //str+="\n";
  447. print_line(str);
  448. r_ret=Variant();
  449. } break;
  450. case TEXT_PRINT_TABBED: {
  451. String str;
  452. for(int i=0;i<p_arg_count;i++) {
  453. if (i)
  454. str+="\t";
  455. str+=p_args[i]->operator String();
  456. }
  457. //str+="\n";
  458. print_line(str);
  459. r_ret=Variant();
  460. } break;
  461. case TEXT_PRINTERR: {
  462. String str;
  463. for(int i=0;i<p_arg_count;i++) {
  464. str+=p_args[i]->operator String();
  465. }
  466. //str+="\n";
  467. OS::get_singleton()->printerr("%s\n",str.utf8().get_data());
  468. r_ret=Variant();
  469. } break;
  470. case TEXT_PRINTRAW: {
  471. String str;
  472. for(int i=0;i<p_arg_count;i++) {
  473. str+=p_args[i]->operator String();
  474. }
  475. //str+="\n";
  476. OS::get_singleton()->print("%s\n",str.utf8().get_data());
  477. r_ret=Variant();
  478. } break;
  479. case GEN_RANGE: {
  480. switch(p_arg_count) {
  481. case 0: {
  482. r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
  483. r_error.argument=1;
  484. } break;
  485. case 1: {
  486. VALIDATE_ARG_NUM(0);
  487. int count=*p_args[0];
  488. Array arr(true);
  489. if (count<=0) {
  490. r_ret=arr;
  491. return;
  492. }
  493. Error err = arr.resize(count);
  494. if (err!=OK) {
  495. r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
  496. r_ret=Variant();
  497. return;
  498. }
  499. for(int i=0;i<count;i++) {
  500. arr[i]=i;
  501. }
  502. r_ret=arr;
  503. } break;
  504. case 2: {
  505. VALIDATE_ARG_NUM(0);
  506. VALIDATE_ARG_NUM(1);
  507. int from=*p_args[0];
  508. int to=*p_args[1];
  509. Array arr(true);
  510. if (from>=to) {
  511. r_ret=arr;
  512. return;
  513. }
  514. Error err = arr.resize(to-from);
  515. if (err!=OK) {
  516. r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
  517. r_ret=Variant();
  518. return;
  519. }
  520. for(int i=from;i<to;i++)
  521. arr[i-from]=i;
  522. r_ret=arr;
  523. } break;
  524. case 3: {
  525. VALIDATE_ARG_NUM(0);
  526. VALIDATE_ARG_NUM(1);
  527. VALIDATE_ARG_NUM(2);
  528. int from=*p_args[0];
  529. int to=*p_args[1];
  530. int incr=*p_args[2];
  531. if (incr==0) {
  532. ERR_EXPLAIN("step argument is zero!");
  533. r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
  534. ERR_FAIL();
  535. }
  536. Array arr(true);
  537. if (from>=to && incr>0) {
  538. r_ret=arr;
  539. return;
  540. }
  541. if (from<=to && incr<0) {
  542. r_ret=arr;
  543. return;
  544. }
  545. //calculate how many
  546. int count=0;
  547. if (incr>0) {
  548. count=((to-from-1)/incr)+1;
  549. } else {
  550. count=((from-to-1)/-incr)+1;
  551. }
  552. Error err = arr.resize(count);
  553. if (err!=OK) {
  554. r_error.error=Variant::CallError::CALL_ERROR_INVALID_METHOD;
  555. r_ret=Variant();
  556. return;
  557. }
  558. if (incr>0) {
  559. int idx=0;
  560. for(int i=from;i<to;i+=incr) {
  561. arr[idx++]=i;
  562. }
  563. } else {
  564. int idx=0;
  565. for(int i=from;i>to;i+=incr) {
  566. arr[idx++]=i;
  567. }
  568. }
  569. r_ret=arr;
  570. } break;
  571. default: {
  572. r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
  573. r_error.argument=3;
  574. } break;
  575. }
  576. } break;
  577. case RESOURCE_LOAD: {
  578. VALIDATE_ARG_COUNT(1);
  579. if (p_args[0]->get_type()!=Variant::STRING) {
  580. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  581. r_error.argument=0;
  582. r_ret=Variant();
  583. }
  584. r_ret=ResourceLoader::load(*p_args[0]);
  585. }
  586. case INST2DICT: {
  587. VALIDATE_ARG_COUNT(1);
  588. if (p_args[0]->get_type()==Variant::NIL) {
  589. r_ret=Variant();
  590. } else if (p_args[0]->get_type()!=Variant::OBJECT) {
  591. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  592. r_error.argument=0;
  593. r_ret=Variant();
  594. } else {
  595. Object *obj = *p_args[0];
  596. if (!obj) {
  597. r_ret=Variant();
  598. } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language()!=GDScriptLanguage::get_singleton()) {
  599. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  600. r_error.argument=0;
  601. r_error.expected=Variant::DICTIONARY;
  602. ERR_PRINT("Not a script with an instance");
  603. } else {
  604. GDInstance *ins = static_cast<GDInstance*>(obj->get_script_instance());
  605. Ref<GDScript> base = ins->get_script();
  606. if (base.is_null()) {
  607. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  608. r_error.argument=0;
  609. r_error.expected=Variant::DICTIONARY;
  610. ERR_PRINT("Not based on a script");
  611. return;
  612. }
  613. GDScript *p = base.ptr();
  614. Vector<StringName> sname;
  615. while(p->_owner) {
  616. sname.push_back(p->name);
  617. p=p->_owner;
  618. }
  619. sname.invert();
  620. if (!p->path.is_resource_file()) {
  621. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  622. r_error.argument=0;
  623. r_error.expected=Variant::DICTIONARY;
  624. print_line("PATH: "+p->path);
  625. ERR_PRINT("Not based on a resource file");
  626. return;
  627. }
  628. NodePath cp(sname,Vector<StringName>(),false);
  629. Dictionary d(true);
  630. d["@subpath"]=cp;
  631. d["@path"]=p->path;
  632. p = base.ptr();
  633. while(p) {
  634. for(Set<StringName>::Element *E=p->members.front();E;E=E->next()) {
  635. Variant value;
  636. if (ins->get(E->get(),value)) {
  637. String k = E->get();
  638. if (!d.has(k)) {
  639. d[k]=value;
  640. }
  641. }
  642. }
  643. p=p->_base;
  644. }
  645. r_ret=d;
  646. }
  647. }
  648. } break;
  649. case DICT2INST: {
  650. VALIDATE_ARG_COUNT(1);
  651. if (p_args[0]->get_type()!=Variant::DICTIONARY) {
  652. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  653. r_error.argument=0;
  654. r_error.expected=Variant::DICTIONARY;
  655. return;
  656. }
  657. Dictionary d = *p_args[0];
  658. if (!d.has("@path")) {
  659. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  660. r_error.argument=0;
  661. r_error.expected=Variant::OBJECT;
  662. return;
  663. }
  664. Ref<Script> scr = ResourceLoader::load(d["@path"]);
  665. if (!scr.is_valid()) {
  666. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  667. r_error.argument=0;
  668. r_error.expected=Variant::OBJECT;
  669. return;
  670. }
  671. Ref<GDScript> gdscr = scr;
  672. if (!gdscr.is_valid()) {
  673. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  674. r_error.argument=0;
  675. r_error.expected=Variant::OBJECT;
  676. return;
  677. }
  678. NodePath sub;
  679. if (d.has("@subpath")) {
  680. sub=d["@subpath"];
  681. }
  682. for(int i=0;i<sub.get_name_count();i++) {
  683. gdscr = gdscr->subclasses[ sub.get_name(i)];
  684. if (!gdscr.is_valid()) {
  685. r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
  686. r_error.argument=0;
  687. r_error.expected=Variant::OBJECT;
  688. return;
  689. }
  690. }
  691. r_ret = gdscr->_new(NULL,0,r_error);
  692. } break;
  693. case PRINT_STACK: {
  694. ScriptLanguage* script = GDScriptLanguage::get_singleton();
  695. for (int i=0; i < script->debug_get_stack_level_count(); i++) {
  696. print_line("Frame "+itos(i)+" - "+script->debug_get_stack_level_source(i)+":"+itos(script->debug_get_stack_level_line(i))+" in function '"+script->debug_get_stack_level_function(i)+"'");
  697. };
  698. } break;
  699. case FUNC_MAX: {
  700. ERR_FAIL_V();
  701. } break;
  702. }
  703. }
  704. bool GDFunctions::is_deterministic(Function p_func) {
  705. //man i couldn't have chosen a worse function name,
  706. //way too controversial..
  707. switch(p_func) {
  708. case MATH_SIN:
  709. case MATH_COS:
  710. case MATH_TAN:
  711. case MATH_SINH:
  712. case MATH_COSH:
  713. case MATH_TANH:
  714. case MATH_ASIN:
  715. case MATH_ACOS:
  716. case MATH_ATAN:
  717. case MATH_ATAN2:
  718. case MATH_SQRT:
  719. case MATH_FMOD:
  720. case MATH_FPOSMOD:
  721. case MATH_FLOOR:
  722. case MATH_CEIL:
  723. case MATH_ROUND:
  724. case MATH_ABS:
  725. case MATH_SIGN:
  726. case MATH_POW:
  727. case MATH_LOG:
  728. case MATH_EXP:
  729. case MATH_ISNAN:
  730. case MATH_ISINF:
  731. case MATH_EASE:
  732. case MATH_DECIMALS:
  733. case MATH_STEPIFY:
  734. case MATH_LERP:
  735. case MATH_DECTIME:
  736. case MATH_DEG2RAD:
  737. case MATH_RAD2DEG:
  738. case MATH_LINEAR2DB:
  739. case MATH_DB2LINEAR:
  740. case LOGIC_MAX:
  741. case LOGIC_MIN:
  742. case LOGIC_CLAMP:
  743. case LOGIC_NEAREST_PO2:
  744. case TYPE_CONVERT:
  745. case TYPE_OF:
  746. case TEXT_STR:
  747. // enable for debug only, otherwise not desirable - case GEN_RANGE:
  748. return true;
  749. default:
  750. return false;
  751. }
  752. return false;
  753. }
  754. MethodInfo GDFunctions::get_info(Function p_func) {
  755. #ifdef TOOLS_ENABLED
  756. //using a switch, so the compiler generates a jumptable
  757. switch(p_func) {
  758. case MATH_SIN: {
  759. MethodInfo mi("sin",PropertyInfo(Variant::REAL,"s"));
  760. mi.return_val.type=Variant::REAL;
  761. return mi;
  762. } break;
  763. case MATH_COS: {
  764. MethodInfo mi("cos",PropertyInfo(Variant::REAL,"s"));
  765. mi.return_val.type=Variant::REAL;
  766. return mi;
  767. } break;
  768. case MATH_TAN: {
  769. MethodInfo mi("tan",PropertyInfo(Variant::REAL,"s"));
  770. mi.return_val.type=Variant::REAL;
  771. return mi;
  772. } break;
  773. case MATH_SINH: {
  774. MethodInfo mi("sinh",PropertyInfo(Variant::REAL,"s"));
  775. mi.return_val.type=Variant::REAL;
  776. return mi;
  777. } break;
  778. case MATH_COSH: {
  779. MethodInfo mi("cosh",PropertyInfo(Variant::REAL,"s"));
  780. mi.return_val.type=Variant::REAL;
  781. return mi;
  782. } break;
  783. case MATH_TANH: {
  784. MethodInfo mi("tanh",PropertyInfo(Variant::REAL,"s"));
  785. mi.return_val.type=Variant::REAL;
  786. return mi;
  787. } break;
  788. case MATH_ASIN: {
  789. MethodInfo mi("asin",PropertyInfo(Variant::REAL,"s"));
  790. mi.return_val.type=Variant::REAL;
  791. return mi;
  792. } break;
  793. case MATH_ACOS: {
  794. MethodInfo mi("acos",PropertyInfo(Variant::REAL,"s"));
  795. mi.return_val.type=Variant::REAL;
  796. return mi;
  797. } break;
  798. case MATH_ATAN: {
  799. MethodInfo mi("atan",PropertyInfo(Variant::REAL,"s"));
  800. mi.return_val.type=Variant::REAL;
  801. return mi;
  802. } break;
  803. case MATH_ATAN2: {
  804. MethodInfo mi("atan2",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y"));
  805. mi.return_val.type=Variant::REAL;
  806. return mi;
  807. } break;
  808. case MATH_SQRT: {
  809. MethodInfo mi("sqrt",PropertyInfo(Variant::REAL,"s"));
  810. mi.return_val.type=Variant::REAL;
  811. return mi;
  812. } break;
  813. case MATH_FMOD: {
  814. MethodInfo mi("fmod",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y"));
  815. mi.return_val.type=Variant::REAL;
  816. return mi;
  817. } break;
  818. case MATH_FPOSMOD: {
  819. MethodInfo mi("fposmod",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y"));
  820. mi.return_val.type=Variant::REAL;
  821. return mi;
  822. } break;
  823. case MATH_FLOOR: {
  824. MethodInfo mi("floor",PropertyInfo(Variant::REAL,"s"));
  825. mi.return_val.type=Variant::REAL;
  826. return mi;
  827. } break;
  828. case MATH_CEIL: {
  829. MethodInfo mi("ceil",PropertyInfo(Variant::REAL,"s"));
  830. mi.return_val.type=Variant::REAL;
  831. return mi;
  832. } break;
  833. case MATH_ROUND: {
  834. MethodInfo mi("round",PropertyInfo(Variant::REAL,"s"));
  835. mi.return_val.type=Variant::REAL;
  836. return mi;
  837. } break;
  838. case MATH_ABS: {
  839. MethodInfo mi("abs",PropertyInfo(Variant::REAL,"s"));
  840. mi.return_val.type=Variant::REAL;
  841. return mi;
  842. } break;
  843. case MATH_SIGN: {
  844. MethodInfo mi("sign",PropertyInfo(Variant::REAL,"s"));
  845. mi.return_val.type=Variant::REAL;
  846. return mi;
  847. } break;
  848. case MATH_POW: {
  849. MethodInfo mi("pow",PropertyInfo(Variant::REAL,"x"),PropertyInfo(Variant::REAL,"y"));
  850. mi.return_val.type=Variant::REAL;
  851. return mi;
  852. } break;
  853. case MATH_LOG: {
  854. MethodInfo mi("log",PropertyInfo(Variant::REAL,"s"));
  855. mi.return_val.type=Variant::REAL;
  856. return mi;
  857. } break;
  858. case MATH_EXP: {
  859. MethodInfo mi("exp",PropertyInfo(Variant::REAL,"s"));
  860. mi.return_val.type=Variant::REAL;
  861. return mi;
  862. } break;
  863. case MATH_ISNAN: {
  864. MethodInfo mi("isnan",PropertyInfo(Variant::REAL,"s"));
  865. mi.return_val.type=Variant::REAL;
  866. return mi;
  867. } break;
  868. case MATH_ISINF: {
  869. MethodInfo mi("isinf",PropertyInfo(Variant::REAL,"s"));
  870. mi.return_val.type=Variant::REAL;
  871. return mi;
  872. } break;
  873. case MATH_EASE: {
  874. MethodInfo mi("ease",PropertyInfo(Variant::REAL,"s"),PropertyInfo(Variant::REAL,"curve"));
  875. mi.return_val.type=Variant::REAL;
  876. return mi;
  877. } break;
  878. case MATH_DECIMALS: {
  879. MethodInfo mi("decimals",PropertyInfo(Variant::REAL,"step"));
  880. mi.return_val.type=Variant::REAL;
  881. return mi;
  882. } break;
  883. case MATH_STEPIFY: {
  884. MethodInfo mi("stepify",PropertyInfo(Variant::REAL,"s"),PropertyInfo(Variant::REAL,"step"));
  885. mi.return_val.type=Variant::REAL;
  886. return mi;
  887. } break;
  888. case MATH_LERP: {
  889. MethodInfo mi("lerp",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b"), PropertyInfo(Variant::REAL,"c"));
  890. mi.return_val.type=Variant::REAL;
  891. return mi;
  892. } break;
  893. case MATH_DECTIME: {
  894. MethodInfo mi("dectime",PropertyInfo(Variant::REAL,"value"),PropertyInfo(Variant::REAL,"amount"),PropertyInfo(Variant::REAL,"step"));
  895. mi.return_val.type=Variant::REAL;
  896. return mi;
  897. } break;
  898. case MATH_RANDOMIZE: {
  899. MethodInfo mi("randomize");
  900. mi.return_val.type=Variant::NIL;
  901. return mi;
  902. } break;
  903. case MATH_RAND: {
  904. MethodInfo mi("rand");
  905. mi.return_val.type=Variant::INT;
  906. return mi;
  907. } break;
  908. case MATH_RANDF: {
  909. MethodInfo mi("randf");
  910. mi.return_val.type=Variant::REAL;
  911. return mi;
  912. } break;
  913. case MATH_RANDOM: {
  914. MethodInfo mi("rand_range",PropertyInfo(Variant::REAL,"from"),PropertyInfo(Variant::REAL,"to"));
  915. mi.return_val.type=Variant::REAL;
  916. return mi;
  917. } break;
  918. case MATH_RANDSEED: {
  919. MethodInfo mi("rand_seed",PropertyInfo(Variant::REAL,"seed"));
  920. mi.return_val.type=Variant::ARRAY;
  921. return mi;
  922. } break;
  923. case MATH_DEG2RAD: {
  924. MethodInfo mi("deg2rad",PropertyInfo(Variant::REAL,"deg"));
  925. mi.return_val.type=Variant::REAL;
  926. return mi;
  927. } break;
  928. case MATH_RAD2DEG: {
  929. MethodInfo mi("rad2deg",PropertyInfo(Variant::REAL,"rad"));
  930. mi.return_val.type=Variant::REAL;
  931. return mi;
  932. } break;
  933. case MATH_LINEAR2DB: {
  934. MethodInfo mi("linear2db",PropertyInfo(Variant::REAL,"nrg"));
  935. mi.return_val.type=Variant::REAL;
  936. return mi;
  937. } break;
  938. case MATH_DB2LINEAR: {
  939. MethodInfo mi("db2linear",PropertyInfo(Variant::REAL,"db"));
  940. mi.return_val.type=Variant::REAL;
  941. return mi;
  942. } break;
  943. case LOGIC_MAX: {
  944. MethodInfo mi("max",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b"));
  945. mi.return_val.type=Variant::REAL;
  946. return mi;
  947. } break;
  948. case LOGIC_MIN: {
  949. MethodInfo mi("min",PropertyInfo(Variant::REAL,"a"),PropertyInfo(Variant::REAL,"b"));
  950. mi.return_val.type=Variant::REAL;
  951. return mi;
  952. } break;
  953. case LOGIC_CLAMP: {
  954. MethodInfo mi("clamp",PropertyInfo(Variant::REAL,"val"),PropertyInfo(Variant::REAL,"min"),PropertyInfo(Variant::REAL,"max"));
  955. mi.return_val.type=Variant::REAL;
  956. return mi;
  957. } break;
  958. case LOGIC_NEAREST_PO2: {
  959. MethodInfo mi("nearest_po2",PropertyInfo(Variant::INT,"val"));
  960. mi.return_val.type=Variant::INT;
  961. return mi;
  962. } break;
  963. case OBJ_WEAKREF: {
  964. MethodInfo mi("weakref",PropertyInfo(Variant::OBJECT,"obj"));
  965. mi.return_val.type=Variant::OBJECT;
  966. return mi;
  967. } break;
  968. case TYPE_CONVERT: {
  969. MethodInfo mi("convert",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::INT,"type"));
  970. mi.return_val.type=Variant::OBJECT;
  971. return mi;
  972. } break;
  973. case TYPE_OF: {
  974. MethodInfo mi("typeof",PropertyInfo(Variant::NIL,"what"));
  975. mi.return_val.type=Variant::INT;
  976. };
  977. case TEXT_STR: {
  978. MethodInfo mi("str",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
  979. mi.return_val.type=Variant::STRING;
  980. return mi;
  981. } break;
  982. case TEXT_PRINT: {
  983. MethodInfo mi("print",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
  984. mi.return_val.type=Variant::NIL;
  985. return mi;
  986. } break;
  987. case TEXT_PRINT_TABBED: {
  988. MethodInfo mi("printt",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
  989. mi.return_val.type=Variant::NIL;
  990. return mi;
  991. } break;
  992. case TEXT_PRINTERR: {
  993. MethodInfo mi("printerr",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
  994. mi.return_val.type=Variant::NIL;
  995. return mi;
  996. } break;
  997. case TEXT_PRINTRAW: {
  998. MethodInfo mi("printraw",PropertyInfo(Variant::NIL,"what"),PropertyInfo(Variant::NIL,"..."));
  999. mi.return_val.type=Variant::NIL;
  1000. return mi;
  1001. } break;
  1002. case GEN_RANGE: {
  1003. MethodInfo mi("range",PropertyInfo(Variant::NIL,"..."));
  1004. mi.return_val.type=Variant::ARRAY;
  1005. return mi;
  1006. } break;
  1007. case RESOURCE_LOAD: {
  1008. MethodInfo mi("load",PropertyInfo(Variant::STRING,"path"));
  1009. mi.return_val.type=Variant::OBJECT;
  1010. return mi;
  1011. } break;
  1012. case INST2DICT: {
  1013. MethodInfo mi("inst2dict",PropertyInfo(Variant::OBJECT,"inst"));
  1014. mi.return_val.type=Variant::DICTIONARY;
  1015. return mi;
  1016. } break;
  1017. case DICT2INST: {
  1018. MethodInfo mi("dict2inst",PropertyInfo(Variant::DICTIONARY,"dict"));
  1019. mi.return_val.type=Variant::OBJECT;
  1020. return mi;
  1021. } break;
  1022. case PRINT_STACK: {
  1023. MethodInfo mi("print_stack");
  1024. mi.return_val.type=Variant::NIL;
  1025. return mi;
  1026. } break;
  1027. case FUNC_MAX: {
  1028. ERR_FAIL_V(MethodInfo());
  1029. } break;
  1030. }
  1031. #endif
  1032. return MethodInfo();
  1033. }