cocos2dx源码:事件分发类


class Event : public Ref
{
    enum class Type
    {
        TOUCH,
        KEYBOARD,
        ACCELERATION,
        MOUSE,
        FOCUS,
        GAME_CONTROLLER,
        CUSTOM
    };
	Type _type;            ///< Event type
    bool _isStopped;       ///< whether the event has been stopped.
    Node* _currentTarget;  ///< Current target
}

Event类继承自Ref,包含三个成员:事件类型、是否停止标志和目标节点。上述代码也枚举出了所有事件类型。


class EventAcceleration : public Event
{
    Acceleration _acc;
}

EventAcceleration 类,包含一个 Acceleration  成员,Acceleration类比较简单,包含x, y, z, timestamp。


class EventController : public Event
{
    enum class ControllerEventType
    {
        CONNECTION,
        BUTTON_STATUS_CHANGED,
        AXIS_STATUS_CHANGED,
    };
	EventController(ControllerEventType type, Controller* controller, int keyCode);
    EventController(ControllerEventType type, Controller* controller, bool isConnected);

    ControllerEventType _controllerEventType;
    Controller* _controller;
    int _keyCode;
    bool _isConnected;
}

EventController 类,包含一个 ControllerEventType,Controller, _keyCode, _isConnected。参数类型不同的两个初始化函数。


class EventCustom : public Event
{
    EventCustom(const std::string& eventName);

    void* _userData;       ///< User data
    std::string _eventName;
}

EventCustom 类,包含两个成员:_userData, _eventName。


class EventTouch : public Event
{
    enum class EventCode
    {
        BEGAN,
        MOVED,
        ENDED,
        CANCELLED
    };
    EventCode _eventCode;
    std::vector<Touch*> _touches;
}

EventTouch 类,包含两个成员:_eventCode,_touches。


class EventListener : public Ref
{
    enum class Type
    {
        UNKNOWN,
        TOUCH_ONE_BY_ONE,
        TOUCH_ALL_AT_ONCE,
        KEYBOARD,
        MOUSE,
        ACCELERATION,
        FOCUS,
		GAME_CONTROLLER,
        CUSTOM
    };
    typedef std::string ListenerID;

    bool init(Type t, const ListenerID& listenerID, const std::function<void(Event*)>& callback);

    std::function<void(Event*)> _onEvent;   /// Event callback function
    Type _type;             /// Event listener type
    ListenerID _listenerID; /// Event listener ID
    bool _isRegistered;     /// Whether the listener has been added to dispatcher.
    int   _fixedPriority;   // The higher the number, the higher the priority, 0 is for scene graph base priority.
    Node* _node;            // scene graph based priority
    bool _paused;           // Whether the listener is paused
    bool _isEnabled;        // Whether the listener is enabled
}

EventListener 类,包含 _onEvent,_type,_listenerID,_isRegistered,_paused,_isEnabled。一个初始化方法init。


class EventListenerTouchOneByOne : public EventListener
{
    static const std::string LISTENER_ID = "__cc_touch_one_by_one";
    static EventListenerTouchOneByOne* create();    //以 Type::TOUCH_ONE_BY_ONE, LISTENER_ID 初始化
    virtual EventListenerTouchOneByOne* clone() override;    //重写clone方法,new、初始化并设置触摸函数,设置变量
    virtual bool checkAvailable() override;    //重写方法,以 onTouchBegan 为判断依据

    typedef std::function<bool(Touch*, Event*)> ccTouchBeganCallback;
    typedef std::function<void(Touch*, Event*)> ccTouchCallback;
    ccTouchBeganCallback onTouchBegan;
    ccTouchCallback onTouchMoved;
    ccTouchCallback onTouchEnded;
    ccTouchCallback onTouchCancelled;
    std::vector<Touch*> _claimedTouches;    //touch vector
    bool _needSwallow;                      //是否吞掉事件不向下传递
}

EventListenerTouchOneByOne 类,单点触摸,包含onTouch方法,会在dispatcher中调用。


class CC_DLL EventListenerCustom : public EventListener
{
    static EventListenerCustom* create(const std::string& eventName, const std::function<void(EventCustom*)>& callback);
    bool init(const ListenerID& listenerId, const std::function<void(EventCustom*)>& callback);

    std::function<void(EventCustom*)> _onCustomEvent;
}

EventListenerCustom 类,自定义监听事件。


enum class DirtyFlag
{
    NONE = 0,
    FIXED_PRIORITY = 1 << 0,
    SCENE_GRAPH_PRIORITY = 1 << 1,
    ALL = FIXED_PRIORITY | SCENE_GRAPH_PRIORITY
};
class EventListenerVector
{
    std::vector<EventListener*>* _fixedListeners;
    std::vector<EventListener*>* _sceneGraphListeners;
    ssize_t _gt0Index;
}

class EventDispatcher : public Ref
{
    void addEventListener(EventListener* listener);  //判断是否在分发状态,不在就调用 forceAddEventListener,在就加入_toAddedListeners vector中
    void addEventListenerWithSceneGraphPriority(EventListener* listener, Node* node); //设置关联节点,设置priority=0,设置register=true,再调用 addEventListener
    void addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority); //设置priority=fixedPriority,设置register=true,再调用 addEventListener
    EventListenerCustom* addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback); //EventListenerCustom::creatre,然后调用addEventListenerWithFixedPriority
    void removeEventListener(EventListener* listener); //先从sceneGraphPriorityListeners找并删除,然后再从fixedPriorityListeners找并删除,若找到了删除_priorityDirtyFlagMap中的值,若没找到在_toAddedListeners找并删除
    void removeEventListenersForType(EventListener::Type listenerType); //根据listenerType调用removeEventListenersForListenerID
    void removeEventListenersForTarget(Node* target, bool recursive = false); //删除某个节点上的所有监听,recursive 是否递归
    void removeCustomEventListeners(const std::string& customEventName); //删除自定义监听,通过string调用removeEventListenersForListenerID
    void removeAllEventListeners(); //出了_internalCustomListenerIDs中的key值,删除其他所有监听
    void pauseEventListenersForTarget(Node* target, bool recursive = false); //设置节点上_nodeListenersMap和_toAddedListeners上所有监听setPaused(true)
    void resumeEventListenersForTarget(Node* target, bool recursive = false); //设置节点上_nodeListenersMap和_toAddedListeners上所有监听setPaused(false),并调用setDirtyForNode
    void dispatchEvent(Event* event); //分发事件,更新Dirty节点updateDirtyFlagForSceneGraph,对于TOUCH类型调用dispatchTouchEvent,对MOUSE类型调用dispatchTouchEventToListeners,对其他类型调用dispatchEventToListeners
        void dispatchCustomEvent(const std::string &eventName, void *optionalUserData = nullptr); //设置自定义数据,调用dispatchEvent
    void EventDispatcher::dispatchTouchEvent(EventTouch* event) //先sortEventListeners,然后调用dispatchTouchEventToListeners,传递根据EventCode调用listener的onTouches方法
    void sortEventListeners(const EventListener::ListenerID& listenerID); //对于_priorityDirtyFlagMap中的listenerID监听,对不同的DirtyFlag分别调用sortEventListenersOfFixedPriority或sortEventListenersOfSceneGraphPriority
    void sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID, Node* rootNode); //根据关联节点的ZOrder由大到小排序监听
    void sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID); //根据_fixedPriority由小到大排序监听
    void dispatchTouchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent); 先调用priority<0的fixedPriorityListeners;然后调用sceneGraphPriorityListeners,对sceneGraphPriorityListeners判断节点是否可见可用;最后调用priority>0的fixedPriorityListeners调用onEvent
    void updateListeners(Event* event); //更新监听列表,对_isRegistered==false的监听删除,对_toAddedListeners的监听加到监听里,对_toRemovedListeners的列表删除
    void removeEventListenersForListenerID(const EventListener::ListenerID& listenerID); //在sceneGraphPriorityListeners,fixedPriorityListeners和_toAddedListeners中删除所有listenerID的key监听
    void forceAddEventListener(EventListener* listener);  //以listenerID 为key,把 listener 加入到 _listenerMap map中。若 priority 为 0 设置 DirtyFlag::SCENE_GRAPH_PRIORITY,并且调用 associateNodeAndEventListener ,resumeEventListenersForTarget ,若不为0 设置 DirtyFlag::FIXED_PRIORITY
    void associateNodeAndEventListener(Node* node, EventListener* listener); //链接节点与监听
    void dissociateNodeAndEventListener(Node* node, EventListener* listener); //解链节点与监听
     void dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent); //先调用priority<0的fixedPriorityListeners,然后调用sceneGraphPriorityListeners,最后调用priority>0的fixedPriorityListeners调用onEvent
    void setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag); //以listenerID为key设置到_priorityDirtyFlagMap中


    
    std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;  ///** Listeners map */
    std::unordered_map<EventListener::ListenerID, DirtyFlag> _priorityDirtyFlagMap; ///** The map of dirty flag */
    std::unordered_map<Node*, std::vector<EventListener*>*> _nodeListenersMap;  ///** The map of node and event listeners */
    std::unordered_map<Node*, int> _nodePriorityMap;  ///** The map of node and its event priority */
    std::unordered_map<float, std::vector<Node*>> _globalZOrderNodeMap;  ///** key: Global Z Order, value: Sorted Nodes */
    std::vector<EventListener*> _toAddedListeners;  ///** The listeners to be added after dispatching event */
    std::vector<EventListener*> _toRemovedListeners;  ///** The listeners to be removed after dispatching event */
    std::set<Node*> _dirtyNodes;  ///** The nodes were associated with scene graph based priority listeners */
    int _inDispatch;  ///** Whether the dispatcher is dispatching event */
    bool _isEnabled;  ///** Whether to enable dispatching event */
    int _nodePriorityIndex;
    std::set<std::string> _internalCustomListenerIDs;
}

EventListenerVector 类,总的监听map:_listenerMap中存key为listenerID,value为EventListenerVector实例。

EventDispatcher 类,添加监听方法addEventListener,最终就是把Event子类加到_listenerMap中的EventListenerVector实例里,分发事件dispatchEvent就是把EventListener子类先排序,后根据priority先调用<0的,然后是=0并且判断关联节点是否可用,最后是>0的事件调用_onEvent。这个_onEvent方法在构建EventListener子类时会传入回调方法。

猜你喜欢

转载自blog.csdn.net/m0_37609239/article/details/131563529