源码分析 EventDispatcher、EventListener、Event 源码分析 (新触摸机制,新的NotificationCenter机制)【上】

admin 2018-3-27 181

源码版本来自3.x,转载请注明

cocos2d-x 源码分析总目录

http://blog.csdn.net/u011225840/article/details/31743129


1.继承结构

1.1 结构

      不详吐槽太多,也不贴图了,贴图要审核好久好久好久好久。
      从小到大,先来看下Event的结构。
      1.Event--------EventTouch,EventCustom,EventMouse,EventKeyboard,EventFocus,EventAcceleration
       其中,EventTouch 和 EventCustom是比较特殊的两个Event。EventTouch是3.x版本的触摸机制相关的Event,而EventCustom则是3.x自定义事件机制的基础,该机制取代了2.x版本中的NotificationCenter。
      2.EventListener-------------EventListenerTouchOneByOne,EventListenerTouchAllAtOnce,EventListenerCustom,EventListenerFocus,EventListenerMouse....对应
      相比于Event,Listener多了一个,因为对应的Touch被拆分成了两个Listener,一个是OneByone,一个是TouchAllAtOnce。前者是onTouchBegan等函数的Listener,后者是onTouchesBegan等函数的Listener。

1.2.EventDispatcher,EventListener,Event三者的关系

       Event相当于data,EventListener包含了data与fuction的一种映射关系,而EventDispatcher相当于一个Manager,管理着EventListener,决定着Event的调用顺序。
       Event中包含了type,target等信息;EventListener包含了ListenerID,相关联的Node,对应的callBack;EventDispatcher里含有各种map,vector来管理不同的Listener。具体的,可以看源码分析。

2.源码分析

        本次源码分析的量比较大,大家要有心理准备哟~

2.1Event相关

2.1.1 Event

  1. enum class Type  
  2.    {  
  3.        TOUCH,  
  4.        KEYBOARD,  
  5.        ACCELERATION,  
  6.        MOUSE,  
  7.        FOCUS,  
  8.        CUSTOM  
  9.    };  
  10.    Type _type;     ///< Event type  
  11.      
  12.    bool _isStopped;       ///< whether the event has been stopped.  
  13.    Node* _currentTarget;  
      
      Event主要包含了三个重要的变量,type,是一个enum变量,里面定义了类型;isStopped定义该event是否已经停止,当一个event发生停止时,与其相关的Listener都要停止callback的调用;currentTarget是与该Event相关联的node。

2.1.2 EventTouch

    EventTouch是cocos2d-x引擎中非常非常重要的事件。对应于四种touch操作,该类内部定义了四种EventCode
    
  1. enum class EventCode  
  2.    {  
  3.        BEGAN,  
  4.        MOVED,  
  5.        ENDED,  
  6.        CANCELLED  
  7.    };  

      不同的EventCode可以告诉Listener来调用不同的callback。
       除此之外,EventTouch中含有std::vector<Touch*> _touches 来记录该事件相关的touch,值得注意的是,本版本默认含有的触摸点最大是5个。

2.1.3 EventCustom

     EventCustom的出现取代了统治2.x版本多年的NotificationCenter,来看下EventCustom的两个重要成员变量。
  1. void* _userData;       ///< User data  
  2. std::string _eventName;  

      有没有似曾相识的感觉,还是一样的key,还是一样的userData(有点不一样。原来是CCObject*)。
       其他的Event因为重要性以及使用度的原因,这里不再赘述,如果以后笔者对他们有新的认识,将会在这里进行添加。

2.2 EventListener相关

2.2.1 EventListener

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

       重要的成员变量:
      1.onEvent,是绑定于该Listener的callback function,该func的声明使用了c++11的新特性。
      2.type与Event类似,增加一个Unknown的属性。
      3.isRegistered变量非常重要,如果他没有被注册,则他的事件不会触发。
      4.优先级代表了响应一个事件时的顺序,该值越低,越先响应。
      5.node 代表了与该listener相关的node,用于 scene graph类的事件响应,具体的在Dispatcher里面有进行介绍。
      6.最后说下ListenerID,这是该类型事件的标识符。除了EventCustomListener的ListerID是与name相关的,其余的ListenerID都是固定的,用于标识该类EventListener。
     
  1. /** Enables or disables the listener 
  2.     *  @note Only listeners with `enabled` state will be able to receive events. 
  3.     *        When an listener was initialized, it's enabled by default. 
  4.     *        An event listener can receive events when it is enabled and is not paused. 
  5.     *        paused state is always false when it is a fixed priority listener. 
  6.     */  
  7.    inline void setEnabled(bool enabled) { _isEnabled = enabled; };  
  1. /** Sets paused state for the listener 
  2.      *  The paused state is only used for scene graph priority listeners. 
  3.      *  `EventDispatcher::resumeAllEventListenersForTarget(node)` will set the paused state to `true`, 
  4.      *  while `EventDispatcher::pauseAllEventListenersForTarget(node)` will set it to `false`. 
  5.      *  @note 1) Fixed priority listeners will never get paused. If a fixed priority doesn't want to receive events, 
  6.      *           call `setEnabled(false)` instead. 
  7.      *        2) In `Node`'s onEnter and onExit, the `paused state` of the listeners which associated with that node will be automatically updated. 
  8.      */  
  9.     inline void setPaused(bool paused) { _paused = paused; };  

      上面两段话,解释了什么时候一个Listener是可以接收事件,什么时候是不可以的。
       1.一个Listener想接收事件必须是enabled true 并且 paused false。
      2.值得注意的是,pause的变量专门是为了scenGraph类的事件存在的(后续有说明),而且一个Node的onEnter和onExit 事件会影响到与Node相关的该类事件的pause状态。

2.2.2 EventListenerOneByOne

     
  1.     /// Overrides  
  2.     virtual EventListenerTouchOneByOne* clone() override;  
  3.     virtual bool checkAvailable() override;  
  4.     //  
  5.   
  6. public:  
  7.     std::function<bool(Touch*, Event*)> onTouchBegan;  
  8.     std::function<void(Touch*, Event*)> onTouchMoved;  
  9.     std::function<void(Touch*, Event*)> onTouchEnded;  
  10.     std::function<void(Touch*, Event*)> onTouchCancelled;  

        上面的是OneByOne重载父类的方法,以及自己本身需要被绑定4个callBack 函数。
        
        
  1. EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()  
  2. {  
  3.     //深拷贝  
  4.     auto ret = new EventListenerTouchOneByOne();  
  5.     if (ret && ret->init())  
  6.     {  
  7.         ret->autorelease();  
  8.           
  9.         ret->onTouchBegan = onTouchBegan;  
  10.         ret->onTouchMoved = onTouchMoved;  
  11.         ret->onTouchEnded = onTouchEnded;  
  12.         ret->onTouchCancelled = onTouchCancelled;  
  13.           
  14.         ret->_claimedTouches = _claimedTouches;  
  15.         ret->_needSwallow = _needSwallow;  
  16.     }  
  17.     else  
  18.     {  
  19.         CC_SAFE_DELETE(ret);  
  20.     }  
  21.     return ret;  
  22. }  

  1. bool EventListenerTouchOneByOne::checkAvailable()  
  2. {  
  3.     // EventDispatcher will use the return value of 'onTouchBegan' to determine whether to pass following 'move', 'end'  
  4.     // message to 'EventListenerTouchOneByOne' or not. So 'onTouchBegan' needs to be set.  
  5.     //OneByOne只需要onTouchBegan不为空,则可以认为其是可用的。  
  6.     if (onTouchBegan == nullptr)  
  7.     {  
  8.         CCASSERT(false"Invalid EventListenerTouchOneByOne!");  
  9.         return false;  
  10.     }  
  11.       
  12.     return true;  
  13. }  
       什么是可用性,当在dispatcher进行事件分发时,如果一个Listener是不可用的,则不会将该事件分发给他。
  1. std::vector<Touch*> _claimedTouches;  
  2. bool _needSwallow;  

        OneByOne的touch是可以设置吞噬属性的。

2.2.3 EventListenerAllAtOnce

        
  1. std::function<void(const std::vector<Touch*>&, Event*)> onTouchesBegan;  
  2. std::function<void(const std::vector<Touch*>&, Event*)> onTouchesMoved;  
  3. std::function<void(const std::vector<Touch*>&, Event*)> onTouchesEnded;  
  4. std::function<void(const std::vector<Touch*>&, Event*)> onTouchesCancelled;  

        AllAtOnce就是所谓的standard touch处理机制,一次性处理所有的touch。
       值得注意的是AllAtOnce的checkAvailable要求,上述四个函数指针都不能为空。
       
  1. bool EventListenerTouchAllAtOnce::checkAvailable()  
  2. {  
  3.     if (onTouchesBegan == nullptr && onTouchesMoved == nullptr  
  4.         && onTouchesEnded == nullptr && onTouchesCancelled == nullptr)  
  5.     {  
  6.         CCASSERT(false"Invalid EventListenerTouchAllAtOnce!");  
  7.         return false;  
  8.     }  
  9.       
  10.     return true;  
  11. }  

2.3 EventListenerCustom

       同样的,EventListenerID是根据独特的Name进行命名的,值得注意的是请确保你的name是具有唯一性的,否在在DispatchCustomEvent时会有问题。

3. EventDispatcher

       从头到尾写了这么多,才开始进入主题,上面的东西都是为了看EventDispatcher源码的开胃菜!!!在介绍这个之前,我们必须要看一个内部类

3.1 EventListenerVector

      
  1. class EventListenerVector  
  2.     {  
  3.     public:  
  4.         EventListenerVector();  
  5.         ~EventListenerVector();  
  6.         size_t size() const;  
  7.         bool empty() const;  
  8.           
  9.         void push_back(EventListener* item);  
  10.         void clearSceneGraphListeners();  
  11.         void clearFixedListeners();  
  12.         void clear();  
  13.           
  14.         inline std::vector<EventListener*>* getFixedPriorityListeners() const { return _fixedListeners; };  
  15.         inline std::vector<EventListener*>* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; };  
  16.         inline ssize_t getGt0Index() const { return _gt0Index; };  
  17.         inline void setGt0Index(ssize_t index) { _gt0Index = index; };  
  18.     private:  
  19.         std::vector<EventListener*>* _fixedListeners;  
  20.         std::vector<EventListener*>* _sceneGraphListeners;  
  21.         ssize_t _gt0Index;  
  22.     };  

继续
最新回复 (0)
返回