PuzzleSDK
NewEventDispatcherTest.cpp
浏览该文件的文档.
1/****************************************************************************
2 Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
3
4 http://www.cocos2d-x.org
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 THE SOFTWARE.
23 ****************************************************************************/
24
25//
26// NewEventDispatcherTest.cpp
27// samples
28//
29// Created by James Chen on 9/13/13.
30//
31//
32
34#include "testResource.h"
35
37
38EventDispatcherTests::EventDispatcherTests()
39{
61}
62
64{
65 return "No title";
66}
67
68// TouchableSpriteTest
70{
72
73 Vec2 origin = Director::getInstance()->getVisibleOrigin();
74 Size size = Director::getInstance()->getVisibleSize();
75
76 auto containerForSprite1 = Node::create();
77 auto sprite1 = Sprite::create("Images/CyanSquare.png");
78 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 80.0f));
79 containerForSprite1->addChild(sprite1);
80 addChild(containerForSprite1, 10);
81
82 auto sprite2 = Sprite::create("Images/MagentaSquare.png");
83 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
84 addChild(sprite2, 20);
85
86 auto sprite3 = Sprite::create("Images/YellowSquare.png");
87 sprite3->setPosition(Vec2(0, 0));
88 sprite2->addChild(sprite3, 1);
89
90 // Make sprite1 touchable
91 auto listener1 = EventListenerTouchOneByOne::create();
92 listener1->setSwallowTouches(true);
93
94 listener1->onTouchBegan = [](Touch* touch, Event* event){
95 auto target = static_cast<Sprite*>(event->getCurrentTarget());
96
97 Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
98 Size s = target->getContentSize();
99 Rect rect = Rect(0, 0, s.width, s.height);
100
101 if (rect.containsPoint(locationInNode))
102 {
103 log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
104 target->setOpacity(180);
105 return true;
106 }
107 return false;
108 };
109
110 listener1->onTouchMoved = [](Touch* touch, Event* event){
111 auto target = static_cast<Sprite*>(event->getCurrentTarget());
112 target->setPosition(target->getPosition() + touch->getDelta());
113 };
114
115 listener1->onTouchEnded = [=](Touch* touch, Event* event){
116 auto target = static_cast<Sprite*>(event->getCurrentTarget());
117 log("sprite onTouchesEnded.. ");
118 target->setOpacity(255);
119 if (target == sprite2)
120 {
121 containerForSprite1->setLocalZOrder(100);
122 }
123 else if(target == sprite1)
124 {
125 containerForSprite1->setLocalZOrder(0);
126 }
127 };
128
129 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
130 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite2);
131 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1->clone(), sprite3);
132
133
134 auto removeAllTouchItem = MenuItemFont::create("Remove All Touch Listeners", [this](Ref* sender){
135 auto senderItem = static_cast<MenuItemFont*>(sender);
136 senderItem->setString("Only Next item could be clicked");
137
138 _eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);
139
140 auto nextItem = MenuItemFont::create("Next", [=](Ref* sender){
142 });
143
144 nextItem->setFontSizeObj(16);
145 nextItem->setPosition(VisibleRect::right() + Vec2(-100.0f, -30.0f));
146
147 auto menu2 = Menu::create(nextItem, nullptr);
148 menu2->setPosition(Vec2(0, 0));
149 menu2->setAnchorPoint(Vec2(0, 0));
150 this->addChild(menu2);
151 });
152
153 removeAllTouchItem->setFontSizeObj(16);
154 removeAllTouchItem->setPosition(VisibleRect::right() + Vec2(-100.0f, 0.0f));
155
156 auto menu = Menu::create(removeAllTouchItem, nullptr);
157 menu->setPosition(Vec2(0, 0));
158 menu->setAnchorPoint(Vec2(0, 0));
159 addChild(menu);
160}
161
162std::string TouchableSpriteTest::title() const
163{
164 return "Touchable Sprite Test";
165}
166
168{
169 return "Please drag the blocks";
170}
171
172// FixedPriorityChangedTest
173
174class TouchableSprite : public Sprite
175{
176public:
177 static TouchableSprite* create(int priority = 0)
178 {
179 auto ret = new (std::nothrow) TouchableSprite(priority);
180 if (ret && ret->init())
181 {
182 ret->autorelease();
183 }
184 else
185 {
186 CC_SAFE_DELETE(ret);
187 }
188 return ret;
189 }
190
191protected:
192 TouchableSprite(int priority)
193 : _listener(nullptr)
194 , _fixedPriority(priority)
196 {
197 }
198
199 virtual bool init() override
200 {
201 if (!Sprite::init())
202 return false;
203
204 auto listener = EventListenerTouchOneByOne::create();
205 listener->setSwallowTouches(true);
206
207 listener->onTouchBegan = [this](Touch* touch, Event* event){
208 Vec2 locationInNode = this->convertToNodeSpace(touch->getLocation());
209 Size s = this->getContentSize();
210 Rect rect = Rect(0, 0, s.width, s.height);
211
212 if (rect.containsPoint(locationInNode))
213 {
214 log("TouchableSprite: onTouchBegan ...");
215 this->setColor(Color3B::RED);
216 return true;
217 }
218 return false;
219 };
220
221 listener->onTouchEnded = [this](Touch* touch, Event* event){
222 log("TouchableSprite: onTouchEnded ...");
223 this->setColor(Color3B::WHITE);
224
226 {
227 _eventDispatcher->removeEventListener(_listener);
228 _listener = nullptr;
229 }
230 };
231
232 if (_fixedPriority != 0)
233 {
234 _eventDispatcher->addEventListenerWithFixedPriority(listener, _fixedPriority);
235 }
236 else
237 {
238 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
239 }
240
241 _listener = listener;
242 return true;
243 }
244
245 virtual void onExit() override
246 {
247 if (_listener != nullptr && _fixedPriority != 0)
248 {
249 _eventDispatcher->removeEventListener(_listener);
250 }
251
252 Sprite::onExit();
253 }
254public:
255 void removeListenerOnTouchEnded(bool toRemove) { _removeListenerOnTouchEnded = toRemove; };
256
257 inline EventListener* getListener() { return _listener; };
258
259private:
260 EventListener* _listener;
263};
264
266{
268
269 Vec2 origin = Director::getInstance()->getVisibleOrigin();
270 Size size = Director::getInstance()->getVisibleSize();
271
272 auto sprite1 = TouchableSprite::create(30);
273 sprite1->setTexture("Images/CyanSquare.png");
274 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 40.0f));
275 addChild(sprite1, 10);
276
277 auto sprite2 = TouchableSprite::create(20);
278 sprite2->setTexture("Images/MagentaSquare.png");
279 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
280 addChild(sprite2, 20);
281
282 auto sprite3 = TouchableSprite::create(10);
283 sprite3->setTexture("Images/YellowSquare.png");
284 sprite3->setPosition(Vec2(0, 0));
285 sprite2->addChild(sprite3, 1);
286
287}
288
289std::string FixedPriorityTest::title() const
290{
291 return "Fixed priority test";
292}
293
295{
296 return "Fixed Priority, Blue: 30, Red: 20, Yellow: 10\n The lower value the higher priority will be.";
297}
298
299// RemoveListenerWhenDispatching
301{
303
304 Vec2 origin = Director::getInstance()->getVisibleOrigin();
305 Size size = Director::getInstance()->getVisibleSize();
306
307 auto sprite1 = Sprite::create("Images/CyanSquare.png");
308 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2));
309 addChild(sprite1, 10);
310
311 // Make sprite1 touchable
312 auto listener1 = EventListenerTouchOneByOne::create();
313 listener1->setSwallowTouches(true);
314 setUserObject(listener1);
315
316 std::shared_ptr<bool> firstClick(new bool(true));
317
318 listener1->onTouchBegan = [=](Touch* touch, Event* event){
319 Vec2 locationInNode = sprite1->convertToNodeSpace(touch->getLocation());
320 Size s = sprite1->getContentSize();
321 Rect rect = Rect(0, 0, s.width, s.height);
322
323 if (rect.containsPoint(locationInNode))
324 {
325 sprite1->setColor(Color3B::RED);
326 return true;
327 }
328 return false;
329 };
330
331 listener1->onTouchEnded = [=](Touch* touch, Event* event){
332 sprite1->setColor(Color3B::WHITE);
333 };
334
335 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
336
337 auto statusLabel = Label::createWithSystemFont("The sprite could be touched!", "", 20);
338 statusLabel->setPosition(origin + Vec2(size.width/2, size.height-90));
339 addChild(statusLabel);
340 std::shared_ptr<bool> enable(new bool(true));
341 // Enable/Disable item
342 auto toggleItem = MenuItemToggle::createWithCallback([=](Ref* sender){
343 if (*enable)
344 {
345 _eventDispatcher->removeEventListener(listener1);
346 statusLabel->setString("The sprite could not be touched!");
347
348 (*enable) = false;
349 }
350 else
351 {
352 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1);
353 statusLabel->setString("The sprite could be touched!");
354
355 (*enable) = true;
356 }
357 }, MenuItemFont::create("Enabled"), MenuItemFont::create("Disabled"), nullptr);
358
359 toggleItem->setPosition(origin + Vec2(size.width/2, 80.0f));
360 auto menu = Menu::create(toggleItem, nullptr);
361 menu->setPosition(Vec2(0.0f, 0.0f));
362 menu->setAnchorPoint(Vec2(0.0f, 0.0f));
363 addChild(menu, -1);
364}
365
367{
368 return "Add and remove listener\n when dispatching event";
369}
370
372{
373 return "";
374}
375
376// CustomEventTest
378{
380
381 Vec2 origin = Director::getInstance()->getVisibleOrigin();
382 Size size = Director::getInstance()->getVisibleSize();
383
384 MenuItemFont::setFontSize(20);
385
386 auto statusLabel = Label::createWithSystemFont("No custom event 1 received!", "", 20);
387 statusLabel->setPosition(origin + Vec2(size.width/2, size.height-90));
388 addChild(statusLabel);
389
390 _listener = EventListenerCustom::create("game_custom_event1", [=](EventCustom* event){
391 std::string str("Custom event 1 received, ");
392 char* buf = static_cast<char*>(event->getUserData());
393 str += buf;
394 str += " times";
395 statusLabel->setString(str.c_str());
396 });
397
398 _eventDispatcher->addEventListenerWithFixedPriority(_listener, 1);
399
400 auto sendItem = MenuItemFont::create("Send Custom Event 1", [=](Ref* sender){
401 static int count = 0;
402 ++count;
403 char* buf = new char[10];
404 sprintf(buf, "%d", count);
405 EventCustom event("game_custom_event1");
406 event.setUserData(buf);
407 _eventDispatcher->dispatchEvent(&event);
408 CC_SAFE_DELETE_ARRAY(buf);
409 });
410 sendItem->setPosition(origin + Vec2(size.width/2, size.height/2));
411
412 auto statusLabel2 = Label::createWithSystemFont("No custom event 2 received!", "", 20);
413 statusLabel2->setPosition(origin + Vec2(size.width/2, size.height-120));
414 addChild(statusLabel2);
415
416 _listener2 = EventListenerCustom::create("game_custom_event2", [=](EventCustom* event){
417 std::string str("Custom event 2 received, ");
418 char* buf = static_cast<char*>(event->getUserData());
419 str += buf;
420 str += " times";
421 statusLabel2->setString(str.c_str());
422 });
423
424 _eventDispatcher->addEventListenerWithFixedPriority(_listener2, 1);
425
426 auto sendItem2 = MenuItemFont::create("Send Custom Event 2", [=](Ref* sender){
427 static int count = 0;
428 ++count;
429 char* buf = new char[10];
430 sprintf(buf, "%d", count);
431 EventCustom event("game_custom_event2");
432 event.setUserData(buf);
433 _eventDispatcher->dispatchEvent(&event);
434 CC_SAFE_DELETE_ARRAY(buf);
435 });
436 sendItem2->setPosition(origin + Vec2(size.width/2, size.height/2 - 40));
437
438 auto menu = Menu::create(sendItem, sendItem2, nullptr);
439 menu->setPosition(Vec2(0, 0));
440 menu->setAnchorPoint(Vec2(0, 0));
441 addChild(menu, -1);
442}
443
445{
446 _eventDispatcher->removeEventListener(_listener);
447 _eventDispatcher->removeEventListener(_listener2);
448 EventDispatcherTestDemo::onExit();
449}
450
451std::string CustomEventTest::title() const
452{
453 return "Send custom event";
454}
455
456std::string CustomEventTest::subtitle() const
457{
458 return "";
459}
460
461// LabelKeyboardEventTest
463{
465
466 Vec2 origin = Director::getInstance()->getVisibleOrigin();
467 Size size = Director::getInstance()->getVisibleSize();
468
469 auto statusLabel = Label::createWithSystemFont("No keyboard event received!", "", 20);
470 statusLabel->setPosition(origin + Vec2(size.width/2, size.height/2));
471 addChild(statusLabel);
472
473 auto listener = EventListenerKeyboard::create();
474 listener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event){
475 char buf[100] = {0};
476 sprintf(buf, "Key %d was pressed!", (int)keyCode);
477 auto label = static_cast<Label*>(event->getCurrentTarget());
478 label->setString(buf);
479 };
480
481 listener->onKeyReleased = [](EventKeyboard::KeyCode keyCode, Event* event){
482 char buf[100] = {0};
483 sprintf(buf, "Key %d was released!", (int)keyCode);
484 auto label = static_cast<Label*>(event->getCurrentTarget());
485 label->setString(buf);
486 };
487
488 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, statusLabel);
489}
490
492{
493 return "Label Receives Keyboard Event";
494}
495
497{
498 return "Please click keyboard\n(Only available on Desktop, Android\nand Windows Universal Apps)";
499}
500
501// SpriteAccelerationEventTest
503{
504#define FIX_POS(_pos, _min, _max) \
505if (_pos < _min) \
506_pos = _min; \
507else if (_pos > _max) \
508_pos = _max; \
509
511
512 Vec2 origin = Director::getInstance()->getVisibleOrigin();
513 Size size = Director::getInstance()->getVisibleSize();
514
515 Device::setAccelerometerEnabled(true);
516
517 auto sprite = Sprite::create(s_Ball);
518 sprite->setPosition(origin + Vec2(size.width/2, size.height/2));
519 addChild(sprite);
520
521 auto listener = EventListenerAcceleration::create([=](Acceleration* acc, Event* event){
522 auto ballSize = sprite->getContentSize();
523
524 auto ptNow = sprite->getPosition();
525
526 log("acc: x = %lf, y = %lf", acc->x, acc->y);
527
528 ptNow.x += acc->x * 9.81f;
529 ptNow.y += acc->y * 9.81f;
530
531 FIX_POS(ptNow.x, (VisibleRect::left().x+ballSize.width / 2.0), (VisibleRect::right().x - ballSize.width / 2.0f));
532 FIX_POS(ptNow.y, (VisibleRect::bottom().y+ballSize.height / 2.0), (VisibleRect::top().y - ballSize.height / 2.0f));
533 sprite->setPosition(ptNow);
534 });
535
536 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite);
537}
538
540{
541 Device::setAccelerometerEnabled(false);
542 EventDispatcherTestDemo::onExit();
543}
544
546{
547 return "Sprite Receives Acceleration Event";
548}
549
551{
552 return "Please move your device\n(Only available on mobile)";
553}
554
555// RemoveAndRetainNodeTest
557{
558 _spriteSaved = false;
559
561
562 Vec2 origin = Director::getInstance()->getVisibleOrigin();
563 Size size = Director::getInstance()->getVisibleSize();
564
565 _sprite = Sprite::create("Images/CyanSquare.png");
566 _sprite->setPosition(origin+Vec2(size.width/2, size.height/2));
567 addChild(_sprite, 10);
568
569 // Make sprite1 touchable
570 auto listener1 = EventListenerTouchOneByOne::create();
571 listener1->setSwallowTouches(true);
572
573 listener1->onTouchBegan = [](Touch* touch, Event* event){
574 auto target = static_cast<Sprite*>(event->getCurrentTarget());
575
576 Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
577 Size s = target->getContentSize();
578 Rect rect = Rect(0, 0, s.width, s.height);
579
580 if (rect.containsPoint(locationInNode))
581 {
582 log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
583 target->setOpacity(180);
584 return true;
585 }
586 return false;
587 };
588
589 listener1->onTouchMoved = [](Touch* touch, Event* event){
590 auto target = static_cast<Sprite*>(event->getCurrentTarget());
591 target->setPosition(target->getPosition() + touch->getDelta());
592 };
593
594 listener1->onTouchEnded = [=](Touch* touch, Event* event){
595 auto target = static_cast<Sprite*>(event->getCurrentTarget());
596 log("sprite onTouchesEnded.. ");
597 target->setOpacity(255);
598 };
599
600 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1, _sprite);
601
602 this->runAction(Sequence::create(DelayTime::create(5.0f),
603 CallFunc::create([this](){
604 _spriteSaved = true;
605 _sprite->retain();
606 _sprite->removeFromParentAndCleanup(false);
607 }),
608 DelayTime::create(5.0f),
609 CallFunc::create([this](){
610 _spriteSaved = false;
611 this->addChild(_sprite);
612 _sprite->release();
613 }),
614 nullptr
615 ));
616}
617
619{
620 EventDispatcherTestDemo::onExit();
621 if (_spriteSaved)
622 {
623 _sprite->release();
624 }
625}
626
628{
629 return "RemoveAndRetainNodeTest";
630}
631
633{
634 return "Sprite should be removed after 5s, add to scene again after 5s";
635}
636
637//RemoveListenerAfterAddingTest
639{
641
642 auto item1 = MenuItemFont::create("Click Me 1", [this](Ref* sender){
643 auto listener = EventListenerTouchOneByOne::create();
644 listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{
645 CCASSERT(false, "Should not come here!");
646 return true;
647 };
648
649 _eventDispatcher->addEventListenerWithFixedPriority(listener, -1);
650 _eventDispatcher->removeEventListener(listener);
651 });
652
653 item1->setPosition(VisibleRect::center() + Vec2(0.0f, 80.0f));
654
655 auto addNextButton = [this](){
656 auto next = MenuItemFont::create("Please Click Me To Reset!", [this](Ref* sender){
658 });
659 next->setPosition(VisibleRect::center() + Vec2(0.0f, -40.0f));
660
661 auto menu = Menu::create(next, nullptr);
662 menu->setPosition(VisibleRect::leftBottom());
663 menu->setAnchorPoint(Vec2::ZERO);
664 this->addChild(menu);
665 };
666
667 auto item2 = MenuItemFont::create("Click Me 2", [=](Ref* sender){
668 auto listener = EventListenerTouchOneByOne::create();
669 listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{
670 CCASSERT(false, "Should not come here!");
671 return true;
672 };
673
674 _eventDispatcher->addEventListenerWithFixedPriority(listener, -1);
675 _eventDispatcher->removeEventListenersForType(EventListener::Type::TOUCH_ONE_BY_ONE);
676
677 addNextButton();
678 });
679
680 item2->setPosition(VisibleRect::center() + Vec2(0.0f, 40.0f));
681
682 auto item3 = MenuItemFont::create("Click Me 3", [=](Ref* sender){
683 auto listener = EventListenerTouchOneByOne::create();
684 listener->onTouchBegan = [](Touch* touch, Event* event) -> bool{
685 CCASSERT(false, "Should not come here!");
686 return true;
687 };
688
689 _eventDispatcher->addEventListenerWithFixedPriority(listener, -1);
690 _eventDispatcher->removeAllEventListeners();
691
692 addNextButton();
693 });
694
695 item3->setPosition(VisibleRect::center());
696
697 auto menu = Menu::create(item1, item2, item3, nullptr);
698 menu->setPosition(VisibleRect::leftBottom());
699 menu->setAnchorPoint(Vec2::ZERO);
700
701 addChild(menu);
702}
703
705{
706 EventDispatcherTestDemo::onExit();
707}
708
710{
711 return "RemoveListenerAfterAddingTest";
712}
713
715{
716 return "Should not crash!";
717}
718
719
720//
721//DirectorEventTest
722//
724:_count1(0)
725,_count2(0)
726,_count3(0)
727,_count4(0)
728{
729
730}
731
733{
735
736 Size s = Director::getInstance()->getWinSize();
737
738 TTFConfig ttfConfig("fonts/arial.ttf", 20);
739
740 _label1 = Label::createWithTTF(ttfConfig, "Update: 0");
741 _label1->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
742 _label1->setPosition(30,s.height/2 + 60);
743 this->addChild(_label1);
744
745 _label2 = Label::createWithTTF(ttfConfig, "Visit: 0");
746 _label2->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
747 _label2->setPosition(30,s.height/2 + 20);
748 this->addChild(_label2);
749
750 _label3 = Label::createWithTTF(ttfConfig, "Draw: 0");
751 _label3->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
752 _label3->setPosition(30,30);
753 _label3->setPosition(30,s.height/2 - 20);
754 this->addChild(_label3);
755
756 _label4 = Label::createWithTTF(ttfConfig, "Projection: 0");
757 _label4->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
758 _label4->setPosition(30,30);
759 _label4->setPosition(30,s.height/2 - 60);
760 this->addChild(_label4);
761
762 auto dispatcher = Director::getInstance()->getEventDispatcher();
763
764 _event1 = dispatcher->addCustomEventListener(Director::EVENT_AFTER_UPDATE, std::bind(&DirectorEventTest::onEvent1, this, std::placeholders::_1));
765 _event2 = dispatcher->addCustomEventListener(Director::EVENT_AFTER_VISIT, std::bind(&DirectorEventTest::onEvent2, this, std::placeholders::_1));
766 _event3 = dispatcher->addCustomEventListener(Director::EVENT_AFTER_DRAW, [&](EventCustom *event) {
767 char buf[20];
768 snprintf(buf, sizeof(buf)-1, "Draw: %d", _count3++);
769 _label3->setString(buf);
770 });
771 _event4 = dispatcher->addCustomEventListener(Director::EVENT_PROJECTION_CHANGED, [&](EventCustom *event) {
772 char buf[20];
773 snprintf(buf, sizeof(buf)-1, "Projection: %d", _count4++);
774 _label4->setString(buf);
775 });
776
777 _event1->retain();
778 _event2->retain();
779 _event3->retain();
780 _event4->retain();
781
782 scheduleUpdate();
783}
784
786{
787 static float time = 0;
788
789 time += dt;
790 if(time > 0.5) {
791 Director::getInstance()->setProjection(Director::Projection::_2D);
792 time = 0;
793 }
794}
795
797{
798 EventDispatcherTestDemo::onExit();
799
800 Director::getInstance()->setProjection(Director::Projection::DEFAULT);
801
802 auto dispatcher = Director::getInstance()->getEventDispatcher();
803 dispatcher->removeEventListener(_event1);
804 dispatcher->removeEventListener(_event2);
805 dispatcher->removeEventListener(_event3);
806 dispatcher->removeEventListener(_event4);
807
808 _event1->release();
809 _event2->release();
810 _event3->release();
811 _event4->release();
812}
813
814void DirectorEventTest::onEvent1(EventCustom *event)
815{
816 char buf[20];
817 snprintf(buf, sizeof(buf)-1, "Update: %d", _count1++);
818 _label1->setString(buf);
819}
820
821void DirectorEventTest::onEvent2(EventCustom *event)
822{
823 char buf[20];
824 snprintf(buf, sizeof(buf)-1, "Visit: %d", _count2++);
825 _label2->setString(buf);
826}
827
828
829std::string DirectorEventTest::title() const
830{
831 return "Testing Director Events";
832}
833
835{
836 return "after visit, after draw, after update, projection changed";
837}
838
839// GlobalZTouchTest
841: _sprite(nullptr)
842, _accum(0)
843{
844
845 auto listener = EventListenerTouchOneByOne::create();
846 listener->setSwallowTouches(true);
847
848 listener->onTouchBegan = [](Touch* touch, Event* event){
849 auto target = static_cast<Sprite*>(event->getCurrentTarget());
850
851 Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation());
852 Size s = target->getContentSize();
853 Rect rect = Rect(0, 0, s.width, s.height);
854
855 if (rect.containsPoint(locationInNode))
856 {
857 log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y);
858 target->setOpacity(180);
859 return true;
860 }
861 return false;
862 };
863
864 listener->onTouchMoved = [](Touch* touch, Event* event){
865 auto target = static_cast<Sprite*>(event->getCurrentTarget());
866 target->setPosition(target->getPosition() + touch->getDelta());
867 };
868
869 listener->onTouchEnded = [=](Touch* touch, Event* event){
870 auto target = static_cast<Sprite*>(event->getCurrentTarget());
871 log("sprite onTouchesEnded.. ");
872 target->setOpacity(255);
873 };
874
875 const int SPRITE_COUNT = 8;
876
877 for (int i = 0; i < SPRITE_COUNT; i++)
878 {
879 Sprite *sprite;
880 if(i==4)
881 {
882 sprite = Sprite::create("Images/CyanSquare.png");
883 _sprite = sprite;
884 _sprite->setGlobalZOrder(-1);
885 }
886 else
887 {
888 sprite = Sprite::create("Images/YellowSquare.png");
889 }
890
891 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(), sprite);
892
893 this->addChild(sprite);
894
895 Size visibleSize = Director::getInstance()->getVisibleSize();
896 sprite->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y);
897 }
898
899 this->scheduleUpdate();
900}
901
903{
904 _accum += dt;
905 if( _accum > 2.0f) {
906 float z = _sprite->getGlobalZOrder();
907 _sprite->setGlobalZOrder(-z);
908 _accum = 0;
909 }
910}
911
912std::string GlobalZTouchTest::title() const
913{
914 return "Global Z Value, Try touch blue sprite";
915}
916
917std::string GlobalZTouchTest::subtitle() const
918{
919 return "Blue Sprite should change go from foreground to background";
920}
921
923{
924 static const int TAG_BLUE_SPRITE = 101;
925 static const int TAG_BLUE_SPRITE2 = 102;
926
927 auto touchOneByOneListener = EventListenerTouchOneByOne::create();
928 touchOneByOneListener->setSwallowTouches(true);
929
930 touchOneByOneListener->onTouchBegan = [=](Touch* touch, Event* event){
931 // Skip if don't touch top half screen.
932 if (!this->isPointInTopHalfAreaOfScreen(touch->getLocation()))
933 return false;
934
935 auto target = static_cast<Sprite*>(event->getCurrentTarget());
936 CCASSERT(target->getTag() == TAG_BLUE_SPRITE, "Yellow blocks shouldn't response event.");
937
938 if (this->isPointInNode(touch->getLocation(), target))
939 {
940 target->setOpacity(180);
941 return true;
942 }
943
944 // Stop propagation, so yellow blocks will not be able to receive event.
945 event->stopPropagation();
946 return false;
947 };
948
949 touchOneByOneListener->onTouchEnded = [=](Touch* touch, Event* event){
950 auto target = static_cast<Sprite*>(event->getCurrentTarget());
951 target->setOpacity(255);
952 };
953
954 auto touchAllAtOnceListener = EventListenerTouchAllAtOnce::create();
955 touchAllAtOnceListener->onTouchesBegan = [=](const std::vector<Touch*>& touches, Event* event){
956 // Skip if don't touch top half screen.
957 if (this->isPointInTopHalfAreaOfScreen(touches[0]->getLocation()))
958 return;
959
960 auto target = static_cast<Sprite*>(event->getCurrentTarget());
961 CCASSERT(target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
962
963 if (this->isPointInNode(touches[0]->getLocation(), target))
964 {
965 target->setOpacity(180);
966 }
967 // Stop propagation, so yellow blocks will not be able to receive event.
968 event->stopPropagation();
969 };
970
971 touchAllAtOnceListener->onTouchesEnded = [=](const std::vector<Touch*>& touches, Event* event){
972 // Skip if don't touch top half screen.
973 if (this->isPointInTopHalfAreaOfScreen(touches[0]->getLocation()))
974 return;
975
976 auto target = static_cast<Sprite*>(event->getCurrentTarget());
977 CCASSERT(target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
978
979 if (this->isPointInNode(touches[0]->getLocation(), target))
980 {
981 target->setOpacity(255);
982 }
983 // Stop propagation, so yellow blocks will not be able to receive event.
984 event->stopPropagation();
985 };
986
987 auto keyboardEventListener = EventListenerKeyboard::create();
988 keyboardEventListener->onKeyPressed = [](EventKeyboard::KeyCode /*key*/, Event* event){
989 auto target = static_cast<Sprite*>(event->getCurrentTarget());
990 CC_UNUSED_PARAM(target);
991 CCASSERT(target->getTag() == TAG_BLUE_SPRITE || target->getTag() == TAG_BLUE_SPRITE2, "Yellow blocks shouldn't response event.");
992 // Stop propagation, so yellow blocks will not be able to receive event.
993 event->stopPropagation();
994 };
995
996 const int SPRITE_COUNT = 8;
997
998 for (int i = 0; i < SPRITE_COUNT; i++)
999 {
1000 Sprite* sprite;
1001 Sprite* sprite2;
1002
1003 if(i==4)
1004 {
1005 sprite = Sprite::create("Images/CyanSquare.png");
1006 sprite->setTag(TAG_BLUE_SPRITE);
1007 addChild(sprite, 100);
1008
1009 sprite2 = Sprite::create("Images/CyanSquare.png");
1010 sprite2->setTag(TAG_BLUE_SPRITE2);
1011 addChild(sprite2, 100);
1012 }
1013 else
1014 {
1015 sprite = Sprite::create("Images/YellowSquare.png");
1016 addChild(sprite, 0);
1017 sprite2 = Sprite::create("Images/YellowSquare.png");
1018 addChild(sprite2, 0);
1019 }
1020
1021 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchOneByOneListener->clone(), sprite);
1022 _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardEventListener->clone(), sprite);
1023
1024 _eventDispatcher->addEventListenerWithSceneGraphPriority(touchAllAtOnceListener->clone(), sprite2);
1025 _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardEventListener->clone(), sprite2);
1026
1027
1028 Size visibleSize = Director::getInstance()->getVisibleSize();
1029 sprite->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y + sprite2->getContentSize().height/2 +10);
1030 sprite2->setPosition(VisibleRect::left().x + visibleSize.width / (SPRITE_COUNT - 1) * i, VisibleRect::center().y - sprite2->getContentSize().height/2-10);
1031 }
1032}
1033
1034bool StopPropagationTest::isPointInNode(Vec2 pt, Node* node)
1035{
1036 Vec2 locationInNode = node->convertToNodeSpace(pt);
1037 Size s = node->getContentSize();
1038 Rect rect = Rect(0, 0, s.width, s.height);
1039
1040 if (rect.containsPoint(locationInNode))
1041 {
1042 return true;
1043 }
1044 return false;
1045}
1046
1048{
1049 Size winSize = Director::getInstance()->getWinSize();
1050
1051 if (pt.y >= winSize.height/2) {
1052 return true;
1053 }
1054
1055 return false;
1056}
1057
1059{
1060 return "Stop Propagation Test";
1061}
1062
1064{
1065 return "Shouldn't crash and only blue block could be clicked";
1066}
1067
1068// PauseResumeTargetTest
1070{
1071 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1072 Size size = Director::getInstance()->getVisibleSize();
1073
1074 auto sprite1 = TouchableSprite::create();
1075 sprite1->setTexture("Images/CyanSquare.png");
1076 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 40.0f));
1077 addChild(sprite1, -10);
1078
1079 auto sprite2 = TouchableSprite::create();
1080 sprite2->setTexture("Images/MagentaSquare.png");
1081 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
1082 addChild(sprite2, -20);
1083
1084 auto sprite3 = TouchableSprite::create(100); // Sprite3 uses fixed priority listener
1085 sprite3->setTexture("Images/YellowSquare.png");
1086 sprite3->setPosition(Vec2(0, 0));
1087 sprite2->addChild(sprite3, -1);
1088
1089 auto popup = MenuItemFont::create("Popup", [=](Ref* sender){
1090
1091 sprite3->getListener()->setEnabled(false);
1092 _eventDispatcher->pauseEventListenersForTarget(this, true);
1093
1094 auto colorLayer = LayerColor::create(Color4B(0, 0, 255, 100));
1095 this->addChild(colorLayer, 99999);
1096
1097 auto closeItem = MenuItemFont::create("close", [=](Ref* sender){
1098 colorLayer->removeFromParent();
1099 _eventDispatcher->resumeEventListenersForTarget(this, true);
1100 sprite3->getListener()->setEnabled(true);
1101 });
1102
1103 closeItem->setPosition(VisibleRect::center());
1104
1105 auto closeMenu = Menu::create(closeItem, nullptr);
1106 closeMenu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1107 closeMenu->setPosition(Vec2::ZERO);
1108
1109 colorLayer->addChild(closeMenu);
1110 });
1111
1112 popup->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1113 popup->setPosition(VisibleRect::right());
1114
1115 auto menu = Menu::create(popup, nullptr);
1116 menu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1117 menu->setPosition(Vec2::ZERO);
1118
1119 addChild(menu);
1120}
1121
1123{
1124}
1125
1127{
1128 return "PauseResumeTargetTest";
1129}
1130
1132{
1133 return "Yellow block uses fixed priority";
1134}
1135
1136// PauseResumeTargetTest2
1138{
1139 MenuItemFont::getFontSize();
1140 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1141 Size size = Director::getInstance()->getVisibleSize();
1142
1144 _touchableSprite->retain();
1145 _touchableSprite->setTexture("Images/CyanSquare.png");
1146 _touchableSprite->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 40.0f));
1147 addChild(_touchableSprite);
1148
1149 _itemPauseTouch = MenuItemFont::create("pauseTouch", [=](Ref* sender){
1150 _itemPauseTouch->setEnabled(false);
1151 _itemResumeTouch->setEnabled(true);
1152
1153 _eventDispatcher->pauseEventListenersForTarget(_touchableSprite);
1154 });
1155
1156 _itemPauseTouch->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1157 _itemPauseTouch->setPosition(VisibleRect::right() + Vec2(-150.0f, 0.0f));
1158
1159 _itemResumeTouch = MenuItemFont::create("resumeTouch", [=](Ref* sender){
1160 _itemPauseTouch->setEnabled(true);
1161 _itemResumeTouch->setEnabled(false);
1162
1163 _eventDispatcher->resumeEventListenersForTarget(_touchableSprite);
1164 });
1165
1166 _itemResumeTouch->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1167 _itemResumeTouch->setPosition(VisibleRect::right() + Vec2(0, 0));
1168
1169 _itemAddToScene = MenuItemFont::create("addToScene", [=](Ref* sender){
1170 _itemAddToScene->setEnabled(false);
1171 _itemRemoveFromScene->setEnabled(true);
1172
1173 this->addChild(_touchableSprite);
1174 });
1175
1176 _itemAddToScene->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1177 _itemAddToScene->setPosition(VisibleRect::right() + Vec2(-150.0f, -50.0f));
1178
1179 _itemRemoveFromScene = MenuItemFont::create("removeFromScene", [=](Ref* sender){
1180 _itemAddToScene->setEnabled(true);
1181 _itemRemoveFromScene->setEnabled(false);
1182 _touchableSprite->removeFromParentAndCleanup(false);
1183 });
1184
1185 _itemRemoveFromScene->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1186 _itemRemoveFromScene->setPosition(VisibleRect::right() + Vec2(0.0f, -50.0f));
1187
1188 _itemAddToScene->setEnabled(false);
1189 _itemResumeTouch->setEnabled(false);
1190
1191 _itemPauseTouch->setFontSizeObj(20);
1192 _itemResumeTouch->setFontSizeObj(20);
1193 _itemAddToScene->setFontSizeObj(20);
1194 _itemRemoveFromScene->setFontSizeObj(20);
1195
1196 auto menu = Menu::create(_itemPauseTouch, _itemResumeTouch, _itemAddToScene, _itemRemoveFromScene, nullptr);
1197 menu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1198 menu->setPosition(Vec2::ZERO);
1199
1200 addChild(menu);
1201}
1202
1204{
1205 _touchableSprite->release();
1206}
1207
1209{
1210 return "PauseResumeTargetTest2";
1211}
1212
1214{
1215 return "";
1216}
1217
1218// PauseResumeTargetTest3
1220{
1221 MenuItemFont::getFontSize();
1222 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1223 Size size = Director::getInstance()->getVisibleSize();
1224
1225 _touchableSprite = Sprite::create("Images/CyanSquare.png");
1226 _touchableSprite->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 40.0f));
1227 addChild(_touchableSprite);
1228
1229 auto item = MenuItemFont::create("addListener", [=](Ref* sender){
1230
1231 MenuItemFont* senderItem = static_cast<MenuItemFont*>(sender);
1232 senderItem->setEnabled(false);
1233
1234 auto listener = EventListenerTouchOneByOne::create();
1235 listener->setSwallowTouches(true);
1236
1237 listener->onTouchBegan = [=](Touch* touch, Event* event){
1238 Vec2 locationInNode = _touchableSprite->convertToNodeSpace(touch->getLocation());
1239 Size s = _touchableSprite->getContentSize();
1240 Rect rect = Rect(0, 0, s.width, s.height);
1241
1242 if (rect.containsPoint(locationInNode))
1243 {
1244 log("TouchableSprite: onTouchBegan ...");
1245 _touchableSprite->setColor(Color3B::RED);
1246 return true;
1247 }
1248 return false;
1249 };
1250
1251 listener->onTouchEnded = [this](Touch* touch, Event* event){
1252 log("TouchableSprite: onTouchEnded ...");
1253 _touchableSprite->setColor(Color3B::WHITE);
1254 };
1255
1256 _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _touchableSprite);
1257 _eventDispatcher->pauseEventListenersForTarget(_touchableSprite);
1258 });
1259
1260 item->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1261 item->setPosition(VisibleRect::right());
1262
1263 auto menu = Menu::create(item, nullptr);
1264 menu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1265 menu->setPosition(Vec2::ZERO);
1266
1267 addChild(menu);
1268}
1269
1271{
1272
1273}
1274
1276{
1277 return "PauseResumeTargetTest3";
1278}
1279
1281{
1282 return "Sprite should not be touchable";
1283}
1284
1285// Issue4129
1287: _bugFixed(false)
1288{
1289 _customlistener = _eventDispatcher->addCustomEventListener(EVENT_COME_TO_BACKGROUND, [this](EventCustom* event){
1290
1291 auto label = Label::createWithSystemFont("Yeah, this issue was fixed.", "", 20);
1292 label->setAnchorPoint(Vec2(0.0f, 0.5f));
1293 label->setPosition(Vec2(VisibleRect::left() + Vec2(0.0f, 30.0f)));
1294 this->addChild(label);
1295
1296 // After test, remove it.
1297 _eventDispatcher->removeEventListener(_customlistener);
1298 _customlistener = nullptr;
1299
1300 _bugFixed = true;
1301 });
1302
1303 auto removeAllTouchItem = MenuItemFont::create("Remove All Listeners", [this](Ref* sender){
1304 auto senderItem = static_cast<MenuItemFont*>(sender);
1305 senderItem->setString("Only 'Reset' item could be clicked");
1306
1307 _eventDispatcher->removeAllEventListeners();
1308
1309 auto nextItem = MenuItemFont::create("Reset", [=](Ref* sender){
1310 CCASSERT(_bugFixed, "This issue was not fixed!");
1312 });
1313
1314 nextItem->setFontSizeObj(16);
1315 nextItem->setPosition(VisibleRect::right() + Vec2(-100.0f, -30.0f));
1316
1317 auto menu2 = Menu::create(nextItem, nullptr);
1318 menu2->setPosition(Vec2(0, 0));
1319 menu2->setAnchorPoint(Vec2(0, 0));
1320 this->addChild(menu2);
1321
1322 // Simulate to dispatch 'come to background' event
1323 _eventDispatcher->dispatchCustomEvent(EVENT_COME_TO_BACKGROUND);
1324 });
1325
1326 removeAllTouchItem->setFontSizeObj(16);
1327 removeAllTouchItem->setPosition(VisibleRect::right() + Vec2(-100.0f, 0.0f));
1328
1329 auto menu = Menu::create(removeAllTouchItem, nullptr);
1330 menu->setPosition(Vec2(0, 0));
1331 menu->setAnchorPoint(Vec2(0, 0));
1332 addChild(menu);
1333}
1334
1336{
1337 if (_customlistener)
1338 {
1339 _eventDispatcher->removeEventListener(_customlistener);
1340 }
1341}
1342
1343std::string Issue4129::title() const
1344{
1345 return "Issue 4129: Remove All Listeners";
1346}
1347
1348std::string Issue4129::subtitle() const
1349{
1350 return "Should see 'Yeah, this issue was fixed.'";
1351}
1352
1353// Issue4160
1355{
1356 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1357 Size size = Director::getInstance()->getVisibleSize();
1358
1359 auto sprite1 = TouchableSprite::create(-30);
1360 sprite1->setTexture("Images/CyanSquare.png");
1361 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80.0f, 40.0f));
1362 addChild(sprite1, -10);
1363
1364 auto sprite2 = TouchableSprite::create(-20);
1365 sprite2->setTexture("Images/MagentaSquare.png");
1366 sprite2->removeListenerOnTouchEnded(true);
1367 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
1368 addChild(sprite2, -20);
1369
1370 auto sprite3 = TouchableSprite::create(-10);
1371 sprite3->setTexture("Images/YellowSquare.png");
1372 sprite3->setPosition(Vec2(0, 0));
1373 sprite2->addChild(sprite3, -1);
1374}
1375
1377{
1378}
1379
1380std::string Issue4160::title() const
1381{
1382 return "Issue 4160: Out of range exception";
1383}
1384
1385std::string Issue4160::subtitle() const
1386{
1387 return "Touch the red block twice \n should not crash and the red one couldn't be touched";
1388}
1389
1390// DanglingNodePointersTest
1392{
1393public:
1394
1395 typedef std::function<void (DanglingNodePointersTestSprite * sprite)> TappedCallback;
1396
1398 {
1399 auto ret = new (std::nothrow) DanglingNodePointersTestSprite(tappedCallback);
1400
1401 if (ret && ret->init())
1402 {
1403 ret->autorelease();
1404 return ret;
1405 }
1406
1407 CC_SAFE_DELETE(ret);
1408 return nullptr;
1409 }
1410
1411protected:
1412
1414 :
1415 _eventListener(nullptr),
1416 _tappedCallback(tappedCallback)
1417 {
1418
1419 }
1420
1421public:
1422
1423 void onEnter() override
1424 {
1425 Sprite::onEnter();
1426
1427 _eventListener = EventListenerTouchOneByOne::create();
1428 _eventListener->setSwallowTouches(false);
1429
1430 _eventListener->onTouchBegan = [this](Touch* touch, Event* event) -> bool
1431 {
1432 _tappedCallback(this);
1433 return false; // Don't claim the touch so it can propagate
1434 };
1435
1436 _eventListener->onTouchEnded = [](Touch* touch, Event* event)
1437 {
1438 // Do nothing
1439 };
1440
1441 _eventDispatcher->addEventListenerWithSceneGraphPriority(_eventListener, this);
1442 }
1443
1444 void onExit() override
1445 {
1446 _eventDispatcher->removeEventListenersForTarget(this);
1447 _eventListener = nullptr;
1448 Sprite::onExit();
1449 }
1450
1451private:
1452 EventListenerTouchOneByOne* _eventListener;
1454};
1455
1457{
1458#if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS == 1 && COCOS2D_DEBUG > 0
1459 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1460 Size size = Director::getInstance()->getVisibleSize();
1461
1462 auto callback2 = [](DanglingNodePointersTestSprite * sprite2)
1463 {
1464 CCASSERT(false, "This should never be called because the sprite gets removed from it's parent and destroyed!");
1465 exit(1);
1466 };
1467
1468 auto callback1 = [callback2, origin, size](DanglingNodePointersTestSprite * sprite1)
1469 {
1470 DanglingNodePointersTestSprite * sprite2 = dynamic_cast<DanglingNodePointersTestSprite*>(sprite1->getChildren().at(0));
1471 CCASSERT(sprite2, "The first child of sprite 1 should be sprite 2!");
1472 CCASSERT(sprite2->getReferenceCount() == 1, "There should only be 1 reference to sprite 1, from it's parent node. Hence removing it will destroy it!");
1473 sprite1->removeAllChildren(); // This call should cause sprite 2 to be destroyed
1474
1475 // Recreate sprite 1 again
1476 sprite2 = DanglingNodePointersTestSprite::create(callback2);
1477 sprite2->setTexture("Images/MagentaSquare.png");
1478 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
1479 sprite1->addChild(sprite2, -20);
1480 };
1481
1482 auto sprite1 = DanglingNodePointersTestSprite::create(callback1); // Sprite 1 will receive touch before sprite 2
1483 sprite1->setTexture("Images/CyanSquare.png");
1484 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2));
1485 addChild(sprite1, -10);
1486
1487 auto sprite2 = DanglingNodePointersTestSprite::create(callback2); // Sprite 2 will be removed when sprite 1 is touched, should never receive an event.
1488 sprite2->setTexture("Images/MagentaSquare.png");
1489 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
1490 sprite1->addChild(sprite2, -20);
1491
1492#endif
1493}
1494
1496{
1497
1498}
1499
1501{
1502 return "DanglingNodePointersTest";
1503}
1504
1506{
1507#if CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS == 1 && COCOS2D_DEBUG > 0
1508 return "Tap the square - should not crash!";
1509#else
1510 return "For test to work, must be compiled with:\n"
1511 "CC_NODE_DEBUG_VERIFY_EVENT_LISTENERS == 1\n&& COCOS2D_DEBUG > 0";
1512#endif
1513}
1514
1515
1517{
1518 Vec2 origin = Director::getInstance()->getVisibleOrigin();
1519 Size size = Director::getInstance()->getVisibleSize();
1520
1521 auto callback1 = [=](DanglingNodePointersTestSprite * sprite)
1522 {
1523 auto callback2 = [](DanglingNodePointersTestSprite * sprite)
1524 {
1525 CCASSERT(false, "This should never get called!");
1526 };
1527
1528 {
1529 AutoreleasePool pool;
1530
1531 auto sprite2 = DanglingNodePointersTestSprite::create(callback2);
1532 sprite2->setTexture("Images/CyanSquare.png");
1533 sprite2->setPosition(origin+Vec2(size.width/2, size.height/2));
1534
1535 addChild(sprite2, 0);
1536 removeChild(sprite2);
1537 }
1538 };
1539
1540 auto sprite1 = DanglingNodePointersTestSprite::create(callback1);
1541 sprite1->setTexture("Images/CyanSquare.png");
1542 sprite1->setPosition(origin+Vec2(size.width/2, size.height/2));
1543 addChild(sprite1, -10);
1544}
1545
1547{
1548 return "RegisterAndUnregisterWhileEventHanldingTest";
1549}
1550
1552{
1553 return "Tap the square multiple times - should not crash!";
1554}
1555
1556//
1558{
1559#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
1560 auto dispatcher = Director::getInstance()->getEventDispatcher();
1561 dispatcher->addCustomEventListener(GLViewImpl::EVENT_WINDOW_RESIZED, [](EventCustom* event) {
1562 // TODO: need to create resizeable window
1563 log("<<< WINDOW RESIZED! >>> ");
1564 });
1565 dispatcher->addCustomEventListener(GLViewImpl::EVENT_WINDOW_FOCUSED, [](EventCustom* event) {
1566 log("<<< WINDOW FOCUSED! >>> ");
1567 });
1568 dispatcher->addCustomEventListener(GLViewImpl::EVENT_WINDOW_UNFOCUSED, [](EventCustom* event) {
1569 log("<<< WINDOW BLURRED! >>> ");
1570 });
1571#endif
1572}
1573
1574std::string WindowEventsTest::title() const
1575{
1576 return "WindowEventsTest";
1577}
1578
1580{
1581#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
1582 return "Resize and Switch to another window and back. Read Logs.";
1583#else
1584 return "Unsupported platform.";
1585#endif
1586}
1587
1588
1589// https://github.com/cocos2d/cocos2d-x/issues/8194
1591{
1592 auto origin = Director::getInstance()->getVisibleOrigin();
1593 auto size = Director::getInstance()->getVisibleSize();
1594 static bool nodesAdded = false;
1595#define tagA 100
1596#define tagB 101
1597 // dispatch custom event in another custom event, make the custom event "Issue8194" take effect immediately
1598 _listener = getEventDispatcher()->addCustomEventListener(Director::EVENT_AFTER_UPDATE, [this](cocos2d::EventCustom *event){
1599 if (nodesAdded)
1600 {
1601 // CCLOG("Fire Issue8194 Event");
1602 getEventDispatcher()->dispatchCustomEvent("Issue8194");
1603
1604 // clear test nodes and listeners
1605 getEventDispatcher()->removeCustomEventListeners("Issue8194");
1606 removeChildByTag(tagA);
1607 removeChildByTag(tagB);
1608 nodesAdded = false;
1609 }
1610 });
1611
1612 // When click this menuitem, it will add two node A and B, then send a custom event.
1613 // Because Node B's localZOrder < A's, the custom event should process by node B.
1614 auto menuItem = MenuItemFont::create("Dispatch Custom Event", [this](Ref *sender) {
1615 // add nodeA to scene
1616 auto nodeA = Node::create();
1617 addChild(nodeA, 1, tagA);
1618
1619 cocos2d::EventListenerCustom* listenerA = cocos2d::EventListenerCustom::create("Issue8194", [&](cocos2d::EventCustom *event){
1620 _subtitleLabel->setString("Bug has been fixed.");
1621 event->stopPropagation();
1622 });
1623 getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenerA, nodeA);
1624
1625 // add nodeB to scene
1626 auto nodeB = Node::create();
1627 addChild(nodeB, -1, tagB);
1628
1629 cocos2d::EventListenerCustom* listenerB = cocos2d::EventListenerCustom::create("Issue8194", [&](cocos2d::EventCustom *event){
1630 _subtitleLabel->setString("Bug exist yet.");
1631 event->stopPropagation();
1632 });
1633 getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenerB, nodeB);
1634
1635 nodesAdded = true;
1636 });
1637
1638 menuItem->setPosition(origin.x + size.width/2, origin.y + size.height/2);
1639 auto menu = Menu::create(menuItem, nullptr);
1640 menu->setPosition(Vec2::ZERO);
1641 addChild(menu);
1642}
1643
1645{
1646 getEventDispatcher()->removeEventListener(_listener);
1647}
1648
1649std::string Issue8194::title() const
1650{
1651 return "Issue 8194";
1652}
1653
1654std::string Issue8194::subtitle() const
1655{
1656 return "After click button, should show 'Bug has been fixed.'";
1657}
1658
1660{
1661 auto origin = Director::getInstance()->getVisibleOrigin();
1662 auto size = Director::getInstance()->getVisibleSize();
1663
1664 auto nodeA = Node::create();
1665 addChild(nodeA);
1666
1667 _listener = cocos2d::EventListenerCustom::create("Issue9898", [&](cocos2d::EventCustom *event){
1668 _eventDispatcher->removeEventListener(_listener);
1669 _eventDispatcher->dispatchCustomEvent("Issue9898");
1670 });
1671 _eventDispatcher->addEventListenerWithSceneGraphPriority(_listener, nodeA);
1672
1673 auto menuItem = MenuItemFont::create("Dispatch Custom Event", [&](Ref *sender) {
1674 _eventDispatcher->dispatchCustomEvent("Issue9898");
1675 });
1676 menuItem->setPosition(origin.x + size.width/2, origin.y + size.height/2);
1677 auto menu = Menu::create(menuItem, nullptr);
1678 menu->setPosition(Vec2::ZERO);
1679 addChild(menu);
1680}
1681
1682std::string Issue9898::title() const
1683{
1684 return "Issue 9898";
1685}
1686
1687std::string Issue9898::subtitle() const
1688{
1689 return "Should not crash if dispatch event after remove\n event listener in callback";
1690}
#define ADD_TEST_CASE(__className__)
Definition: BaseTest.h:211
#define tagA
#define tagB
#define FIX_POS(_pos, _min, _max)
virtual void onEnter() override
cocos2d::EventListenerCustom * _listener
virtual std::string title() const override
cocos2d::EventListenerCustom * _listener2
virtual std::string subtitle() const override
virtual void onExit() override
virtual std::string subtitle() const override
virtual std::string title() const override
EventListenerTouchOneByOne * _eventListener
static DanglingNodePointersTestSprite * create(const TappedCallback &tappedCallback)
std::function< void(DanglingNodePointersTestSprite *sprite)> TappedCallback
DanglingNodePointersTestSprite(const TappedCallback &tappedCallback)
cocos2d::Label * _label4
virtual std::string title() const override
void onEvent2(cocos2d::EventCustom *event)
void onEvent1(cocos2d::EventCustom *event)
cocos2d::EventListenerCustom * _event1
virtual void onExit() override
cocos2d::Label * _label3
cocos2d::EventListenerCustom * _event4
virtual std::string subtitle() const override
virtual void onEnter() override
virtual void update(float dt) override
cocos2d::Label * _label1
cocos2d::Label * _label2
cocos2d::EventListenerCustom * _event3
cocos2d::EventListenerCustom * _event2
virtual std::string title() const override
virtual std::string title() const override
virtual void onEnter() override
virtual std::string subtitle() const override
virtual std::string subtitle() const override
virtual std::string title() const override
cocos2d::Sprite * _sprite
virtual void update(float dt) override
virtual std::string subtitle() const override
virtual std::string title() const override
cocos2d::EventListenerCustom * _customlistener
virtual std::string subtitle() const override
virtual std::string title() const override
cocos2d::EventListenerCustom * _listener
virtual std::string title() const override
virtual std::string subtitle() const override
cocos2d::EventListenerCustom * _listener
virtual std::string subtitle() const override
virtual std::string title() const override
virtual std::string title() const override
virtual std::string subtitle() const override
virtual void onEnter() override
cocos2d::MenuItemFont * _itemAddToScene
virtual std::string title() const override
cocos2d::MenuItemFont * _itemResumeTouch
virtual std::string subtitle() const override
cocos2d::Sprite * _touchableSprite
cocos2d::MenuItemFont * _itemPauseTouch
cocos2d::MenuItemFont * _itemRemoveFromScene
cocos2d::Sprite * _touchableSprite
virtual std::string subtitle() const override
virtual std::string title() const override
virtual std::string title() const override
virtual std::string subtitle() const override
virtual std::string subtitle() const override
virtual std::string title() const override
virtual void onEnter() override
virtual std::string subtitle() const override
virtual std::string title() const override
virtual void onExit() override
virtual std::string title() const override
virtual std::string subtitle() const override
virtual std::string subtitle() const override
virtual std::string title() const override
virtual std::string subtitle() const override
virtual std::string title() const override
virtual std::string title() const override
bool isPointInTopHalfAreaOfScreen(cocos2d::Vec2 pt)
virtual std::string subtitle() const override
bool isPointInNode(cocos2d::Vec2 pt, cocos2d::Node *node)
TestSuite * getTestSuite() const
Definition: BaseTest.h:83
virtual void onEnter() override
Definition: BaseTest.cpp:430
cocos2d::Label * _subtitleLabel
Definition: BaseTest.h:107
virtual void restartCurrTest()
Definition: BaseTest.cpp:299
virtual void enterNextTest()
Definition: BaseTest.cpp:309
void removeListenerOnTouchEnded(bool toRemove)
static TouchableSprite * create(int priority=0)
EventListener * getListener()
virtual void onExit() override
virtual bool init() override
virtual void onEnter() override
virtual std::string subtitle() const override
virtual std::string title() const override
static cocos2d::Vec2 top()
Definition: VisibleRect.cpp:57
static cocos2d::Vec2 center()
Definition: VisibleRect.cpp:69
static cocos2d::Vec2 bottom()
Definition: VisibleRect.cpp:63
static cocos2d::Vec2 left()
Definition: VisibleRect.cpp:45
static cocos2d::Vec2 leftBottom()
Definition: VisibleRect.cpp:87
static cocos2d::Vec2 right()
Definition: VisibleRect.cpp:51
virtual std::string title() const override
virtual std::string subtitle() const override
static const char s_Ball[]
Definition: testResource.h:53