From 8fa969b39e9bf296d32c9828df8ce0e6d454cd84 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 18 Sep 2013 22:20:20 +0800 Subject: [PATCH 1/5] issue #2087: Init Event::_userData. --- cocos2dx/event_dispatcher/CCEvent.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cocos2dx/event_dispatcher/CCEvent.cpp b/cocos2dx/event_dispatcher/CCEvent.cpp index 1dc9294d83..9dbe5030ca 100644 --- a/cocos2dx/event_dispatcher/CCEvent.cpp +++ b/cocos2dx/event_dispatcher/CCEvent.cpp @@ -30,6 +30,7 @@ Event::Event(const std::string& type) : _type(type) , _isStopped(false) , _currentTarget(nullptr) +, _userData(nullptr) { } From 3985574c302ecef1f38255c0610b2ae4832845a7 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 18 Sep 2013 22:21:22 +0800 Subject: [PATCH 2/5] issue #2087: Bug fix in EventDispatcher: _isRegister fix. --- cocos2dx/event_dispatcher/CCEventDispatcher.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cocos2dx/event_dispatcher/CCEventDispatcher.cpp b/cocos2dx/event_dispatcher/CCEventDispatcher.cpp index 4be2cc89c0..84b848ebe1 100644 --- a/cocos2dx/event_dispatcher/CCEventDispatcher.cpp +++ b/cocos2dx/event_dispatcher/CCEventDispatcher.cpp @@ -172,12 +172,11 @@ void EventDispatcher::removeEventListener(EventListener* listener) for (auto itemIter = iter->second->begin(); itemIter != iter->second->end(); ++itemIter) { if ((*itemIter)->listener == listener) - { - listener->retain(); - + { + (*itemIter)->listener->_isRegistered = false; + (*itemIter)->listener->release(); if (_inDispatch == 0) { - (*itemIter)->listener->release(); delete (*itemIter); iter->second->erase(itemIter); } @@ -207,11 +206,6 @@ void EventDispatcher::removeEventListener(EventListener* listener) if (isFound) break; } - - if (isFound) - { - listener->release(); - } } void EventDispatcher::setPriority(EventListener* listener, int fixedPriority) @@ -610,6 +604,7 @@ void EventDispatcher::removeListenersForEventType(const std::string& eventType) { for (auto iter = listenerItemIter->second->begin(); iter != listenerItemIter->second->end(); ++iter) { + (*iter)->listener->_isRegistered = false; (*iter)->listener->release(); if (_inDispatch) { @@ -637,6 +632,7 @@ void EventDispatcher::removeAllListeners() { for (auto iter = listenerItemIter->second->begin(); iter != listenerItemIter->second->end(); ++iter) { + (*iter)->listener->_isRegistered = false; (*iter)->listener->release(); if (_inDispatch) { From 32089fa517973db933102355fef60da56baebbfd Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 18 Sep 2013 22:23:02 +0800 Subject: [PATCH 3/5] issue #2087: Adding new EventDispatcher Test. 1) RemoveListenerWhenDispatching 2) CustomEventTest 3) LabelKeyboardEventTest 4) SpriteAccelerationEventTest --- .../NewEventDispatcherTest.cpp | 237 +++++++++++++++++- .../NewEventDispatcherTest.h | 34 +++ 2 files changed, 267 insertions(+), 4 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 093758227a..171b760536 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -7,13 +7,18 @@ // #include "NewEventDispatcherTest.h" +#include "testResource.h" namespace { std::function createFunctions[] = { CL(TouchableSpriteTest), - CL(FixedPriorityTest) + CL(FixedPriorityTest), + CL(RemoveListenerWhenDispatching), + CL(CustomEventTest), + CL(LabelKeyboardEventTest), + CL(SpriteAccelerationEventTest) }; unsigned int TEST_CASE_COUNT = sizeof(createFunctions) / sizeof(createFunctions[0]); @@ -148,7 +153,7 @@ void TouchableSpriteTest::onEnter() if (rect.containsPoint(locationInNode)) { - log("sprite tag %d, began... x = %f, y = %f", target->getTag(), locationInNode.x, locationInNode.y); + log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y); target->setOpacity(180); return true; } @@ -162,7 +167,7 @@ void TouchableSpriteTest::onEnter() listener1->onTouchEnded = [=](Touch* touch, Event* event){ auto target = static_cast(event->getCurrentTarget()); - log("sprite tag %d onTouchesEnded.. ", target->getTag()); + log("sprite onTouchesEnded.. "); target->setOpacity(255); if (target == sprite2) { @@ -186,7 +191,7 @@ std::string TouchableSpriteTest::title() std::string TouchableSpriteTest::subtitle() { - return ""; + return "Please drag the blocks"; } // FixedPriorityChangedTest @@ -299,3 +304,227 @@ std::string FixedPriorityTest::subtitle() { return "Fixed Priority, Blue: 30, Red: 20, Yellow: 10\n The lower value the higher priority will be."; } + +// RemoveListenerWhenDispatching +void RemoveListenerWhenDispatching::onEnter() +{ + EventDispatcherTestDemo::onEnter(); + + auto dispatcher = EventDispatcher::getInstance(); + + Point origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + auto sprite1 = Sprite::create("Images/CyanSquare.png"); + sprite1->setPosition(origin+Point(size.width/2, size.height/2)); + addChild(sprite1, 10); + + // Make sprite1 touchable + auto listener1 = TouchEventListener::create(Touch::DispatchMode::ONE_BY_ONE); + listener1->setSwallowTouches(true); + setUserObject(listener1); + + std::shared_ptr firstClick(new bool(true)); + + listener1->onTouchBegan = [=](Touch* touch, Event* event){ + Point locationInNode = sprite1->convertToNodeSpace(touch->getLocation()); + Size s = sprite1->getContentSize(); + Rect rect = Rect(0, 0, s.width, s.height); + + if (rect.containsPoint(locationInNode)) + { + sprite1->setColor(Color3B::RED); + return true; + } + return false; + }; + + listener1->onTouchEnded = [=](Touch* touch, Event* event){ + sprite1->setColor(Color3B::WHITE); + }; + + dispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); + + auto statusLabel = LabelTTF::create("The sprite could be touched!", "", 20); + statusLabel->setPosition(origin + Point(size.width/2, size.height-90)); + addChild(statusLabel); + std::shared_ptr enable(new bool(true)); + // Enable/Disable item + auto toggleItem = MenuItemToggle::createWithCallback([=](Object* sender){ + if (*enable) + { + dispatcher->removeEventListener(listener1); + statusLabel->setString("The sprite could not be touched!"); + + (*enable) = false; + } + else + { + dispatcher->addEventListenerWithSceneGraphPriority(listener1, sprite1); + statusLabel->setString("The sprite could be touched!"); + + (*enable) = true; + } + }, MenuItemFont::create("Enabled"), MenuItemFont::create("Disabled"), NULL); + + toggleItem->setPosition(origin + Point(size.width/2, 80)); + auto menu = Menu::create(toggleItem, nullptr); + menu->setPosition(Point(0, 0)); + menu->setAnchorPoint(Point(0, 0)); + addChild(menu, -1); +} + +std::string RemoveListenerWhenDispatching::title() +{ + return "Add and remove listener\n when dispatching event"; +} + +std::string RemoveListenerWhenDispatching::subtitle() +{ + return ""; +} + +// CustomEventTest +void CustomEventTest::onEnter() +{ + EventDispatcherTestDemo::onEnter(); + + auto dispatcher = EventDispatcher::getInstance(); + + Point origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + auto statusLabel = LabelTTF::create("No custom event received!", "", 20); + statusLabel->setPosition(origin + Point(size.width/2, size.height-90)); + addChild(statusLabel); + + _listener = EventListener::create("game_custom_event", [=](Event* event){ + std::string str("Custom event received, "); + char* buf = static_cast(event->getUserData()); + str += buf; + str += " times"; + statusLabel->setString(str.c_str()); + delete[] buf; + }); + + dispatcher->addEventListenerWithFixedPriority(_listener, 1); + + auto sendItem = MenuItemFont::create("Send Custom Event", [=](Object* sender){ + static int count = 0; + ++count; + char* buf = new char[10]; + sprintf(buf, "%d", count); + Event event("game_custom_event"); + event.setUserData(buf); + dispatcher->dispatchEvent(&event); + }); + sendItem->setPosition(origin + Point(size.width/2, size.height/2)); + auto menu = Menu::create(sendItem, nullptr); + menu->setPosition(Point(0, 0)); + menu->setAnchorPoint(Point(0, 0)); + addChild(menu, -1); +} + +void CustomEventTest::onExit() +{ + EventDispatcher::getInstance()->removeEventListener(_listener); + EventDispatcherTestDemo::onExit(); +} + +std::string CustomEventTest::title() +{ + return "Send custom event"; +} + +std::string CustomEventTest::subtitle() +{ + return ""; +} + +// LabelKeyboardEventTest +void LabelKeyboardEventTest::onEnter() +{ + EventDispatcherTestDemo::onEnter(); + + auto dispatcher = EventDispatcher::getInstance(); + + Point origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + auto statusLabel = LabelTTF::create("No keyboard event received!", "", 20); + statusLabel->setPosition(origin + Point(size.width/2, size.height/2)); + addChild(statusLabel); + + auto listener = KeyboardEventListener::create(); + listener->onKeyPressed = [](KeyboardEvent::KeyCode keyCode, Event* event){ + char buf[100] = {0}; + sprintf(buf, "Key %d was pressed!", (int)keyCode); + auto label = static_cast(event->getCurrentTarget()); + label->setString(buf); + }; + + listener->onKeyReleased = [](KeyboardEvent::KeyCode keyCode, Event* event){ + char buf[100] = {0}; + sprintf(buf, "Key %d was released!", (int)keyCode); + auto label = static_cast(event->getCurrentTarget()); + label->setString(buf); + }; + + dispatcher->addEventListenerWithSceneGraphPriority(listener, statusLabel); +} + +std::string LabelKeyboardEventTest::title() +{ + return "Label Receives Keyboard Event"; +} + +std::string LabelKeyboardEventTest::subtitle() +{ + return "Please click keyboard\n(Only available on Desktop and Android)"; +} + +// SpriteAccelerationEventTest +void SpriteAccelerationEventTest::onEnter() +{ +#define FIX_POS(_pos, _min, _max) \ +if (_pos < _min) \ +_pos = _min; \ +else if (_pos > _max) \ +_pos = _max; \ + + EventDispatcherTestDemo::onEnter(); + + auto dispatcher = EventDispatcher::getInstance(); + + Point origin = Director::getInstance()->getVisibleOrigin(); + Size size = Director::getInstance()->getVisibleSize(); + + auto sprite = Sprite::create(s_Ball); + sprite->setPosition(origin + Point(size.width/2, size.height/2)); + addChild(sprite); + + auto listener = AccelerationEventListener::create([=](Acceleration* acc, Event* event){ + auto ballSize = sprite->getContentSize(); + + auto ptNow = sprite->getPosition(); + + ptNow.x -= acc->x ; + ptNow.y -= acc->y ; + + FIX_POS(ptNow.x, (VisibleRect::left().x+ballSize.width / 2.0), (VisibleRect::right().x - ballSize.width / 2.0)); + FIX_POS(ptNow.y, (VisibleRect::bottom().y+ballSize.height / 2.0), (VisibleRect::top().y - ballSize.height / 2.0)); + sprite->setPosition(ptNow); + }); + + dispatcher->addEventListenerWithSceneGraphPriority(listener, sprite); +} + +std::string SpriteAccelerationEventTest::title() +{ + return "Sprite Receives Acceleration Event"; +} + +std::string SpriteAccelerationEventTest::subtitle() +{ + return "Please move your device\n(Only available on mobile)"; +} \ No newline at end of file diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index a0a702215c..9a79ef8094 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -47,5 +47,39 @@ public: virtual std::string subtitle(); }; +class RemoveListenerWhenDispatching : public EventDispatcherTestDemo +{ +public: + virtual void onEnter(); + virtual std::string title(); + virtual std::string subtitle(); +}; + +class CustomEventTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual void onExit() override; + virtual std::string title() override; + virtual std::string subtitle() override; +private: + EventListener* _listener; +}; + +class LabelKeyboardEventTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual std::string title() override; + virtual std::string subtitle() override; +}; + +class SpriteAccelerationEventTest : public EventDispatcherTestDemo +{ +public: + virtual void onEnter() override; + virtual std::string title() override; + virtual std::string subtitle() override; +}; #endif /* defined(__samples__NewEventDispatcherTest__) */ From 8bb406a1ecdb106e9cecd2d17b3f299a9519ffb4 Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 18 Sep 2013 22:45:48 +0800 Subject: [PATCH 4/5] issue #2087: Enabling acc when testing it. --- .../NewEventDispatcherTest.cpp | 13 +++++++++++-- .../NewEventDispatcherTest/NewEventDispatcherTest.h | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp index 171b760536..8b22f3d6f5 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.cpp @@ -499,6 +499,8 @@ _pos = _max; \ Point origin = Director::getInstance()->getVisibleOrigin(); Size size = Director::getInstance()->getVisibleSize(); + Device::setAccelerometerEnabled(true); + auto sprite = Sprite::create(s_Ball); sprite->setPosition(origin + Point(size.width/2, size.height/2)); addChild(sprite); @@ -508,8 +510,10 @@ _pos = _max; \ auto ptNow = sprite->getPosition(); - ptNow.x -= acc->x ; - ptNow.y -= acc->y ; + log("acc: x = %lf, y = %lf", acc->x, acc->y); + + ptNow.x += acc->x * 9.81f; + ptNow.y += acc->y * 9.81f; FIX_POS(ptNow.x, (VisibleRect::left().x+ballSize.width / 2.0), (VisibleRect::right().x - ballSize.width / 2.0)); FIX_POS(ptNow.y, (VisibleRect::bottom().y+ballSize.height / 2.0), (VisibleRect::top().y - ballSize.height / 2.0)); @@ -519,6 +523,11 @@ _pos = _max; \ dispatcher->addEventListenerWithSceneGraphPriority(listener, sprite); } +void SpriteAccelerationEventTest::onExit() +{ + Device::setAccelerometerEnabled(false); +} + std::string SpriteAccelerationEventTest::title() { return "Sprite Receives Acceleration Event"; diff --git a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h index 9a79ef8094..ff23ac330b 100644 --- a/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h +++ b/samples/Cpp/TestCpp/Classes/NewEventDispatcherTest/NewEventDispatcherTest.h @@ -78,6 +78,7 @@ class SpriteAccelerationEventTest : public EventDispatcherTestDemo { public: virtual void onEnter() override; + virtual void onExit() override; virtual std::string title() override; virtual std::string subtitle() override; }; From 4288160d509d439a4f113c913282c09e585ea60b Mon Sep 17 00:00:00 2001 From: James Chen Date: Wed, 18 Sep 2013 22:47:50 +0800 Subject: [PATCH 5/5] issue #2087: Renaming EventDispatcherTest name to EventDispatcherTest(NEW) --- samples/Cpp/TestCpp/Classes/controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/Cpp/TestCpp/Classes/controller.cpp b/samples/Cpp/TestCpp/Classes/controller.cpp index 7717917111..fc2b73c985 100644 --- a/samples/Cpp/TestCpp/Classes/controller.cpp +++ b/samples/Cpp/TestCpp/Classes/controller.cpp @@ -42,7 +42,7 @@ struct { #endif { "CurrentLanguageTest", []() { return new CurrentLanguageTestScene(); } }, { "DrawPrimitivesTest", [](){return new DrawPrimitivesTestScene();} }, - { "EventDispatcherTest", []() { return new EventDispatcherTestScene(); } }, + { "EventDispatcherTest(NEW)", []() { return new EventDispatcherTestScene(); } }, { "EffectAdvancedTest", []() { return new EffectAdvanceScene(); } }, { "EffectsTest", [](){return new EffectTestScene();} }, { "ExtensionsTest", []() { return new ExtensionsTestScene(); } },