mirror of https://github.com/axmolengine/axmol.git
Merge pull request #4578 from dumganhar/event-dispatcher-fix
closed #3463: ListenerID is std::string now. To avoid hash collision when using lots of EventCustoms.
This commit is contained in:
commit
15c6295361
|
@ -26,6 +26,10 @@
|
|||
#include "CCEventTouch.h"
|
||||
#include "CCEventCustom.h"
|
||||
#include "CCEventListenerTouch.h"
|
||||
#include "CCEventListenerAcceleration.h"
|
||||
#include "CCEventListenerMouse.h"
|
||||
#include "CCEventListenerKeyboard.h"
|
||||
|
||||
#include "CCNode.h"
|
||||
#include "CCDirector.h"
|
||||
|
||||
|
@ -59,31 +63,30 @@ private:
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
static EventListener::ListenerID getListenerID(Event* event)
|
||||
static EventListener::ListenerID __getListenerID(Event* event)
|
||||
{
|
||||
EventListener::ListenerID ret;
|
||||
switch (event->getType())
|
||||
{
|
||||
case Event::Type::ACCELERATION:
|
||||
ret = static_cast<EventListener::ListenerID>(EventListener::Type::ACCELERATION);
|
||||
ret = EventListenerAcceleration::LISTENER_ID;
|
||||
break;
|
||||
case Event::Type::CUSTOM:
|
||||
{
|
||||
auto customEvent = static_cast<EventCustom*>(event);
|
||||
auto listenerID = std::hash<std::string>()(customEvent->getEventName());
|
||||
ret = static_cast<EventListener::ListenerID>(listenerID);
|
||||
ret = customEvent->getEventName();
|
||||
}
|
||||
break;
|
||||
case Event::Type::KEYBOARD:
|
||||
ret = static_cast<EventListener::ListenerID>(EventListener::Type::KEYBOARD);
|
||||
ret = EventListenerKeyboard::LISTENER_ID;
|
||||
break;
|
||||
case Event::Type::MOUSE:
|
||||
ret = static_cast<EventListener::ListenerID>(EventListener::Type::MOUSE);
|
||||
ret = EventListenerMouse::LISTENER_ID;
|
||||
break;
|
||||
case Event::Type::TOUCH:
|
||||
// Touch listener is very special, it contains two kinds of listeners, EventListenerTouchOneByOne and EventListenerTouchAllAtOnce.
|
||||
// return UNKNOW instead.
|
||||
ret = static_cast<EventListener::ListenerID>(EventListener::Type::UNKNOWN);
|
||||
// return UNKNOWN instead.
|
||||
CCASSERT(false, "Don't call this method if the event is for touch.");
|
||||
break;
|
||||
default:
|
||||
CCASSERT(false, "Invalid type!");
|
||||
|
@ -557,7 +560,7 @@ void EventDispatcher::dispatchEvent(Event* event)
|
|||
return;
|
||||
}
|
||||
|
||||
auto listenerID = getListenerID(event);
|
||||
auto listenerID = __getListenerID(event);
|
||||
|
||||
sortEventListeners(listenerID);
|
||||
|
||||
|
@ -580,14 +583,11 @@ void EventDispatcher::dispatchEvent(Event* event)
|
|||
|
||||
void EventDispatcher::dispatchTouchEvent(EventTouch* event)
|
||||
{
|
||||
auto touchOneByOneID = static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE);
|
||||
auto touchAllAtOnceID = static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE);
|
||||
sortEventListeners(EventListenerTouchOneByOne::LISTENER_ID);
|
||||
sortEventListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
|
||||
|
||||
sortEventListeners(touchOneByOneID);
|
||||
sortEventListeners(touchAllAtOnceID);
|
||||
|
||||
auto oneByOnelisteners = getListeners(touchOneByOneID);
|
||||
auto allAtOncelisteners = getListeners(touchAllAtOnceID);
|
||||
auto oneByOnelisteners = getListeners(EventListenerTouchOneByOne::LISTENER_ID);
|
||||
auto allAtOncelisteners = getListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
|
||||
|
||||
// If there aren't any touch listeners, return directly.
|
||||
if (nullptr == oneByOnelisteners && nullptr == allAtOncelisteners)
|
||||
|
@ -776,7 +776,7 @@ void EventDispatcher::dispatchTouchEvent(EventTouch* event)
|
|||
|
||||
void EventDispatcher::updateListeners(Event* event)
|
||||
{
|
||||
auto onUpdateListeners = [this](EventListener::ListenerID listenerID)
|
||||
auto onUpdateListeners = [this](const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
auto listenersIter = _listeners.find(listenerID);
|
||||
if (listenersIter == _listeners.end())
|
||||
|
@ -844,12 +844,12 @@ void EventDispatcher::updateListeners(Event* event)
|
|||
|
||||
if (event->getType() == Event::Type::TOUCH)
|
||||
{
|
||||
onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ONE_BY_ONE));
|
||||
onUpdateListeners(static_cast<EventListener::ListenerID>(EventListener::Type::TOUCH_ALL_AT_ONCE));
|
||||
onUpdateListeners(EventListenerTouchOneByOne::LISTENER_ID);
|
||||
onUpdateListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
onUpdateListeners(getListenerID(event));
|
||||
onUpdateListeners(__getListenerID(event));
|
||||
}
|
||||
|
||||
|
||||
|
@ -907,7 +907,7 @@ void EventDispatcher::updateDirtyFlagForSceneGraph()
|
|||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::sortEventListeners(EventListener::ListenerID listenerID)
|
||||
void EventDispatcher::sortEventListeners(const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
DirtyFlag dirtyFlag = DirtyFlag::NONE;
|
||||
|
||||
|
@ -933,7 +933,7 @@ void EventDispatcher::sortEventListeners(EventListener::ListenerID listenerID)
|
|||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::ListenerID listenerID)
|
||||
void EventDispatcher::sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
auto listeners = getListeners(listenerID);
|
||||
|
||||
|
@ -962,7 +962,7 @@ void EventDispatcher::sortEventListenersOfSceneGraphPriority(EventListener::List
|
|||
#endif
|
||||
}
|
||||
|
||||
void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::ListenerID listenerID)
|
||||
void EventDispatcher::sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
auto listeners = getListeners(listenerID);
|
||||
|
||||
|
@ -996,7 +996,7 @@ void EventDispatcher::sortEventListenersOfFixedPriority(EventListener::ListenerI
|
|||
|
||||
}
|
||||
|
||||
EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListener::ListenerID listenerID)
|
||||
EventDispatcher::EventListenerVector* EventDispatcher::getListeners(const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
auto iter = _listeners.find(listenerID);
|
||||
if (iter != _listeners.end())
|
||||
|
@ -1007,7 +1007,7 @@ EventDispatcher::EventListenerVector* EventDispatcher::getListeners(EventListene
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void EventDispatcher::removeEventListenersForListenerID(EventListener::ListenerID listenerID)
|
||||
void EventDispatcher::removeEventListenersForListenerID(const EventListener::ListenerID& listenerID)
|
||||
{
|
||||
auto listenerItemIter = _listeners.find(listenerID);
|
||||
if (listenerItemIter != _listeners.end())
|
||||
|
@ -1068,26 +1068,47 @@ void EventDispatcher::removeEventListenersForListenerID(EventListener::ListenerI
|
|||
|
||||
void EventDispatcher::removeEventListeners(EventListener::Type listenerType)
|
||||
{
|
||||
CCASSERT(listenerType != EventListener::Type::CUSTOM, "Not support custom event listener type, please use EventDispatcher::removeCustomEventListeners instead.");
|
||||
|
||||
removeEventListenersForListenerID(static_cast<EventListener::ListenerID>(listenerType));
|
||||
if (listenerType == EventListener::Type::TOUCH_ONE_BY_ONE)
|
||||
{
|
||||
removeEventListenersForListenerID(EventListenerTouchOneByOne::LISTENER_ID);
|
||||
}
|
||||
else if (listenerType == EventListener::Type::TOUCH_ALL_AT_ONCE)
|
||||
{
|
||||
removeEventListenersForListenerID(EventListenerTouchAllAtOnce::LISTENER_ID);
|
||||
}
|
||||
else if (listenerType == EventListener::Type::MOUSE)
|
||||
{
|
||||
removeEventListenersForListenerID(EventListenerMouse::LISTENER_ID);
|
||||
}
|
||||
else if (listenerType == EventListener::Type::ACCELERATION)
|
||||
{
|
||||
removeEventListenersForListenerID(EventListenerAcceleration::LISTENER_ID);
|
||||
}
|
||||
else if (listenerType == EventListener::Type::KEYBOARD)
|
||||
{
|
||||
removeEventListenersForListenerID(EventListenerKeyboard::LISTENER_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
CCASSERT(false, "Invalid listener type!");
|
||||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::removeCustomEventListeners(const std::string& customEventName)
|
||||
{
|
||||
removeEventListenersForListenerID(std::hash<std::string>()(customEventName));
|
||||
removeEventListenersForListenerID(customEventName);
|
||||
}
|
||||
|
||||
void EventDispatcher::removeAllEventListeners()
|
||||
{
|
||||
std::vector<EventListener::ListenerID> types(_listeners.size());
|
||||
|
||||
for (auto iter = _listeners.begin(); iter != _listeners.end(); ++iter)
|
||||
for (const auto& e : _listeners)
|
||||
{
|
||||
types.push_back(iter->first);
|
||||
types.push_back(e.first);
|
||||
}
|
||||
|
||||
for (auto& type : types)
|
||||
for (const auto& type : types)
|
||||
{
|
||||
removeEventListenersForListenerID(type);
|
||||
}
|
||||
|
@ -1118,7 +1139,7 @@ void EventDispatcher::setDirtyForNode(Node* node)
|
|||
}
|
||||
}
|
||||
|
||||
void EventDispatcher::setDirty(EventListener::ListenerID listenerID, DirtyFlag flag)
|
||||
void EventDispatcher::setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag)
|
||||
{
|
||||
auto iter = _priorityDirtyFlagMap.find(listenerID);
|
||||
if (iter == _priorityDirtyFlagMap.end())
|
||||
|
|
|
@ -148,22 +148,22 @@ private:
|
|||
void addEventListener(EventListener* listener);
|
||||
|
||||
/** Gets event the listener list for the event listener type. */
|
||||
EventListenerVector* getListeners(EventListener::ListenerID listenerID);
|
||||
EventListenerVector* getListeners(const EventListener::ListenerID& listenerID);
|
||||
|
||||
/** Update dirty flag */
|
||||
void updateDirtyFlagForSceneGraph();
|
||||
|
||||
/** Removes all listeners with the same event listener ID */
|
||||
void removeEventListenersForListenerID(EventListener::ListenerID listenerID);
|
||||
void removeEventListenersForListenerID(const EventListener::ListenerID& listenerID);
|
||||
|
||||
/** Sort event listener */
|
||||
void sortEventListeners(EventListener::ListenerID listenerID);
|
||||
void sortEventListeners(const EventListener::ListenerID& listenerID);
|
||||
|
||||
/** Sorts the listeners of specified type by scene graph priority */
|
||||
void sortEventListenersOfSceneGraphPriority(EventListener::ListenerID listenerID);
|
||||
void sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID);
|
||||
|
||||
/** Sorts the listeners of specified type by fixed priority */
|
||||
void sortEventListenersOfFixedPriority(EventListener::ListenerID listenerID);
|
||||
void sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID);
|
||||
|
||||
/** Updates all listeners
|
||||
* 1) Removes all listener items that have been marked as 'removed' when dispatching event.
|
||||
|
@ -193,7 +193,7 @@ private:
|
|||
};
|
||||
|
||||
/** Sets the dirty flag for a specified listener ID */
|
||||
void setDirty(EventListener::ListenerID listenerID, DirtyFlag flag);
|
||||
void setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag);
|
||||
|
||||
/** Walks though scene graph to get the draw order for each node, it's called before sorting event listener with scene graph priority */
|
||||
void visitTarget(Node* node);
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
CUSTOM
|
||||
};
|
||||
|
||||
typedef std::size_t ListenerID;
|
||||
typedef std::string ListenerID;
|
||||
|
||||
protected:
|
||||
/** Constructor */
|
||||
|
@ -83,7 +83,7 @@ protected:
|
|||
inline bool isRegistered() const { return _isRegistered; };
|
||||
|
||||
inline Type getType() const { return _type; };
|
||||
inline ListenerID getListenerID() const { return _listenerID; };
|
||||
inline const ListenerID& getListenerID() const { return _listenerID; };
|
||||
|
||||
inline void setFixedPriority(int fixedPriority) { _fixedPriority = fixedPriority; };
|
||||
inline int getFixedPriority() const { return _fixedPriority; };
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const std::string EventListenerAcceleration::LISTENER_ID = "__cc_acceleration";
|
||||
|
||||
EventListenerAcceleration::EventListenerAcceleration()
|
||||
{
|
||||
|
||||
|
@ -59,7 +61,7 @@ bool EventListenerAcceleration::init(std::function<void(Acceleration*, Event* ev
|
|||
this->onAccelerationEvent(&accEvent->_acc, event);
|
||||
};
|
||||
|
||||
if (EventListener::init(Type::ACCELERATION, static_cast<ListenerID>(Type::ACCELERATION), listener))
|
||||
if (EventListener::init(Type::ACCELERATION, LISTENER_ID, listener))
|
||||
{
|
||||
onAccelerationEvent = callback;
|
||||
return true;
|
||||
|
|
|
@ -33,6 +33,8 @@ NS_CC_BEGIN
|
|||
class EventListenerAcceleration : public EventListener
|
||||
{
|
||||
public:
|
||||
static const std::string LISTENER_ID;
|
||||
|
||||
static EventListenerAcceleration* create(std::function<void(Acceleration*, Event*)> callback);
|
||||
virtual ~EventListenerAcceleration();
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ EventListenerCustom::EventListenerCustom()
|
|||
EventListenerCustom* EventListenerCustom::create(const std::string& eventName, std::function<void(EventCustom*)> callback)
|
||||
{
|
||||
EventListenerCustom* ret = new EventListenerCustom();
|
||||
if (ret && ret->init(std::hash<std::string>()(eventName), callback))
|
||||
if (ret && ret->init(eventName, callback))
|
||||
{
|
||||
ret->autorelease();
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const std::string EventListenerKeyboard::LISTENER_ID = "__cc_keyboard";
|
||||
|
||||
bool EventListenerKeyboard::checkAvailable()
|
||||
{
|
||||
if (onKeyPressed == nullptr && onKeyReleased == nullptr)
|
||||
|
@ -92,7 +94,7 @@ bool EventListenerKeyboard::init()
|
|||
}
|
||||
};
|
||||
|
||||
if (EventListener::init(Type::KEYBOARD, static_cast<ListenerID>(Type::KEYBOARD), listener))
|
||||
if (EventListener::init(Type::KEYBOARD, LISTENER_ID, listener))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ class Event;
|
|||
class EventListenerKeyboard : public EventListener
|
||||
{
|
||||
public:
|
||||
static const std::string LISTENER_ID;
|
||||
|
||||
static EventListenerKeyboard* create();
|
||||
|
||||
/// Overrides
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const std::string EventListenerMouse::LISTENER_ID = "__cc_mouse";
|
||||
|
||||
bool EventListenerMouse::checkAvailable()
|
||||
{
|
||||
return true;
|
||||
|
@ -99,7 +101,7 @@ bool EventListenerMouse::init()
|
|||
}
|
||||
};
|
||||
|
||||
if (EventListener::init(Type::MOUSE, static_cast<ListenerID>(Type::MOUSE), listener))
|
||||
if (EventListener::init(Type::MOUSE, LISTENER_ID, listener))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ class Event;
|
|||
class EventListenerMouse : public EventListener
|
||||
{
|
||||
public:
|
||||
static const std::string LISTENER_ID;
|
||||
|
||||
static EventListenerMouse* create();
|
||||
|
||||
/// Overrides
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
const std::string EventListenerTouchOneByOne::LISTENER_ID = "__cc_touch_one_by_one";
|
||||
|
||||
EventListenerTouchOneByOne::EventListenerTouchOneByOne()
|
||||
: onTouchBegan(nullptr)
|
||||
, onTouchMoved(nullptr)
|
||||
|
@ -46,7 +48,7 @@ EventListenerTouchOneByOne::~EventListenerTouchOneByOne()
|
|||
|
||||
bool EventListenerTouchOneByOne::init()
|
||||
{
|
||||
if (EventListener::init(Type::TOUCH_ONE_BY_ONE, static_cast<ListenerID>(Type::TOUCH_ONE_BY_ONE), nullptr))
|
||||
if (EventListener::init(Type::TOUCH_ONE_BY_ONE, LISTENER_ID, nullptr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -107,6 +109,9 @@ EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()
|
|||
}
|
||||
|
||||
/////////
|
||||
|
||||
const std::string EventListenerTouchAllAtOnce::LISTENER_ID = "__cc_touch_all_at_once";
|
||||
|
||||
EventListenerTouchAllAtOnce::EventListenerTouchAllAtOnce()
|
||||
: onTouchesBegan(nullptr)
|
||||
, onTouchesMoved(nullptr)
|
||||
|
@ -122,7 +127,7 @@ EventListenerTouchAllAtOnce::~EventListenerTouchAllAtOnce()
|
|||
|
||||
bool EventListenerTouchAllAtOnce::init()
|
||||
{
|
||||
if (EventListener::init(Type::TOUCH_ALL_AT_ONCE, static_cast<ListenerID>(Type::TOUCH_ALL_AT_ONCE), nullptr))
|
||||
if (EventListener::init(Type::TOUCH_ALL_AT_ONCE, LISTENER_ID, nullptr))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ NS_CC_BEGIN
|
|||
class EventListenerTouchOneByOne : public EventListener
|
||||
{
|
||||
public:
|
||||
static const std::string LISTENER_ID;
|
||||
|
||||
static EventListenerTouchOneByOne* create();
|
||||
|
||||
virtual ~EventListenerTouchOneByOne();
|
||||
|
@ -67,8 +69,8 @@ private:
|
|||
class EventListenerTouchAllAtOnce : public EventListener
|
||||
{
|
||||
public:
|
||||
static const ListenerID ID = static_cast<ListenerID>(Type::TOUCH_ALL_AT_ONCE);
|
||||
|
||||
static const std::string LISTENER_ID;
|
||||
|
||||
static EventListenerTouchAllAtOnce* create();
|
||||
virtual ~EventListenerTouchAllAtOnce();
|
||||
|
||||
|
|
|
@ -195,7 +195,7 @@ bool EventListenerPhysicsContact::init()
|
|||
onEvent(event);
|
||||
};
|
||||
|
||||
return EventListenerCustom::init(std::hash<std::string>()(PHYSICSCONTACT_EVENT_NAME), func);
|
||||
return EventListenerCustom::init(PHYSICSCONTACT_EVENT_NAME, func);
|
||||
}
|
||||
|
||||
void EventListenerPhysicsContact::onEvent(EventCustom* event)
|
||||
|
|
Loading…
Reference in New Issue