jsb_node.cpp 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596
  1. /****************************************************************************
  2. Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
  3. http://www.cocos.com
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated engine source code (the "Software"), a limited,
  6. worldwide, royalty-free, non-assignable, revocable and non-exclusive license
  7. to use Cocos Creator solely to develop games on your target platforms. You shall
  8. not use Cocos Creator software for developing other software or tools that's
  9. used for developing games. You are not granted to publish, distribute,
  10. sublicense, and/or sell copies of Cocos Creator.
  11. The software or tools in this License Agreement are licensed, not sold.
  12. Xiamen Yaji Software Co., Ltd. reserves all rights not expressly granted to you.
  13. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. THE SOFTWARE.
  20. ****************************************************************************/
  21. //
  22. // jsb_node.cpp
  23. // cocos2d_js_bindings
  24. //
  25. // Created by James Chen on 4/26/17.
  26. //
  27. //
  28. #include "jsb_node.hpp"
  29. #include "jsb_global.h"
  30. #include "jsb_conversions.hpp"
  31. #include "ScriptingCore.h"
  32. #include "cocos2d.h"
  33. using namespace cocos2d;
  34. #define STANDALONE_TEST 0
  35. extern se::Object* __jsb_cocos2d_Node_proto;
  36. extern se::Class* __jsb_cocos2d__Node_class;
  37. extern se::Object* __jsb_cocos2d_Scheduler_proto;
  38. se::Object* __jsb_Node_proto = nullptr;
  39. se::Class* __jsb_Node_class = nullptr;
  40. static bool Node_finalized(se::State& s)
  41. {
  42. if (s.nativeThisObject())
  43. {
  44. Node* thiz = (Node*) s.nativeThisObject();
  45. SE_LOGD("Node_finalized %p ...\n", thiz->getUserData());
  46. CC_SAFE_RELEASE(thiz);
  47. }
  48. return true;
  49. }
  50. SE_BIND_FINALIZE_FUNC(Node_finalized)
  51. static bool Node_constructor(se::State& s)
  52. {
  53. SE_LOGD("Node_constructor ...\n");
  54. Node* obj = new Node();
  55. s.thisObject()->setPrivateData(obj);
  56. return true;
  57. }
  58. SE_BIND_CTOR(Node_constructor, __jsb_Node_class, Node_finalized)
  59. static bool Node_ctor(se::State& s)
  60. {
  61. SE_LOGD("Node_ctor ...\n");
  62. Node* obj = new Node();
  63. s.thisObject()->setPrivateData(obj);
  64. return true;
  65. }
  66. SE_BIND_SUB_CLS_CTOR(Node_ctor, __jsb_Node_class, Node_finalized)
  67. static bool Node_create(se::State& s)
  68. {
  69. Node* node = Node::create();
  70. node->retain();
  71. auto obj = se::Object::createObjectWithClass(__jsb_Node_class);
  72. obj->setPrivateData(node);
  73. s.rval().setObject(obj);
  74. return true;
  75. }
  76. SE_BIND_FUNC(Node_create)
  77. static bool Node_onEnter(se::State& s)
  78. {
  79. ScriptingCore::getInstance()->setCalledFromScript(true);
  80. Node* thiz = (Node*)s.nativeThisObject();
  81. thiz->onEnter();
  82. return true;
  83. }
  84. SE_BIND_FUNC(Node_onEnter)
  85. static bool Node_onExit(se::State& s)
  86. {
  87. ScriptingCore::getInstance()->setCalledFromScript(true);
  88. Node* thiz = (Node*)s.nativeThisObject();
  89. thiz->onExit();
  90. return true;
  91. }
  92. SE_BIND_FUNC(Node_onExit)
  93. static bool Node_onEnterTransitionDidFinish(se::State& s)
  94. {
  95. ScriptingCore::getInstance()->setCalledFromScript(true);
  96. Node* thiz = (Node*)s.nativeThisObject();
  97. thiz->onEnterTransitionDidFinish();
  98. return true;
  99. }
  100. SE_BIND_FUNC(Node_onEnterTransitionDidFinish)
  101. static bool Node_onExitTransitionDidStart(se::State& s)
  102. {
  103. ScriptingCore::getInstance()->setCalledFromScript(true);
  104. Node* thiz = (Node*)s.nativeThisObject();
  105. thiz->onExitTransitionDidStart();
  106. return true;
  107. }
  108. SE_BIND_FUNC(Node_onExitTransitionDidStart)
  109. static bool Node_cleanup(se::State& s)
  110. {
  111. ScriptingCore::getInstance()->setCalledFromScript(true);
  112. Node* thiz = (Node*)s.nativeThisObject();
  113. thiz->cleanup();
  114. return true;
  115. }
  116. SE_BIND_FUNC(Node_cleanup)
  117. static bool Node_addChild(se::State& s)
  118. {
  119. const auto& args = s.args();
  120. Node* thiz = (Node*)s.nativeThisObject();
  121. Node* child = (Node*)args[0].toObject()->getPrivateData();
  122. thiz->addChild(child);
  123. return true;
  124. }
  125. SE_BIND_FUNC(Node_addChild)
  126. class ScheduleElement
  127. {
  128. public:
  129. ScheduleElement(se::Object* target, se::Object* func, const std::string& key, uint32_t targetId, uint32_t funcId)
  130. : _target(target)
  131. , _func(func)
  132. , _key(key)
  133. , _targetId(targetId)
  134. , _funcId(funcId)
  135. {}
  136. ScheduleElement(ScheduleElement&& o)
  137. {
  138. *this = std::move(o);
  139. }
  140. ScheduleElement* operator=(ScheduleElement&& o)
  141. {
  142. if (this != &o)
  143. {
  144. _target = o._target;
  145. _func = o._func;
  146. _key = std::move(o._key);
  147. _targetId = o._targetId;
  148. _funcId = o._funcId;
  149. }
  150. return this;
  151. }
  152. inline se::Object* getTarget() const { return _target; }
  153. inline se::Object* getFunc() const { return _func; }
  154. inline const std::string& getKey() const { return _key; }
  155. inline uint32_t getTargetId() const { return _targetId; }
  156. inline uint32_t getFuncId() const { return _funcId; }
  157. private:
  158. ScheduleElement(const ScheduleElement& o) { assert(false); }
  159. ScheduleElement* operator=(const ScheduleElement& o) { assert(false); return this; }
  160. se::Object* _target;
  161. se::Object* _func;
  162. std::string _key;
  163. uint32_t _targetId;
  164. uint32_t _funcId;
  165. };
  166. static uint32_t __scheduleTargetIdCounter = 0;
  167. static uint32_t __scheduleFuncIdCounter = 0;
  168. static const char* SCHEDULE_TARGET_ID_KEY = "__seScheTargetId";
  169. static const char* SCHEDULE_FUNC_ID_KEY = "__seScheFuncId";
  170. static std::unordered_map<uint32_t/*targetId*/, std::unordered_map<uint32_t/*funcId*/, ScheduleElement>> __js_target_schedulekey_map;
  171. static std::unordered_map<uint32_t/*targetId*/, std::pair<int/*priority*/, se::Object*>> __js_target_schedule_update_map;
  172. static bool isScheduleExist(uint32_t jsFuncId, uint32_t jsTargetId, const ScheduleElement** outElement)
  173. {
  174. bool found = false;
  175. for (const auto& e : __js_target_schedulekey_map)
  176. {
  177. if (e.first == jsTargetId)
  178. {
  179. for (const auto& e2 : e.second)
  180. {
  181. if (e2.first == jsFuncId)
  182. {
  183. *outElement = &e2.second;
  184. found = true;
  185. break;
  186. }
  187. }
  188. }
  189. if (found)
  190. {
  191. break;
  192. }
  193. }
  194. if (!found)
  195. {
  196. *outElement = nullptr;
  197. }
  198. return found;
  199. }
  200. static bool isScheduleExist(const std::string& key, uint32_t jsTargetId, const ScheduleElement** outElement)
  201. {
  202. bool found = false;
  203. for (const auto& e : __js_target_schedulekey_map)
  204. {
  205. if (e.first == jsTargetId)
  206. {
  207. for (const auto& e2 : e.second)
  208. {
  209. if (e2.second.getKey() == key)
  210. {
  211. *outElement = &e2.second;
  212. found = true;
  213. break;
  214. }
  215. }
  216. }
  217. if (found)
  218. break;
  219. }
  220. if (!found)
  221. {
  222. *outElement = nullptr;
  223. }
  224. return found;
  225. }
  226. static void removeSchedule(uint32_t jsFuncId, uint32_t jsTargetId, bool needDetachChild)
  227. {
  228. auto funcObjKeyMapIter = __js_target_schedulekey_map.find(jsTargetId);
  229. if (funcObjKeyMapIter != __js_target_schedulekey_map.end())
  230. {
  231. auto& funcMap = funcObjKeyMapIter->second;
  232. auto iter = funcMap.find(jsFuncId);
  233. if (iter != funcMap.end())
  234. {
  235. se::Object* target = iter->second.getTarget();
  236. se::Object* func = iter->second.getFunc();
  237. if (needDetachChild)
  238. {
  239. target->detachObject(func);
  240. }
  241. func->decRef();
  242. target->decRef();
  243. funcMap.erase(iter);
  244. }
  245. if (funcMap.empty())
  246. {
  247. __js_target_schedulekey_map.erase(funcObjKeyMapIter);
  248. }
  249. }
  250. }
  251. static void removeScheduleForThis(uint32_t jsTargetId, bool needDetachChild)
  252. {
  253. auto funcObjKeyMapIter = __js_target_schedulekey_map.find(jsTargetId);
  254. if (funcObjKeyMapIter != __js_target_schedulekey_map.end())
  255. {
  256. auto& funcMap = funcObjKeyMapIter->second;
  257. se::Object* target = nullptr;
  258. se::Object* func = nullptr;
  259. for (auto& e : funcMap)
  260. {
  261. target = e.second.getTarget();
  262. func = e.second.getFunc();
  263. if (needDetachChild)
  264. {
  265. target->detachObject(func);
  266. }
  267. func->decRef(); // Release jsFunc
  268. target->decRef(); // Release jsThis
  269. }
  270. funcMap.clear();
  271. __js_target_schedulekey_map.erase(funcObjKeyMapIter);
  272. }
  273. }
  274. static void removeAllSchedules(bool needDetachChild)
  275. {
  276. CCLOG("Begin unschedule all callbacks");
  277. for (auto& e1 :__js_target_schedulekey_map)
  278. {
  279. auto& funcMap = e1.second;
  280. CCLOG(">> Found funcMap: %d", (int)funcMap.size());
  281. se::Object* target = nullptr;
  282. se::Object* func = nullptr;
  283. for (auto& e : funcMap)
  284. {
  285. target = e.second.getTarget();
  286. func = e.second.getFunc();
  287. if (needDetachChild)
  288. {
  289. CCLOG("detachObject: owner: %p, target: %p", target, func);
  290. target->detachObject(func);
  291. }
  292. target->decRef(); // Release jsThis
  293. func->decRef(); // Release jsFunc
  294. }
  295. funcMap.clear();
  296. }
  297. __js_target_schedulekey_map.clear();
  298. }
  299. static void removeAllScheduleUpdates()
  300. {
  301. for (auto& e2 : __js_target_schedule_update_map)
  302. {
  303. e2.second.second->decRef();
  304. }
  305. __js_target_schedule_update_map.clear();
  306. }
  307. static void removeAllScheduleAndUpdate(bool needDetachChild)
  308. {
  309. removeAllSchedules(needDetachChild);
  310. removeAllScheduleUpdates();
  311. }
  312. static bool isScheduleUpdateExist(uint32_t targetId)
  313. {
  314. for (const auto& e : __js_target_schedule_update_map)
  315. {
  316. if (e.first == targetId)
  317. {
  318. return true;
  319. }
  320. }
  321. return false;
  322. }
  323. static void removeScheduleUpdate(uint32_t targetId)
  324. {
  325. auto iter = __js_target_schedule_update_map.find(targetId);
  326. if (iter != __js_target_schedule_update_map.end())
  327. {
  328. iter->second.second->decRef();
  329. __js_target_schedule_update_map.erase(iter);
  330. }
  331. }
  332. static void removeScheduleUpdatesForMinPriority(int minPriority)
  333. {
  334. int foundPriority = 0;
  335. auto iter = __js_target_schedule_update_map.begin();
  336. while (iter != __js_target_schedule_update_map.end())
  337. {
  338. foundPriority = iter->second.first;
  339. if (foundPriority >= minPriority)
  340. {
  341. iter->second.second->decRef();
  342. iter = __js_target_schedule_update_map.erase(iter);
  343. }
  344. else
  345. {
  346. ++iter;
  347. }
  348. }
  349. }
  350. static void insertScheduleUpdate(uint32_t targetId, int priority, se::Object* targetObj)
  351. {
  352. assert(__js_target_schedule_update_map.find(targetId) == __js_target_schedule_update_map.end());
  353. __js_target_schedule_update_map[targetId] = std::make_pair(priority, targetObj);
  354. targetObj->incRef();
  355. }
  356. static void insertSchedule(uint32_t funcId, uint32_t targetId, ScheduleElement&& element)
  357. {
  358. auto& funcKeyMap = __js_target_schedulekey_map[targetId];
  359. assert(funcKeyMap.find(funcId) == funcKeyMap.end());
  360. element.getTarget()->incRef();
  361. element.getFunc()->incRef();
  362. funcKeyMap.emplace(funcId, std::move(element));
  363. }
  364. static bool isTargetExistInScheduler(uint32_t targetId)
  365. {
  366. assert(targetId != 0);
  367. // Iterating the schedule func map
  368. for (const auto& e : __js_target_schedulekey_map)
  369. {
  370. if (e.first == targetId)
  371. {
  372. return true;
  373. }
  374. }
  375. // Iterating the schedule update map
  376. for (const auto& e : __js_target_schedule_update_map)
  377. {
  378. if (e.first == targetId)
  379. {
  380. return true;
  381. }
  382. }
  383. return false;
  384. }
  385. class UnscheduleNotifier
  386. {
  387. public:
  388. UnscheduleNotifier(uint32_t funcId, uint32_t targetId)
  389. : _funcId(funcId)
  390. , _targetId(targetId)
  391. {
  392. }
  393. ~UnscheduleNotifier()
  394. {
  395. // SE_LOGD("~UnscheduleNotifier, targetId: %u, funcId: %u\n", _targetId, _funcId);
  396. se::ScriptEngine::getInstance()->clearException();
  397. se::AutoHandleScope hs;
  398. removeSchedule(_funcId, _targetId, false);
  399. }
  400. private:
  401. uint32_t _funcId;
  402. uint32_t _targetId;
  403. };
  404. static uint32_t __idx = 0;
  405. static bool Scheduler_scheduleCommon(Scheduler* scheduler, const se::Value& jsThis, const se::Value& jsFunc, float interval, unsigned int repeat, float delay, bool isPaused, bool toRootTarget, const std::string& callFromDebug)
  406. {
  407. assert(jsThis.isObject());
  408. assert(jsFunc.isObject());
  409. assert(jsFunc.toObject()->isFunction());
  410. jsThis.toObject()->attachObject(jsFunc.toObject());
  411. std::string key;
  412. se::Value targetIdVal;
  413. se::Value funcIdVal;
  414. uint32_t targetId = 0;
  415. uint32_t funcId = 0;
  416. if (jsThis.toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) && targetIdVal.isNumber())
  417. {
  418. targetId = targetIdVal.toUint32();
  419. }
  420. if (jsFunc.toObject()->getProperty(SCHEDULE_FUNC_ID_KEY, &funcIdVal) && funcIdVal.isNumber())
  421. {
  422. funcId = funcIdVal.toUint32();
  423. }
  424. if (targetIdVal.isNumber() && funcIdVal.isNumber())
  425. {
  426. const ScheduleElement* scheduleElem = nullptr;
  427. bool found = isScheduleExist(funcId, targetId, &scheduleElem);
  428. if (found)
  429. key = scheduleElem->getKey();
  430. if (found && !key.empty())
  431. {
  432. removeSchedule(funcId, targetId, true);
  433. scheduler->unschedule(key, reinterpret_cast<void*>(targetId));
  434. }
  435. }
  436. else
  437. {
  438. if (targetId == 0)
  439. {
  440. targetId = ++__scheduleTargetIdCounter;
  441. // counter is probably overfollow, it maybe 0 which is invalid id. Increase 1.
  442. if (targetId == 0)
  443. {
  444. targetId = ++__scheduleTargetIdCounter;
  445. }
  446. jsThis.toObject()->setProperty(SCHEDULE_TARGET_ID_KEY, se::Value(targetId));
  447. }
  448. if (funcId == 0)
  449. {
  450. funcId = ++__scheduleFuncIdCounter;
  451. // counter is probably overfollow, it maybe 0 which is invalid id. Increase 1.
  452. if (funcId == 0)
  453. {
  454. funcId = ++__scheduleFuncIdCounter;
  455. }
  456. jsFunc.toObject()->setProperty(SCHEDULE_FUNC_ID_KEY, se::Value(funcId));
  457. }
  458. }
  459. key = StringUtils::format("__node_schedule_key:%u", __idx++);
  460. se::Object* target = jsThis.toObject();
  461. insertSchedule(funcId, targetId, ScheduleElement(target, jsFunc.toObject(), key, targetId, funcId));
  462. std::shared_ptr<UnscheduleNotifier> unscheduleNotifier = std::make_shared<UnscheduleNotifier>(funcId, targetId);
  463. if (toRootTarget)
  464. {
  465. target->root();
  466. }
  467. scheduler->schedule([jsThis, jsFunc, unscheduleNotifier, callFromDebug](float dt){
  468. se::ScriptEngine::getInstance()->clearException();
  469. se::AutoHandleScope hs;
  470. se::Object* thisObj = jsThis.toObject();
  471. se::Object* funcObj = jsFunc.toObject();
  472. se::ValueArray args;
  473. args.push_back(se::Value((double)dt));
  474. bool ok = funcObj->call(args, thisObj);
  475. if (!ok)
  476. {
  477. CCLOGERROR("Invoking schedule callback failed, where: %s", callFromDebug.c_str());
  478. }
  479. }, reinterpret_cast<void*>(targetId), interval, repeat, delay, isPaused, key);
  480. return true;
  481. }
  482. static bool Node_schedule(se::State& s)
  483. {
  484. const auto& args = s.args();
  485. int argc = (int)args.size();
  486. #if 0//COCOS2D_DEBUG > 0
  487. SE_LOGD("--------------------------\nschedule target count: %d\n", (int)__js_target_schedulekey_map.size());
  488. int totalCount = 0;
  489. for (const auto& e1 : __js_target_schedulekey_map)
  490. {
  491. SE_LOGD("schedule target: %p, functions: %d\n", e1.first, (int)e1.second.size());
  492. totalCount += (int)e1.second.size();
  493. }
  494. SE_LOGD("total: %d-------------------------- \n", totalCount);
  495. #endif
  496. if (argc >= 1)
  497. {
  498. Node* thiz = (Node*)s.nativeThisObject();
  499. se::Value jsThis(s.thisObject());
  500. se::Value jsFunc(args[0]);
  501. float interval = 0.0f;
  502. unsigned int repeat = CC_REPEAT_FOREVER;
  503. float delay = 0.0f;
  504. bool ok = false;
  505. if (argc >= 2)
  506. {
  507. ok = seval_to_float(args[1], &interval);
  508. SE_PRECONDITION2(ok, false, "Converting 'interval' argument failed");
  509. }
  510. if (argc >= 3)
  511. {
  512. ok = seval_to_uint32(args[2], &repeat);
  513. SE_PRECONDITION2(ok, false, "Converting 'interval' argument failed");
  514. }
  515. if (argc >= 4)
  516. {
  517. ok = seval_to_float(args[3], &delay);
  518. SE_PRECONDITION2(ok, false, "Converting 'delay' argument failed");
  519. }
  520. return Scheduler_scheduleCommon(thiz->getScheduler(), jsThis, jsFunc, interval, repeat, delay, !thiz->isRunning(), false, "cc.Node.schedule");
  521. }
  522. SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, ">=1");
  523. return false;
  524. }
  525. SE_BIND_FUNC(Node_schedule)
  526. static bool Node_scheduleOnce(se::State& s)
  527. {
  528. const auto& args = s.args();
  529. size_t argc = args.size();
  530. #if 0//COCOS2D_DEBUG > 0
  531. SE_LOGD("--------------------------\nschedule target count: %d\n", (int)__js_target_schedulekey_map.size());
  532. for (const auto& e1 : __js_target_schedulekey_map)
  533. {
  534. SE_LOGD("schedule target: %p, functions: %d\n", e1.first, (int)e1.second.size());
  535. }
  536. SE_LOGD("-------------------------- \n");
  537. #endif
  538. Node* thiz = (Node*)s.nativeThisObject();
  539. se::Value jsThis(s.thisObject());
  540. se::Value jsFunc(args[0]);
  541. float delay = 0.0f;
  542. bool ok = false;
  543. if (argc >= 2)
  544. {
  545. ok = seval_to_float(args[1], &delay);
  546. SE_PRECONDITION2(ok, false, "Converting 'delay' argument failed");
  547. }
  548. return Scheduler_scheduleCommon(thiz->getScheduler(), jsThis, jsFunc, 0.0f, 0, delay, !thiz->isRunning(), false, "cc.Node.scheduleOnce");
  549. }
  550. SE_BIND_FUNC(Node_scheduleOnce)
  551. class UnscheduleUpdateNotifier
  552. {
  553. public:
  554. UnscheduleUpdateNotifier(uint32_t targetId)
  555. : _targetId(targetId)
  556. {
  557. }
  558. ~UnscheduleUpdateNotifier()
  559. {
  560. // SE_LOGD("~UnscheduleUpdateNotifier: %p\n", _target);
  561. removeScheduleUpdate(_targetId);
  562. }
  563. private:
  564. uint32_t _targetId;
  565. };
  566. static bool Scheduler_unscheduleUpdateCommon(Scheduler* scheduler, se::Object* jsTarget, uint32_t* foundTargetId = nullptr)
  567. {
  568. assert(jsTarget != nullptr);
  569. se::Value targetIdVal;
  570. if (!jsTarget->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) || !targetIdVal.isNumber())
  571. {
  572. if (foundTargetId != nullptr)
  573. *foundTargetId = 0;
  574. return false;
  575. }
  576. uint32_t targetId = targetIdVal.toUint32();
  577. if (foundTargetId != nullptr)
  578. *foundTargetId = targetId;
  579. bool found = isScheduleUpdateExist(targetId);
  580. if (found)
  581. {
  582. removeScheduleUpdate(targetId);
  583. scheduler->unscheduleUpdate(reinterpret_cast<void*>(targetId));
  584. }
  585. return found;
  586. }
  587. static bool Scheduler_scheduleUpdateCommon(Scheduler* scheduler, const se::Value& jsThis, int priority, bool isPaused)
  588. {
  589. se::Object* jsTargetObj = jsThis.toObject();
  590. uint32_t targetId = 0;
  591. Scheduler_unscheduleUpdateCommon(scheduler, jsTargetObj, &targetId);
  592. if (targetId == 0)
  593. {
  594. targetId = ++__scheduleTargetIdCounter;
  595. // counter is probably overfollow, it maybe 0 which is invalid id. Increase 1.
  596. if (targetId == 0)
  597. {
  598. targetId = ++__scheduleTargetIdCounter;
  599. }
  600. jsTargetObj->setProperty(SCHEDULE_TARGET_ID_KEY, se::Value(targetId));
  601. }
  602. insertScheduleUpdate(targetId, priority, jsTargetObj);
  603. std::shared_ptr<UnscheduleUpdateNotifier> scheduleUpdateWrapper = std::make_shared<UnscheduleUpdateNotifier>(targetId);
  604. se::Value thisVal = jsThis;
  605. scheduler->schedulePerFrame([thisVal, scheduleUpdateWrapper](float dt){
  606. se::ScriptEngine::getInstance()->clearException();
  607. se::AutoHandleScope hs;
  608. se::Value funcVal;
  609. if (thisVal.toObject()->getProperty("update", &funcVal) && funcVal.isObject() && funcVal.toObject()->isFunction())
  610. {
  611. se::ValueArray args;
  612. args.reserve(1);
  613. args.push_back(se::Value(dt));
  614. funcVal.toObject()->call(args, thisVal.toObject());
  615. }
  616. }, reinterpret_cast<void*>(targetId), priority, isPaused);
  617. return true;
  618. }
  619. static bool Node_scheduleUpdate(se::State& s)
  620. {
  621. #if COCOS2D_DEBUG > 1
  622. SE_LOGD("--------------------------\nscheduleUpdate target count: %d\n", (int)__js_target_schedule_update_map.size());
  623. for (const auto& e1 : __js_target_schedule_update_map)
  624. {
  625. SE_LOGD("target: %u, updated: priority: %d\n", e1.first, e1.second.first);
  626. }
  627. SE_LOGD("-------------------------- \n");
  628. #endif
  629. Node* thiz = (Node*)s.nativeThisObject();
  630. se::Value jsThis(s.thisObject());
  631. return Scheduler_scheduleUpdateCommon(thiz->getScheduler(), jsThis, 0, !thiz->isRunning());
  632. }
  633. SE_BIND_FUNC(Node_scheduleUpdate)
  634. static bool Node_scheduleUpdateWithPriority(se::State& s)
  635. {
  636. const auto& args = s.args();
  637. int argc = (int)args.size();
  638. #if COCOS2D_DEBUG > 1
  639. SE_LOGD("--------------------------\nscheduleUpdate target count: %d\n", (int)__js_target_schedule_update_map.size());
  640. for (const auto& e1 : __js_target_schedule_update_map)
  641. {
  642. SE_LOGD("target: %u, updated: priority: %d\n", e1.first, e1.second.first);
  643. }
  644. SE_LOGD("-------------------------- \n");
  645. #endif
  646. Node* thiz = (Node*)s.nativeThisObject();
  647. se::Value jsThis(s.thisObject());
  648. int priority = 0;
  649. if (argc == 1)
  650. {
  651. bool ok = seval_to_int32(args[0], &priority);
  652. SE_PRECONDITION2(ok, false, "Converting priority failed!");
  653. return Scheduler_scheduleUpdateCommon(thiz->getScheduler(), jsThis, priority, !thiz->isRunning());
  654. }
  655. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  656. return false;
  657. }
  658. SE_BIND_FUNC(Node_scheduleUpdateWithPriority)
  659. static bool Node_unscheduleUpdate(se::State& s)
  660. {
  661. int argc = (int)s.args().size();
  662. if (argc == 0)
  663. {
  664. Node* node = (Node*)s.nativeThisObject();
  665. Scheduler_unscheduleUpdateCommon(node->getScheduler(), s.thisObject());
  666. return true;
  667. }
  668. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 0);
  669. return false;
  670. }
  671. SE_BIND_FUNC(Node_unscheduleUpdate)
  672. static bool Scheduler_unscheduleCommon(Scheduler* scheduler, const se::Value& jsThis, const se::Value& jsFuncOrKey)
  673. {
  674. std::string key;
  675. bool found = false;
  676. se::Value targetIdVal;
  677. se::Value funcIdVal;
  678. jsThis.toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal);
  679. if (!targetIdVal.isNumber())
  680. return true;
  681. uint32_t targetId = targetIdVal.toUint32();
  682. uint32_t funcId = 0;
  683. if (jsFuncOrKey.isString() || jsFuncOrKey.isNumber())
  684. {
  685. key = jsFuncOrKey.toStringForce();
  686. const ScheduleElement* scheduleElem = nullptr;
  687. found = isScheduleExist(key, targetId, &scheduleElem);
  688. if (found)
  689. funcId = scheduleElem->getFuncId();
  690. }
  691. else if (jsFuncOrKey.isObject())
  692. {
  693. if (jsFuncOrKey.toObject()->getProperty(SCHEDULE_FUNC_ID_KEY, &funcIdVal) && funcIdVal.isNumber())
  694. {
  695. funcId = funcIdVal.toUint32();
  696. const ScheduleElement* scheduleElem = nullptr;
  697. found = isScheduleExist(funcId, targetId, &scheduleElem);
  698. if (found)
  699. key = scheduleElem->getKey();
  700. }
  701. }
  702. else
  703. {
  704. assert(false);
  705. }
  706. if (!targetIdVal.isNumber() || !funcIdVal.isNumber())
  707. {
  708. return true;
  709. }
  710. if (found && !key.empty())
  711. {
  712. removeSchedule(funcId, targetId, true);
  713. scheduler->unschedule(key, reinterpret_cast<void*>(targetId));
  714. }
  715. else
  716. {
  717. SE_LOGD("WARNING: %s not found\n", __FUNCTION__);
  718. }
  719. return true;
  720. }
  721. static bool Node_unschedule(se::State& s)
  722. {
  723. const auto& args = s.args();
  724. int argc = (int)args.size();
  725. if (argc == 1)
  726. {
  727. Node* thiz = (Node*)s.nativeThisObject();
  728. se::Value jsThis(s.thisObject());
  729. se::Value jsFunc(args[0]);
  730. return Scheduler_unscheduleCommon(thiz->getScheduler(), jsThis, jsFunc);
  731. }
  732. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  733. return false;
  734. }
  735. SE_BIND_FUNC(Node_unschedule)
  736. static bool Scheduler_isScheduled(Scheduler* scheduler, const se::Value& jsThis, const se::Value& jsFuncOrKey)
  737. {
  738. se::Value targetIdVal;
  739. if (!jsThis.toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) || !targetIdVal.isNumber())
  740. return false;
  741. uint32_t targetId = targetIdVal.toUint32();
  742. if (isTargetExistInScheduler(targetId))
  743. {
  744. if (jsFuncOrKey.isString() || jsFuncOrKey.isNumber())
  745. {
  746. return scheduler->isScheduled(jsFuncOrKey.toStringForce(), reinterpret_cast<void*>(targetId));
  747. }
  748. else if (jsFuncOrKey.isObject())
  749. {
  750. std::string key;
  751. se::Value funcIdVal;
  752. if (jsFuncOrKey.toObject()->getProperty(SCHEDULE_FUNC_ID_KEY, &funcIdVal) && funcIdVal.isNumber())
  753. {
  754. uint32_t funcId = funcIdVal.toUint32();
  755. const ScheduleElement* scheduleElem = nullptr;
  756. if (isScheduleExist(funcId, targetId, &scheduleElem))
  757. {
  758. key = scheduleElem->getKey();
  759. if (!key.empty())
  760. {
  761. return scheduler->isScheduled(key, reinterpret_cast<void*>(targetId));
  762. }
  763. }
  764. }
  765. }
  766. else
  767. {
  768. assert(false);
  769. }
  770. }
  771. return false;
  772. }
  773. static bool Node_isScheduled(se::State& s)
  774. {
  775. const auto& args = s.args();
  776. int argc = (int)args.size();
  777. if (argc == 1)
  778. {
  779. Node* thiz = (Node*)s.nativeThisObject();
  780. se::Value jsThis(s.thisObject());
  781. se::Value jsFuncOrKey(args[0]);
  782. bool isScheduled = Scheduler_isScheduled(thiz->getScheduler(), jsThis, jsFuncOrKey);
  783. s.rval().setBoolean(isScheduled);
  784. return true;
  785. }
  786. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  787. return false;
  788. }
  789. SE_BIND_FUNC(Node_isScheduled)
  790. static bool Scheduler_unscheduleAllCallbacksCommon(Scheduler* scheduler, se::Object* jsThis, bool needDetachChild)
  791. {
  792. se::Value targetIdVal;
  793. if (!jsThis->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) || !targetIdVal.isNumber())
  794. return true;
  795. uint32_t targetId = targetIdVal.toUint32();
  796. if (isTargetExistInScheduler(targetId))
  797. {
  798. removeScheduleForThis(targetId, needDetachChild);
  799. removeScheduleUpdate(targetId);
  800. scheduler->unscheduleAllForTarget(reinterpret_cast<void*>(targetId));
  801. }
  802. return true;
  803. }
  804. static bool Node_unscheduleAllCallbacks(se::State& s)
  805. {
  806. const auto& args = s.args();
  807. int argc = (int)args.size();
  808. Node* thiz = (Node*)s.nativeThisObject();
  809. if (argc == 0)
  810. {
  811. return Scheduler_unscheduleAllCallbacksCommon(thiz->getScheduler(), s.thisObject(), true);
  812. }
  813. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 0);
  814. return false;
  815. }
  816. SE_BIND_FUNC(Node_unscheduleAllCallbacks)
  817. static bool Node_getChildren(se::State& s)
  818. {
  819. Node* thiz = (Node*)s.nativeThisObject();
  820. const auto& children = thiz->getChildren();
  821. bool ok = Vector_to_seval(children, &s.rval());
  822. return ok;
  823. }
  824. SE_BIND_FUNC(Node_getChildren)
  825. static bool Node_foo(se::State& s)
  826. {
  827. s.rval().setString("hello world");
  828. return true;
  829. }
  830. SE_BIND_FUNC(Node_foo)
  831. static bool Node_set_x(se::State& s)
  832. {
  833. const auto& args = s.args();
  834. Node* thiz = (Node*)s.nativeThisObject();
  835. float x = args[0].toNumber();
  836. SE_LOGD("cc.Node set_x (%f) native obj: %p\n", x, thiz);
  837. thiz->setPositionX(x);
  838. return true;
  839. }
  840. SE_BIND_PROP_SET(Node_set_x)
  841. static bool Node_get_x(se::State& s)
  842. {
  843. Node* thiz = (Node*)s.nativeThisObject();
  844. s.rval().setFloat(thiz->getPositionX());
  845. return true;
  846. }
  847. SE_BIND_PROP_GET(Node_get_x)
  848. static bool Node_set_y(se::State& s)
  849. {
  850. const auto& args = s.args();
  851. Node* thiz = (Node*)s.nativeThisObject();
  852. float y = args[0].toNumber();
  853. SE_LOGD("cc.Node set_y (%f) native obj: %p\n", y, thiz);
  854. thiz->setPositionY(y);
  855. return true;
  856. }
  857. SE_BIND_PROP_SET(Node_set_y)
  858. static bool Node_get_y(se::State& s)
  859. {
  860. Node* thiz = (Node*)s.nativeThisObject();
  861. s.rval().setFloat(thiz->getPositionY());
  862. return true;
  863. }
  864. SE_BIND_PROP_GET(Node_get_y)
  865. static bool Node_setContentSize(se::State& s)
  866. {
  867. const auto& args = s.args();
  868. size_t argc = args.size();
  869. Node* cobj = (Node*)s.nativeThisObject();
  870. bool ok = true;
  871. if (argc == 1)
  872. {
  873. cocos2d::Size arg0;
  874. ok &= seval_to_Size(args[0], &arg0);
  875. SE_PRECONDITION2(ok, false, "Error processing arguments");
  876. cobj->setContentSize(arg0);
  877. return true;
  878. }
  879. else if (argc == 2)
  880. {
  881. float width = 0.0f;
  882. float height = 0.0f;
  883. ok &= seval_to_float(args[0], &width);
  884. ok &= seval_to_float(args[1], &height);
  885. cobj->setContentSize(cocos2d::Size(width, height));
  886. return true;
  887. }
  888. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
  889. return false;
  890. }
  891. SE_BIND_FUNC(Node_setContentSize)
  892. static bool Node_setAnchorPoint(se::State& s)
  893. {
  894. const auto& args = s.args();
  895. size_t argc = args.size();
  896. Node* cobj = (Node*)s.nativeThisObject();
  897. bool ok = true;
  898. if (argc == 1)
  899. {
  900. cocos2d::Vec2 arg0;
  901. ok &= seval_to_Vec2(args[0], &arg0);
  902. SE_PRECONDITION2(ok, false, "Error processing arguments");
  903. cobj->setAnchorPoint(arg0);
  904. return true;
  905. }
  906. else if (argc == 2)
  907. {
  908. float x = 0.0f;
  909. float y = 0.0f;
  910. ok &= seval_to_float(args[0], &x);
  911. ok &= seval_to_float(args[1], &y);
  912. cobj->setAnchorPoint(cocos2d::Vec2(x, y));
  913. return true;
  914. }
  915. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
  916. return false;
  917. }
  918. SE_BIND_FUNC(Node_setAnchorPoint)
  919. static bool Node_setPosition(se::State& s)
  920. {
  921. const auto& args = s.args();
  922. size_t argc = args.size();
  923. Node* cobj = (Node*)s.nativeThisObject();
  924. bool ok = true;
  925. if (argc == 1)
  926. {
  927. cocos2d::Vec2 arg0;
  928. ok &= seval_to_Vec2(args[0], &arg0);
  929. SE_PRECONDITION2(ok, false, "Error processing arguments");
  930. cobj->setPosition(arg0);
  931. return true;
  932. }
  933. else if (argc == 2)
  934. {
  935. float x = 0.0f;
  936. float y = 0.0f;
  937. ok &= seval_to_float(args[0], &x);
  938. ok &= seval_to_float(args[1], &y);
  939. cobj->setPosition(x, y);
  940. return true;
  941. }
  942. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 2);
  943. return false;
  944. }
  945. SE_BIND_FUNC(Node_setPosition)
  946. // Scheduler
  947. static bool js_cocos2dx_Scheduler_scheduleUpdateForTarget(se::State& s)
  948. {
  949. const auto& args = s.args();
  950. int argc = (int)args.size();
  951. if (argc >= 1)
  952. {
  953. bool ok = true;
  954. se::Value jsTarget = args[0];
  955. int priority = 0;
  956. bool isPaused = false;
  957. if (argc >= 2)
  958. {
  959. ok = seval_to_int32(args[1], &priority);
  960. SE_PRECONDITION2(ok, false, "Error processing arguments");
  961. }
  962. if (argc >= 3)
  963. {
  964. ok = seval_to_boolean(args[2], &isPaused);
  965. SE_PRECONDITION2(ok, false, "Error processing arguments");
  966. }
  967. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  968. Scheduler_scheduleUpdateCommon(cobj, jsTarget, priority, isPaused);
  969. return true;
  970. }
  971. SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, ">=1");
  972. return false;
  973. }
  974. SE_BIND_FUNC(js_cocos2dx_Scheduler_scheduleUpdateForTarget)
  975. static bool js_cocos2dx_Scheduler_unscheduleUpdate(se::State& s)
  976. {
  977. const auto& args = s.args();
  978. int argc = (int)args.size();
  979. if (argc >= 1)
  980. {
  981. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  982. se::Value jsTarget = args[0];
  983. Scheduler_unscheduleUpdateCommon(cobj, jsTarget.toObject());
  984. return true;
  985. }
  986. SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, "1");
  987. return false;
  988. }
  989. SE_BIND_FUNC(js_cocos2dx_Scheduler_unscheduleUpdate)
  990. static bool js_cocos2dx_Scheduler_schedule(se::State& s)
  991. {
  992. const auto& args = s.args();
  993. int argc = (int)args.size();
  994. #if 0//COCOS2D_DEBUG > 0
  995. SE_LOGD("--------------------------\nschedule target count: %d\n", (int)__js_target_schedulekey_map.size());
  996. for (const auto& e1 : __js_target_schedulekey_map)
  997. {
  998. SE_LOGD("schedule target: %p, functions: %d\n", e1.first, (int)e1.second.size());
  999. }
  1000. SE_LOGD("-------------------------- \n");
  1001. #endif
  1002. //
  1003. if (argc >= 4)
  1004. {
  1005. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1006. se::Value jsFunc;
  1007. se::Value jsThis;
  1008. if (args[0].isObject() && args[0].toObject()->isFunction())
  1009. {
  1010. jsFunc = args[0];
  1011. jsThis = args[1];
  1012. }
  1013. else
  1014. {
  1015. jsFunc = args[1];
  1016. jsThis = args[0];
  1017. }
  1018. bool isBindedObject = jsThis.toObject()->getPrivateData() != nullptr;
  1019. // SE_LOGD("%s, is binded object: %s\n", __FUNCTION__, isBindedObject ? "true" : "false");
  1020. assert(jsThis.isObject());
  1021. assert(!jsThis.toObject()->isFunction());
  1022. bool ok = false;
  1023. float interval = 0.0f;
  1024. unsigned int repeat = CC_REPEAT_FOREVER;
  1025. float delay = 0.0f;
  1026. bool isPaused = false;
  1027. ok = seval_to_float(args[2], &interval);
  1028. SE_PRECONDITION2(ok, false, "Converting 'interval' argument failed");
  1029. if (argc == 4)
  1030. {
  1031. // callback, target, interval, paused
  1032. ok = seval_to_boolean(args[3], &isPaused);
  1033. SE_PRECONDITION2(ok, false, "Converting 'isPaused' argument failed");
  1034. }
  1035. else if (argc >= 6)
  1036. {
  1037. // callback, target, interval, repeat, delay, paused
  1038. // repeat
  1039. ok = seval_to_uint32(args[3], &repeat);
  1040. SE_PRECONDITION2(ok, false, "Converting 'interval' argument failed");
  1041. // delay
  1042. ok = seval_to_float(args[4], &delay);
  1043. SE_PRECONDITION2(ok, false, "Converting 'delay' argument failed");
  1044. // isPaused
  1045. ok = seval_to_boolean(args[5], &isPaused);
  1046. SE_PRECONDITION2(ok, false, "Converting 'isPaused' argument failed");
  1047. }
  1048. return Scheduler_scheduleCommon(cobj, jsThis, jsFunc, interval, repeat, delay, isPaused, !isBindedObject, "cc.Scheduler.schedule");
  1049. }
  1050. SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, ">=2");
  1051. return false;
  1052. }
  1053. SE_BIND_FUNC(js_cocos2dx_Scheduler_schedule)
  1054. static bool js_cocos2dx_Scheduler_unschedule(se::State& s)
  1055. {
  1056. const auto& args = s.args();
  1057. int argc = (int)args.size();
  1058. if (argc >= 2)
  1059. {
  1060. se::Value jsFuncOrKey;
  1061. se::Value jsTarget;
  1062. if (args[0].isString() || (args[0].isObject() && args[0].toObject()->isFunction()))
  1063. {
  1064. jsFuncOrKey = args[0];
  1065. jsTarget = args[1];
  1066. }
  1067. else
  1068. {
  1069. jsFuncOrKey = args[1];
  1070. jsTarget = args[0];
  1071. }
  1072. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1073. return Scheduler_unscheduleCommon(cobj, jsTarget, jsFuncOrKey);
  1074. }
  1075. SE_REPORT_ERROR("wrong number of arguments: %d, expected: %s", argc, ">=2");
  1076. return false;
  1077. }
  1078. SE_BIND_FUNC(js_cocos2dx_Scheduler_unschedule)
  1079. static bool js_cocos2dx_Scheduler_unscheduleAllForTarget(se::State& s)
  1080. {
  1081. const auto& args = s.args();
  1082. int argc = (int)args.size();
  1083. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1084. if (argc == 1)
  1085. {
  1086. se::Value target = args[0];
  1087. return Scheduler_unscheduleAllCallbacksCommon(cobj, target.toObject(), true);
  1088. }
  1089. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  1090. return false;
  1091. }
  1092. SE_BIND_FUNC(js_cocos2dx_Scheduler_unscheduleAllForTarget)
  1093. static bool js_cocos2dx_Scheduler_unscheduleAllCallbacks(se::State& s)
  1094. {
  1095. const auto& args = s.args();
  1096. int argc = (int)args.size();
  1097. if (argc == 0)
  1098. {
  1099. removeAllScheduleAndUpdate(true);
  1100. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1101. cobj->unscheduleAll();
  1102. CCLOG("After unschedule all callbacks");
  1103. return true;
  1104. }
  1105. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 0);
  1106. return false;
  1107. }
  1108. SE_BIND_FUNC(js_cocos2dx_Scheduler_unscheduleAllCallbacks)
  1109. static bool js_cocos2dx_Scheduler_unscheduleAllCallbacksWithMinPriority(se::State& s)
  1110. {
  1111. const auto& args = s.args();
  1112. int argc = (int)args.size();
  1113. if (argc == 1)
  1114. {
  1115. int minPriority = 0;
  1116. bool ok = false;
  1117. ok = seval_to_int32(args[0], &minPriority);
  1118. SE_PRECONDITION2(ok, false, "Converting minPriority failed!");
  1119. removeAllSchedules(true);
  1120. removeScheduleUpdatesForMinPriority(minPriority);
  1121. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1122. cobj->unscheduleAllWithMinPriority(minPriority);
  1123. return true;
  1124. }
  1125. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 0);
  1126. return false;
  1127. }
  1128. SE_BIND_FUNC(js_cocos2dx_Scheduler_unscheduleAllCallbacksWithMinPriority)
  1129. static bool js_cocos2dx_Scheduler_isScheduled(se::State& s)
  1130. {
  1131. const auto& args = s.args();
  1132. int argc = (int)args.size();
  1133. if (argc == 2)
  1134. {
  1135. Scheduler* thiz = (Scheduler*)s.nativeThisObject();
  1136. se::Value jsFuncOrKey(args[0]);
  1137. se::Value jsThis(args[1]);
  1138. bool isScheduled = Scheduler_isScheduled(thiz, jsThis, jsFuncOrKey);
  1139. s.rval().setBoolean(isScheduled);
  1140. return true;
  1141. }
  1142. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 2);
  1143. return false;
  1144. }
  1145. SE_BIND_FUNC(js_cocos2dx_Scheduler_isScheduled)
  1146. static bool js_cocos2dx_Scheduler_pauseTarget(se::State& s)
  1147. {
  1148. const auto& args = s.args();
  1149. int argc = (int)args.size();
  1150. if (argc == 1)
  1151. {
  1152. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1153. se::Value targetIdVal;
  1154. if (args[0].toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) && targetIdVal.isNumber())
  1155. {
  1156. uint32_t targetId = targetIdVal.toUint32();
  1157. if (isTargetExistInScheduler(targetId))
  1158. {
  1159. cobj->pauseTarget(reinterpret_cast<void*>(targetId));
  1160. }
  1161. }
  1162. return true;
  1163. }
  1164. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  1165. return false;
  1166. }
  1167. SE_BIND_FUNC(js_cocos2dx_Scheduler_pauseTarget)
  1168. static bool js_cocos2dx_Scheduler_resumeTarget(se::State& s)
  1169. {
  1170. const auto& args = s.args();
  1171. int argc = (int)args.size();
  1172. if (argc == 1)
  1173. {
  1174. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1175. se::Value targetIdVal;
  1176. if (args[0].toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) && targetIdVal.isNumber())
  1177. {
  1178. uint32_t targetId = targetIdVal.toUint32();
  1179. if (isTargetExistInScheduler(targetId))
  1180. {
  1181. cobj->resumeTarget(reinterpret_cast<void*>(targetId));
  1182. }
  1183. }
  1184. return true;
  1185. }
  1186. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  1187. return false;
  1188. }
  1189. SE_BIND_FUNC(js_cocos2dx_Scheduler_resumeTarget)
  1190. static bool js_cocos2dx_Scheduler_isTargetPaused(se::State& s)
  1191. {
  1192. const auto& args = s.args();
  1193. int argc = (int)args.size();
  1194. if (argc == 1)
  1195. {
  1196. Scheduler* cobj = (Scheduler*)s.nativeThisObject();
  1197. se::Value targetIdVal;
  1198. if (args[0].toObject()->getProperty(SCHEDULE_TARGET_ID_KEY, &targetIdVal) && targetIdVal.isNumber())
  1199. {
  1200. uint32_t targetId = targetIdVal.toUint32();
  1201. if (isTargetExistInScheduler(targetId))
  1202. {
  1203. bool isPaused = cobj->isTargetPaused(reinterpret_cast<void*>(targetId));
  1204. s.rval().setBoolean(isPaused);
  1205. return true;
  1206. }
  1207. }
  1208. s.rval().setBoolean(false);
  1209. return true;
  1210. }
  1211. SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", argc, 1);
  1212. return false;
  1213. }
  1214. SE_BIND_FUNC(js_cocos2dx_Scheduler_isTargetPaused)
  1215. static void resumeAllSchedulesForTarget(Node* node, se::Object* jsThis)
  1216. {
  1217. node->getScheduler()->resumeTarget(jsThis);
  1218. }
  1219. static void pauseAllSchedulesForTarget(Node* node, se::Object* jsThis)
  1220. {
  1221. node->getScheduler()->pauseTarget(jsThis);
  1222. }
  1223. static void cleanupAllSchedulesForTarget(Node* node, se::Object* jsThis)
  1224. {
  1225. //IDEA: ?? Do we need this since we have already had a 'UnscheduleNotifier' and 'UnscheduleUpdateWrapper'.
  1226. node->getScheduler()->unscheduleAllForTarget(jsThis);
  1227. }
  1228. static bool onReceiveNodeEvent(void* node, ScriptingCore::NodeEventType type)
  1229. {
  1230. auto iter = se::NativePtrToObjectMap::find(node);
  1231. if (iter == se::NativePtrToObjectMap::end())
  1232. return false;
  1233. se::ScriptEngine::getInstance()->clearException();
  1234. se::AutoHandleScope hs;
  1235. se::Object* target = iter->second;
  1236. const char* funcName = nullptr;
  1237. bool ret = false;
  1238. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1239. JSNative func = nullptr;
  1240. #endif
  1241. if (type == ScriptingCore::NodeEventType::ENTER)
  1242. {
  1243. funcName = "onEnter";
  1244. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1245. func = _SE(Node_onEnter);
  1246. #endif
  1247. }
  1248. else if (type == ScriptingCore::NodeEventType::EXIT)
  1249. {
  1250. funcName = "onExit";
  1251. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1252. func = _SE(Node_onExit);
  1253. #endif
  1254. }
  1255. else if (type == ScriptingCore::NodeEventType::ENTER_TRANSITION_DID_FINISH)
  1256. {
  1257. funcName = "onEnterTransitionDidFinish";
  1258. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1259. func = _SE(Node_onEnterTransitionDidFinish);
  1260. #endif
  1261. }
  1262. else if (type == ScriptingCore::NodeEventType::EXIT_TRANSITION_DID_START)
  1263. {
  1264. funcName = "onExitTransitionDidStart";
  1265. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1266. func = _SE(Node_onExitTransitionDidStart);
  1267. #endif
  1268. }
  1269. else if (type == ScriptingCore::NodeEventType::CLEANUP)
  1270. {
  1271. funcName = "cleanup";
  1272. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1273. func = _SE(Node_cleanup);
  1274. #endif
  1275. }
  1276. else
  1277. {
  1278. assert(false);
  1279. }
  1280. se::Value funcVal;
  1281. bool ok = target->getProperty(funcName, &funcVal);
  1282. #if SCRIPT_ENGINE_TYPE == SCRIPT_ENGINE_SM
  1283. bool isNativeFunc = funcVal.toObject()->_isNativeFunction(func);
  1284. #else
  1285. bool isNativeFunc = funcVal.toObject()->_isNativeFunction();
  1286. #endif
  1287. if (ok && !isNativeFunc)
  1288. {
  1289. ret = funcVal.toObject()->call(se::EmptyValueArray, target);
  1290. }
  1291. // Handle schedule stuff
  1292. if (type == ScriptingCore::NodeEventType::ENTER)
  1293. {
  1294. resumeAllSchedulesForTarget((Node*)node, target);
  1295. }
  1296. else if (type == ScriptingCore::NodeEventType::EXIT)
  1297. {
  1298. pauseAllSchedulesForTarget((Node*)node, target);
  1299. }
  1300. else if (type == ScriptingCore::NodeEventType::CLEANUP)
  1301. {
  1302. cleanupAllSchedulesForTarget((Node*)node, target);
  1303. }
  1304. return ret;
  1305. }
  1306. bool jsb_register_Node_manual(se::Object* global)
  1307. {
  1308. #if STANDALONE_TEST
  1309. se::Object* ccObj = nullptr;
  1310. getOrCreatePlainObject_r("cc", global, &ccObj);
  1311. auto cls = se::Class::create("Node", ccObj, nullptr, _SE(Node_constructor));
  1312. cls->defineStaticFunction("create", _SE(Node_create));
  1313. cls->defineProperty("x", _SE(Node_get_x), _SE(Node_set_x));
  1314. cls->defineProperty("y", _SE(Node_get_y), _SE(Node_set_y));
  1315. cls->defineFunction("ctor", _SE(Node_ctor));
  1316. se::ScriptEngine::getInstance()->addAfterCleanupHook([](){
  1317. SAFE_DEC_REF(ccObj);
  1318. });
  1319. #else
  1320. auto cls = __jsb_cocos2d_Node_proto;
  1321. #endif
  1322. cls->defineFunction("onEnter", _SE(Node_onEnter));
  1323. cls->defineFunction("onExit", _SE(Node_onExit));
  1324. cls->defineFunction("onEnterTransitionDidFinish", _SE(Node_onEnterTransitionDidFinish));
  1325. cls->defineFunction("onExitTransitionDidStart", _SE(Node_onExitTransitionDidStart));
  1326. cls->defineFunction("cleanup", _SE(Node_cleanup));
  1327. cls->defineFunction("schedule", _SE(Node_schedule));
  1328. cls->defineFunction("scheduleOnce", _SE(Node_scheduleOnce));
  1329. cls->defineFunction("scheduleUpdateWithPriority", _SE(Node_scheduleUpdateWithPriority));
  1330. cls->defineFunction("scheduleUpdate", _SE(Node_scheduleUpdate));
  1331. cls->defineFunction("unscheduleUpdate", _SE(Node_unscheduleUpdate));
  1332. cls->defineFunction("unschedule", _SE(Node_unschedule));
  1333. cls->defineFunction("unscheduleAllCallbacks", _SE(Node_unscheduleAllCallbacks));
  1334. cls->defineFunction("isScheduled", _SE(Node_isScheduled));
  1335. cls->defineFunction("setContentSize", _SE(Node_setContentSize));
  1336. cls->defineFunction("setAnchorPoint", _SE(Node_setAnchorPoint));
  1337. cls->defineFunction("setPosition", _SE(Node_setPosition));
  1338. auto schedulerProto = __jsb_cocos2d_Scheduler_proto;
  1339. schedulerProto->defineFunction("scheduleUpdateForTarget", _SE(js_cocos2dx_Scheduler_scheduleUpdateForTarget));
  1340. schedulerProto->defineFunction("scheduleUpdate", _SE(js_cocos2dx_Scheduler_scheduleUpdateForTarget));
  1341. schedulerProto->defineFunction("unscheduleUpdate", _SE(js_cocos2dx_Scheduler_unscheduleUpdate));
  1342. schedulerProto->defineFunction("schedule", _SE(js_cocos2dx_Scheduler_schedule));
  1343. schedulerProto->defineFunction("scheduleCallbackForTarget", _SE(js_cocos2dx_Scheduler_schedule));
  1344. schedulerProto->defineFunction("unschedule", _SE(js_cocos2dx_Scheduler_unschedule));
  1345. schedulerProto->defineFunction("unscheduleCallbackForTarget", _SE(js_cocos2dx_Scheduler_unschedule));
  1346. schedulerProto->defineFunction("unscheduleAllForTarget", _SE(js_cocos2dx_Scheduler_unscheduleAllForTarget));
  1347. schedulerProto->defineFunction("unscheduleAllCallbacks", _SE(js_cocos2dx_Scheduler_unscheduleAllCallbacks));
  1348. schedulerProto->defineFunction("unscheduleAllCallbacksWithMinPriority", _SE(js_cocos2dx_Scheduler_unscheduleAllCallbacksWithMinPriority));
  1349. schedulerProto->defineFunction("isScheduled", _SE(js_cocos2dx_Scheduler_isScheduled));
  1350. schedulerProto->defineFunction("pauseTarget", _SE(js_cocos2dx_Scheduler_pauseTarget));
  1351. schedulerProto->defineFunction("resumeTarget", _SE(js_cocos2dx_Scheduler_resumeTarget));
  1352. schedulerProto->defineFunction("isTargetPaused", _SE(js_cocos2dx_Scheduler_isTargetPaused));
  1353. #if STANDALONE_TEST
  1354. cls->defineFunction("addChild", _SE(Node_addChild));
  1355. cls->defineFunction("getChildren", _SE(Node_getChildren));
  1356. cls->defineFinalizeFunction(_SE(Node_finalized));
  1357. cls->install();
  1358. __jsb_Node_proto = cls->getProto();
  1359. __jsb_Node_class = cls;
  1360. __jsb_Node_proto->defineFunction("foo", _SE(Node_foo));
  1361. __jsb_Node_proto->setProperty("var1", se::Value("I'm var1"));
  1362. __jsb_Node_proto->setProperty("var2", se::Value(10000.323));
  1363. #endif
  1364. ScriptingCore::getInstance()->setNodeEventListener(onReceiveNodeEvent);
  1365. se::ScriptEngine::getInstance()->clearException();
  1366. return true;
  1367. }