Skip to content

Commit 95baff7

Browse files
James Chenminggo
authored andcommitted
fixed #17835: pauseEventListenersForTarget doesn't work correctly while in dispatching event (#17836)
* add test. * fixed #17835: pauseEventListenersForTarget doesn't work correctly while in dispatching event * remove a unneeded check
1 parent 1bfbf35 commit 95baff7

File tree

5 files changed

+201
-14
lines changed

5 files changed

+201
-14
lines changed

cocos/2d/CCNode.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ void Node::cleanup()
212212
this->stopAllActions();
213213
// timers
214214
this->unscheduleAllCallbacks();
215+
216+
_eventDispatcher->removeEventListenersForTarget(this);
215217

216218
for( const auto &child: _children)
217219
child->cleanup();

cocos/base/CCEventDispatcher.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,9 @@ void EventDispatcher::forceAddEventListener(EventListener* listener)
487487

488488
associateNodeAndEventListener(node, listener);
489489

490-
if (node->isRunning())
490+
if (!node->isRunning())
491491
{
492-
resumeEventListenersForTarget(node);
492+
listener->setPaused(true);
493493
}
494494
}
495495
else

cocos/base/CCEventListener.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ bool EventListener::init(Type t, const ListenerID& listenerID, const std::functi
4141
_type = t;
4242
_listenerID = listenerID;
4343
_isRegistered = false;
44-
_paused = true;
44+
_paused = false;
4545
_isEnabled = true;
4646

4747
return true;

tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp

Lines changed: 164 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ EventDispatcherTests::EventDispatcherTests()
2525
ADD_TEST_CASE(GlobalZTouchTest);
2626
ADD_TEST_CASE(StopPropagationTest);
2727
ADD_TEST_CASE(PauseResumeTargetTest);
28+
ADD_TEST_CASE(PauseResumeTargetTest2);
29+
ADD_TEST_CASE(PauseResumeTargetTest3);
2830
ADD_TEST_CASE(Issue4129);
2931
ADD_TEST_CASE(Issue4160);
3032
ADD_TEST_CASE(DanglingNodePointersTest);
@@ -169,30 +171,31 @@ class TouchableSprite : public Sprite
169171
, _removeListenerOnTouchEnded(false)
170172
{
171173
}
172-
173-
public:
174-
void onEnter() override
174+
175+
virtual bool init() override
175176
{
176-
Sprite::onEnter();
177-
177+
if (!Sprite::init())
178+
return false;
179+
178180
auto listener = EventListenerTouchOneByOne::create();
179181
listener->setSwallowTouches(true);
180182

181-
listener->onTouchBegan = [=](Touch* touch, Event* event){
182-
183+
listener->onTouchBegan = [this](Touch* touch, Event* event){
183184
Vec2 locationInNode = this->convertToNodeSpace(touch->getLocation());
184185
Size s = this->getContentSize();
185186
Rect rect = Rect(0, 0, s.width, s.height);
186187

187188
if (rect.containsPoint(locationInNode))
188189
{
190+
log("TouchableSprite: onTouchBegan ...");
189191
this->setColor(Color3B::RED);
190192
return true;
191193
}
192194
return false;
193195
};
194196

195197
listener->onTouchEnded = [this](Touch* touch, Event* event){
198+
log("TouchableSprite: onTouchEnded ...");
196199
this->setColor(Color3B::WHITE);
197200

198201
if (_removeListenerOnTouchEnded)
@@ -212,18 +215,19 @@ class TouchableSprite : public Sprite
212215
}
213216

214217
_listener = listener;
218+
return true;
215219
}
216220

217-
void onExit() override
221+
virtual void onExit() override
218222
{
219-
if (_listener != nullptr)
223+
if (_listener != nullptr && _fixedPriority != 0)
220224
{
221225
_eventDispatcher->removeEventListener(_listener);
222226
}
223227

224228
Sprite::onExit();
225229
}
226-
230+
public:
227231
void removeListenerOnTouchEnded(bool toRemove) { _removeListenerOnTouchEnded = toRemove; };
228232

229233
inline EventListener* getListener() { return _listener; };
@@ -575,7 +579,7 @@ void RemoveAndRetainNodeTest::onEnter()
575579
CallFunc::create([this](){
576580
_spriteSaved = true;
577581
_sprite->retain();
578-
_sprite->removeFromParent();
582+
_sprite->removeFromParentAndCleanup(false);
579583
}),
580584
DelayTime::create(5.0f),
581585
CallFunc::create([this](){
@@ -1104,6 +1108,155 @@ std::string PauseResumeTargetTest::subtitle() const
11041108
return "Yellow block uses fixed priority";
11051109
}
11061110

1111+
// PauseResumeTargetTest2
1112+
PauseResumeTargetTest2::PauseResumeTargetTest2()
1113+
{
1114+
MenuItemFont::getFontSize();
1115+
Vec2 origin = Director::getInstance()->getVisibleOrigin();
1116+
Size size = Director::getInstance()->getVisibleSize();
1117+
1118+
_touchableSprite = TouchableSprite::create();
1119+
_touchableSprite->retain();
1120+
_touchableSprite->setTexture("Images/CyanSquare.png");
1121+
_touchableSprite->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80, 40));
1122+
addChild(_touchableSprite);
1123+
1124+
_itemPauseTouch = MenuItemFont::create("pauseTouch", [=](Ref* sender){
1125+
_itemPauseTouch->setEnabled(false);
1126+
_itemResumeTouch->setEnabled(true);
1127+
1128+
_eventDispatcher->pauseEventListenersForTarget(_touchableSprite);
1129+
});
1130+
1131+
_itemPauseTouch->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1132+
_itemPauseTouch->setPosition(VisibleRect::right() + Vec2(-150, 0));
1133+
1134+
_itemResumeTouch = MenuItemFont::create("resumeTouch", [=](Ref* sender){
1135+
_itemPauseTouch->setEnabled(true);
1136+
_itemResumeTouch->setEnabled(false);
1137+
1138+
_eventDispatcher->resumeEventListenersForTarget(_touchableSprite);
1139+
});
1140+
1141+
_itemResumeTouch->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1142+
_itemResumeTouch->setPosition(VisibleRect::right() + Vec2(0, 0));
1143+
1144+
_itemAddToScene = MenuItemFont::create("addToScene", [=](Ref* sender){
1145+
_itemAddToScene->setEnabled(false);
1146+
_itemRemoveFromScene->setEnabled(true);
1147+
1148+
this->addChild(_touchableSprite);
1149+
});
1150+
1151+
_itemAddToScene->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1152+
_itemAddToScene->setPosition(VisibleRect::right() + Vec2(-150, -50));
1153+
1154+
_itemRemoveFromScene = MenuItemFont::create("removeFromScene", [=](Ref* sender){
1155+
_itemAddToScene->setEnabled(true);
1156+
_itemRemoveFromScene->setEnabled(false);
1157+
_touchableSprite->removeFromParentAndCleanup(false);
1158+
});
1159+
1160+
_itemRemoveFromScene->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1161+
_itemRemoveFromScene->setPosition(VisibleRect::right() + Vec2(0, -50));
1162+
1163+
_itemAddToScene->setEnabled(false);
1164+
_itemResumeTouch->setEnabled(false);
1165+
1166+
_itemPauseTouch->setFontSizeObj(20);
1167+
_itemResumeTouch->setFontSizeObj(20);
1168+
_itemAddToScene->setFontSizeObj(20);
1169+
_itemRemoveFromScene->setFontSizeObj(20);
1170+
1171+
auto menu = Menu::create(_itemPauseTouch, _itemResumeTouch, _itemAddToScene, _itemRemoveFromScene, nullptr);
1172+
menu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1173+
menu->setPosition(Vec2::ZERO);
1174+
1175+
addChild(menu);
1176+
}
1177+
1178+
PauseResumeTargetTest2::~PauseResumeTargetTest2()
1179+
{
1180+
_touchableSprite->release();
1181+
}
1182+
1183+
std::string PauseResumeTargetTest2::title() const
1184+
{
1185+
return "PauseResumeTargetTest2";
1186+
}
1187+
1188+
std::string PauseResumeTargetTest2::subtitle() const
1189+
{
1190+
return "";
1191+
}
1192+
1193+
// PauseResumeTargetTest3
1194+
PauseResumeTargetTest3::PauseResumeTargetTest3()
1195+
{
1196+
MenuItemFont::getFontSize();
1197+
Vec2 origin = Director::getInstance()->getVisibleOrigin();
1198+
Size size = Director::getInstance()->getVisibleSize();
1199+
1200+
_touchableSprite = Sprite::create("Images/CyanSquare.png");
1201+
_touchableSprite->setPosition(origin+Vec2(size.width/2, size.height/2) + Vec2(-80, 40));
1202+
addChild(_touchableSprite);
1203+
1204+
auto item = MenuItemFont::create("addListener", [=](Ref* sender){
1205+
1206+
MenuItemFont* senderItem = static_cast<MenuItemFont*>(sender);
1207+
senderItem->setEnabled(false);
1208+
1209+
auto listener = EventListenerTouchOneByOne::create();
1210+
listener->setSwallowTouches(true);
1211+
1212+
listener->onTouchBegan = [=](Touch* touch, Event* event){
1213+
Vec2 locationInNode = _touchableSprite->convertToNodeSpace(touch->getLocation());
1214+
Size s = _touchableSprite->getContentSize();
1215+
Rect rect = Rect(0, 0, s.width, s.height);
1216+
1217+
if (rect.containsPoint(locationInNode))
1218+
{
1219+
log("TouchableSprite: onTouchBegan ...");
1220+
_touchableSprite->setColor(Color3B::RED);
1221+
return true;
1222+
}
1223+
return false;
1224+
};
1225+
1226+
listener->onTouchEnded = [this](Touch* touch, Event* event){
1227+
log("TouchableSprite: onTouchEnded ...");
1228+
_touchableSprite->setColor(Color3B::WHITE);
1229+
};
1230+
1231+
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _touchableSprite);
1232+
_eventDispatcher->pauseEventListenersForTarget(_touchableSprite);
1233+
});
1234+
1235+
item->setAnchorPoint(Vec2::ANCHOR_MIDDLE_RIGHT);
1236+
item->setPosition(VisibleRect::right());
1237+
1238+
auto menu = Menu::create(item, nullptr);
1239+
menu->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
1240+
menu->setPosition(Vec2::ZERO);
1241+
1242+
addChild(menu);
1243+
}
1244+
1245+
PauseResumeTargetTest3::~PauseResumeTargetTest3()
1246+
{
1247+
1248+
}
1249+
1250+
std::string PauseResumeTargetTest3::title() const
1251+
{
1252+
return "PauseResumeTargetTest3";
1253+
}
1254+
1255+
std::string PauseResumeTargetTest3::subtitle() const
1256+
{
1257+
return "Sprite should not be touchable";
1258+
}
1259+
11071260
// Issue4129
11081261
Issue4129::Issue4129()
11091262
: _bugFixed(false)

tests/cpp-tests/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,38 @@ class PauseResumeTargetTest : public EventDispatcherTestDemo
168168
private:
169169
};
170170

171+
class PauseResumeTargetTest2 : public EventDispatcherTestDemo
172+
{
173+
public:
174+
CREATE_FUNC(PauseResumeTargetTest2);
175+
PauseResumeTargetTest2();
176+
virtual ~PauseResumeTargetTest2();
177+
178+
virtual std::string title() const override;
179+
virtual std::string subtitle() const override;
180+
181+
private:
182+
cocos2d::Sprite* _touchableSprite;
183+
cocos2d::MenuItemFont* _itemPauseTouch;
184+
cocos2d::MenuItemFont* _itemResumeTouch;
185+
cocos2d::MenuItemFont* _itemAddToScene;
186+
cocos2d::MenuItemFont* _itemRemoveFromScene;
187+
};
188+
189+
class PauseResumeTargetTest3 : public EventDispatcherTestDemo
190+
{
191+
public:
192+
CREATE_FUNC(PauseResumeTargetTest3);
193+
PauseResumeTargetTest3();
194+
virtual ~PauseResumeTargetTest3();
195+
196+
virtual std::string title() const override;
197+
virtual std::string subtitle() const override;
198+
199+
private:
200+
cocos2d::Sprite* _touchableSprite;
201+
};
202+
171203
class Issue4129 : public EventDispatcherTestDemo
172204
{
173205
public:

0 commit comments

Comments
 (0)