cocos2d-x 3.7 源码分析 EventDispatcher

cocos2d-x 3.7 源码分析 EventDispatcher,第1张

概述#ifndef __CC_TOUCH_H__#define __CC_TOUCH_H__#include "base/CCRef.h"#include "math/CCGeometry.h"NS_CC_BEGIN/** @class Touch * @brief Encapsulates the Touch information, such as touch point,
#ifndef __CC_touch_H__#define __CC_touch_H__#include "base/CCRef.h"#include "math/CCGeometry.h"NS_CC_BEGIN/** @class touch * @brIEf Encapsulates the touch information,such as touch point,ID and so on,and provIDes the methods that commonly used. */class CC_DLL touch : public Ref{public:    /**      * dispatch mode,how the touches are dispathced.     * @Js NA     */    enum class dispatchMode    {        ALL_AT_ONCE,/** All at once. */        ONE_BY_ONE,/** One by one. */    };    // 构造函数.cocos2dx源码中 voID GLVIEw::handletouchesBegin(int num,intptr_t IDs[],float xs[],float ys[])调用过。    touch()     : _ID(0),_startPointCaptured(false)    {        }        /** Set the touch infomation. It always used to monitor touch event.     *     * @param ID A given ID     * @param x A given x coordinate.     * @param y A given y coordinate.     */    voID settouchInfo(int ID,float x,float y)    {        _ID = ID;        _prevPoint = _point;        _point.x   = x;        _point.y   = y;                if (!_startPointCaptured)   // 首次设置touchInfo,startPoint、prevPoint 与 point相等。        {            _startPoint = _point;            _startPointCaptured = true;            _prevPoint = _point;        }    }        // in openGL coordinates.  (开始坐标,前一个坐标,当前坐标)    Vec2 getStartLocation() const;    Vec2 getPrevIoUsLocation() const;    Vec2 getLocation() const;    // in screen coordinates.  (开始坐标,前一个坐标,当前坐标)    Vec2 getStartLocationInVIEw() const;    Vec2 getPrevIoUsLocationInVIEw() const;    Vec2 getLocationInVIEw() const;                // 当前坐标和前一个坐标之间的差值。    Vec2 getDelta() const;            /** Get touch ID.     * @Js getID     * @lua getID     *     * @return The ID of touch.     */    int getID() const    {        return _ID;    }private:    int _ID;                    // ID    bool _startPointCaptured;   // 是否捕获过开始点    Vec2 _startPoint;           // 开始点    Vec2 _point;                // 当前点    Vec2 _prevPoint;            // 上一次点坐标};NS_CC_END#endif
#include "base/CCtouch.h"#include "base/CCDirector.h"NS_CC_BEGIN// returns the current touch location in screen coordinatesVec2 touch::getLocationInVIEw() const {     return _point; }// returns the prevIoUs touch location in screen coordinatesVec2 touch::getPrevIoUsLocationInVIEw() const {     return _prevPoint; }// returns the start touch location in screen coordinatesVec2 touch::getStartLocationInVIEw() const {     return _startPoint; }// returns the current touch location in OpenGL coordinatesVec2 touch::getLocation() const{     return Director::getInstance()->convertToGL(_point); }// returns the prevIoUs touch location in OpenGL coordinatesVec2 touch::getPrevIoUsLocation() const{     return Director::getInstance()->convertToGL(_prevPoint);  }// returns the start touch location in OpenGL coordinatesVec2 touch::getStartLocation() const{     return Director::getInstance()->convertToGL(_startPoint);  }// returns the delta position between the current location and the prevIoUs location in OpenGL coordinatesVec2 touch::getDelta() const{         return getLocation() - getPrevIoUsLocation();}NS_CC_END

touch类相对比较简单。

待解决问题:

1.touch对象在CCGLvIEw的创建,以及整个流程。

2.Director::getInstance()->convertToGL(_point); 坐标转换问题。

#ifndef __CCEVENT_H__#define __CCEVENT_H__#include "base/CCRef.h"#include "platform/CCPlatformMacros.h"NS_CC_BEGINclass Node;// 所有事件的基类class CC_DLL Event : public Ref{public:    // 内部枚举类Type(使用方法,Event::Type::touch)    enum class Type    {        touch,KEYBOARD,acceleration,MOUSE,FOCUS,GAME_CONTRolLER,CUSTOM    };    public:    Event(Type type);    virtual ~Event();    // 类型	inline Type getType() const { return _type; };        // 停止传播事件    inline voID stopPropagation() { _isstopped = true; };        // 事件是否停止    inline bool isstopped() const { return _isstopped; };        // 与node关联的事件才有用,fixedPriority 返回0.(It onlys be available when the event Listener is associated with node. It returns 0 when the Listener is associated with fixed priority.)    inline Node* getCurrentTarget() { return _currentTarget; };    protected:    inline voID setCurrentTarget(Node* target) { _currentTarget = target; };    	Type _type;             // 描述当前对象的事件类型。    bool _isstopped;        // 描述当前事件是否已经停止。    Node* _currentTarget;   // 是侦听事件的Node类型的对象。        frIEnd class Eventdispatcher;};NS_CC_END#endif

#include "base/CCEvent.h"NS_CC_BEGINEvent::Event(Type type): _type(type),_isstopped(false),_currentTarget(nullptr){}Event::~Event(){}NS_CC_END
Event类是事件类的基类,有3个重要属性:

1.target

2.type

3.isstopped

#ifndef __cocos2d_libs__touchEvent__#define __cocos2d_libs__touchEvent__#include "base/CCEvent.h"#include <vector>NS_CC_BEGINclass touch;#define touch_PERF_DEBUG 1class CC_DLL Eventtouch : public Event{public:    static const int MAX_touches = 15;  // 事件的最大touch个数。        // 内部枚举类EventCode。在dispatcher event时会用到。    enum class EventCode    {        BEGAN,MOVED,ENDED,CANCELLED    };    Eventtouch();    inline EventCode getEventCode() const { return _eventCode; };        // 当前触摸屏幕所有点的列表    inline const std::vector<touch*>& gettouches() const { return _touches; };    // 测试相关方法#if touch_PERF_DEBUG    voID setEventCode(EventCode eventCode) { _eventCode = eventCode; };    voID settouches(const std::vector<touch*>& touches) { _touches = touches; };#endif    private:    EventCode _eventCode;           // 事件code(began,moved,ended,cancelled)    std::vector<touch*> _touches;   // touch数组 获取当前触摸屏幕所有点的列表    frIEnd class GLVIEw;};NS_CC_END#endif
#include "base/CCEventtouch.h"#include "base/CCtouch.h"NS_CC_BEGINEventtouch::Eventtouch(): Event(Type::touch){    _touches.reserve(MAX_touches);}NS_CC_END
Eventtouch类继承自Event,加上Event的3个属性,Eventtouch共有5个属性:

1.target

2.type

3.isstopped

4.touches:当前触摸屏幕所有点的列表

5.eventCode:该属性在dispatcher中会用到,后面分析


#ifndef __cocos2d_libs__CCCustomEvent__#define __cocos2d_libs__CCCustomEvent__#include <string>#include "base/CCEvent.h"NS_CC_BEGINclass CC_DLL EventCustom : public Event{public:    EventCustom(const std::string& eventname);        inline voID setUserData(voID* data) { _userData = data; };    inline voID* getUserData() const { return _userData; };        inline const std::string& getEventname() const { return _eventname; };protected:    voID* _userData;        // User data    std::string _eventname;};NS_CC_END#endif

#include "base/CCEventCustom.h"#include "base/CCEvent.h"NS_CC_BEGINEventCustom::EventCustom(const std::string& eventname): Event(Type::CUSTOM),_userData(nullptr),_eventname(eventname){}NS_CC_END

EventCustom类继承自Event,加上Event的3个属性,EventCustom共有5个属性:

1.target

2.type

3.isstopped

4.eventname

5.userData

使用EventCustom的地方还是很多的,这里只粗略介绍下。

#ifndef __CCEVENTListENER_H__#define __CCEVENTListENER_H__#include <functional>#include <string>#include <memory>#include "platform/CCPlatformMacros.h"#include "base/CCRef.h"NS_CC_BEGINclass Event;class Node;/** @class EventListener *  @brIEf The base class of event Listener. *  If you need custom Listener which with different callback,you need to inherit this class. *  For instance,you Could refer to EventListeneracceleration,EventListenerKeyboard,EventListenertouchOneByOne,EventListenerCustom. */class CC_DLL EventListener : public Ref{public:    /** Type Event type.*/  // 这个类型与Event的类型有一小点不同,就是将触摸事件类型分成了 One by One (一个接一个) 与  All At Once (同时一起)两种。    enum class Type    {        UNKNowN,touch_ONE_BY_ONE,touch_ALL_AT_ONCE,CUSTOM    };    typedef std::string ListenerID; public:    EventListener();    bool init(Type t,const ListenerID& ListenerID,const std::function<voID(Event*)>& callback);    virtual ~EventListener();        // 纯虚函数监测监听器是否可用    virtual bool checkAvailable() = 0;        // 纯虚函数,因为clone的方式不同,又需要这个功能接口,所以在设置为纯虚函数,使子类必需实现。    virtual EventListener* clone() = 0;    // 当EventListener enabled并且not paused时,EventListener才能接受事件。    inline voID setEnabled(bool enabled) { _isEnabled = enabled; };    inline bool isEnabled() const { return _isEnabled; };protected:    /** Gets the type of this Listener     *  @note It's different from `EventType`,e.g. touchEvent has two kinds of event Listeners - EventListenerOneByOne,EventListenerAllAtOnce     */    inline Type getType() const { return _type; };      // eventType && ListenerID ===> Listeners.  EventListenertouchOneByOne::ListENER_ID = "__cc_touch_one_by_one"; EventListenertouchAllAtOnce::ListENER_ID = "__cc_touch_all_at_once"; (When event is being dispatched,Listener ID is used as key for searching Listeners according to event type.)    inline const ListenerID& getListenerID() const { return _ListenerID; };        // 注册    inline voID setRegistered(bool registered) { _isRegistered = registered; };    inline bool isRegistered() const { return _isRegistered; };        /************************************************     Sets paused state for the Listener     The paused state is only used for scene graph priority Listeners.     `Eventdispatcher::resumeAllEventListenersForTarget(node)` will set the paused state to `false`,while `Eventdispatcher::pauseAllEventListenersForTarget(node)` will set it to `true`.     @note             1) Fixed priority Listeners will never get paused. If a fixed priority doesn't want to receive events,call `setEnabled(false)` instead.            2) In `Node`'s onEnter and onExit,the `paused state` of the Listeners which associated with that node will be automatically updated.          sceneGraPHPriorityListener:     fixedPriorityListener:不使用_paused属性。          paused状态在node 的“onEnter”和“onExit”中改变     ************************************************/    inline voID setPaused(bool paused) { _paused = paused; };    inline bool isPaused() const { return _paused; };        // 获取与Listener相关联的node。fixed priority Listeners为nullptr。    inline Node* getAssociatednode() const { return _node; };    inline voID setAssociatednode(Node* node) { _node = node; };       // 用于fixed priority Listeners,可以设为不为0的值。    inline voID setFixedPriority(int fixedPriority) { _fixedPriority = fixedPriority; };    inline int getFixedPriority() const { return _fixedPriority; };    protected:    Type _type;                             // Event Listener type    ListenerID _ListenerID;                 // Event Listener ID    std::function<voID(Event*)> _onEvent;   // Event callback function        bool _isRegistered;                     // Whether the Listener has been added to dispatcher.    bool _isEnabled;                        // Whether the Listener is enabled    bool _paused;                           // Whether the Listener is paused        Node* _node;                            // scene graph based priority        int  _fixedPriority;                    // The higher the number,the higher the priority,0 is for scene graph base priority.        frIEnd class Eventdispatcher;};NS_CC_END#endif

#include "base/CCEventListener.h"NS_CC_BEGINEventListener::EventListener(){}    EventListener::~EventListener() {	cclOGINFO("In the destructor of EventListener. %p",this);}bool EventListener::init(Type t,const std::function<voID(Event*)>& callback){    _onEvent = callback;    _type = t;    _ListenerID = ListenerID;    _isRegistered = false;    _paused = true;    _isEnabled = true;        return true;}bool EventListener::checkAvailable(){ 	return (_onEvent != nullptr);}NS_CC_END
EventListener是事件监听器的基类,有8个属性:

1.type

2.ListenerID

3.onEvent

4.register

5.paused

6.enabled

7.node

8.fixedPriority

#ifndef __cocos2d_libs__CCtouchEventListener__#define __cocos2d_libs__CCtouchEventListener__#include "base/CCEventListener.h"#include <vector>NS_CC_BEGINclass touch;// 单点触摸监听器class CC_DLL EventListenertouchOneByOne : public EventListener{public:    static const std::string ListENER_ID;        // 创建单点触摸事件监听器    static EventListenertouchOneByOne* create();    EventListenertouchOneByOne();    bool init();    virtual ~EventListenertouchOneByOne();        // 是否吞噬掉触摸点,如果true,触摸将不会向下层传播。    bool isSwallowtouches();    voID setSwallowtouches(bool needSwallow);        /// OverrIDes 重写夫类的纯虚函数。    virtual EventListenertouchOneByOne* clone() overrIDe;    virtual bool checkAvailable() overrIDe;    public://    typedef std::function<bool(touch*,Event*)> cctouchBeganCallback;//    typedef std::function<voID(touch*,Event*)> cctouchCallback;    // public方法:创建监听器时,需手动设置 ontouch方法(ontouchBegan,ontouchmoved,ontouchended,ontouchCancelled)。    std::function<bool(touch*,Event*)> ontouchBegan;    std::function<voID(touch*,Event*)> ontouchmoved;    std::function<voID(touch*,Event*)> ontouchended;    std::function<voID(touch*,Event*)> ontouchCancelled;    private:    std::vector<touch*> _claimedtouches;    // 触摸点列表。(ontouchBegan 返回true)&&(Listener已经注册)过的touch对象才会被添加。    bool _needSwallow;                      // 是否需要吞噬触摸点        frIEnd class Eventdispatcher;};// 多点触摸监听器class CC_DLL EventListenertouchAllAtOnce : public EventListener{public:    static const std::string ListENER_ID;        static EventListenertouchAllAtOnce* create();    EventListenertouchAllAtOnce();    bool init();    virtual ~EventListenertouchAllAtOnce();        /// OverrIDes    virtual EventListenertouchAllAtOnce* clone() overrIDe;    virtual bool checkAvailable() overrIDe;public:    typedef std::function<voID(const std::vector<touch*>&,Event*)> cctouchesCallback;    cctouchesCallback ontouchesBegan;    cctouchesCallback ontouchesMoved;    cctouchesCallback ontouchesEnded;    cctouchesCallback ontouchesCancelled;        private:        frIEnd class Eventdispatcher;};NS_CC_END#endif

#include "base/CCEventListenertouch.h"#include "base/CCEventdispatcher.h"#include "base/CCEventtouch.h"#include "base/CCtouch.h"#include <algorithm>NS_CC_BEGINconst std::string EventListenertouchOneByOne::ListENER_ID = "__cc_touch_one_by_one";EventListenertouchOneByOne* EventListenertouchOneByOne::create(){    auto ret = new (std::nothrow) EventListenertouchOneByOne();    if (ret && ret->init())    {        ret->autorelease();    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}EventListenertouchOneByOne::EventListenertouchOneByOne(): ontouchBegan(nullptr),ontouchmoved(nullptr),ontouchended(nullptr),ontouchCancelled(nullptr),_needSwallow(false){}bool EventListenertouchOneByOne::init(){    if (EventListener::init(Type::touch_ONE_BY_ONE,ListENER_ID,nullptr))    {        return true;    }        return false;}EventListenertouchOneByOne::~EventListenertouchOneByOne(){    cclOGINFO("In the destructor of EventListenertouchOneByOne,%p",this);}voID EventListenertouchOneByOne::setSwallowtouches(bool needSwallow){    _needSwallow = needSwallow;}bool EventListenertouchOneByOne::isSwallowtouches(){    return _needSwallow;}bool EventListenertouchOneByOne::checkAvailable(){    // Eventdispatcher will use the return value of 'ontouchBegan' to determine whether to pass following 'move','end'    // message to 'EventListenertouchOneByOne' or not. So 'ontouchBegan' needs to be set.    // ontouchBegin 必须需要。    if (ontouchBegan == nullptr)    {        CCASSERT(false,"InvalID EventListenertouchOneByOne!");        return false;    }        return true;}EventListenertouchOneByOne* EventListenertouchOneByOne::clone(){    auto ret = new (std::nothrow) EventListenertouchOneByOne();    if (ret && ret->init())    {        ret->autorelease();                ret->ontouchBegan = ontouchBegan;        ret->ontouchmoved = ontouchmoved;        ret->ontouchended = ontouchended;        ret->ontouchCancelled = ontouchCancelled;                ret->_claimedtouches = _claimedtouches;        ret->_needSwallow = _needSwallow;    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}/////////const std::string EventListenertouchAllAtOnce::ListENER_ID = "__cc_touch_all_at_once";EventListenertouchAllAtOnce::EventListenertouchAllAtOnce(): ontouchesBegan(nullptr),ontouchesMoved(nullptr),ontouchesEnded(nullptr),ontouchesCancelled(nullptr){}EventListenertouchAllAtOnce::~EventListenertouchAllAtOnce(){    cclOGINFO("In the destructor of EventListenertouchAllAtOnce,this);}bool EventListenertouchAllAtOnce::init(){    if (EventListener::init(Type::touch_ALL_AT_ONCE,nullptr))    {        return true;    }        return false;}EventListenertouchAllAtOnce* EventListenertouchAllAtOnce::create(){    auto ret = new (std::nothrow) EventListenertouchAllAtOnce();    if (ret && ret->init())    {        ret->autorelease();    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}bool EventListenertouchAllAtOnce::checkAvailable(){    // ontouchesBegin、ontouchesMoved、ontouchesEnded、ontouchesCancelled 只需要任意一个不为空就行了    if (ontouchesBegan == nullptr && ontouchesMoved == nullptr&& ontouchesEnded == nullptr && ontouchesCancelled == nullptr)    {        CCASSERT(false,"InvalID EventListenertouchAllAtOnce!");        return false;    }        return true;}EventListenertouchAllAtOnce* EventListenertouchAllAtOnce::clone(){    auto ret = new (std::nothrow) EventListenertouchAllAtOnce();    if (ret && ret->init())    {        ret->autorelease();                ret->ontouchesBegan = ontouchesBegan;        ret->ontouchesMoved = ontouchesMoved;        ret->ontouchesEnded = ontouchesEnded;        ret->ontouchesCancelled = ontouchesCancelled;    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}NS_CC_END
EventListenertouch是EventListener的子类,具有EventListener的所有属性,加上自身4个属性,共14个属性:

1.ontouchBegan

2.ontouchmove

3.ontouchended

4.ontouchCanceled

5.claimedtouches

6.needSwallow

7.type

8.ListenerID

9.onEvent

10.paused

11.enabled

12.registered

13.node

14.fixedPriority


#ifndef __cocos2d_libs__CCCustomEventListener__#define __cocos2d_libs__CCCustomEventListener__#include "base/CCEventListener.h"NS_CC_BEGINclass EventCustom;/**************************************************************************** 用法:    // 1.dispatcher    auto dispatcher = Director::getInstance()->getEventdispatcher();     // 2.addListener    auto Listener = EventListenerCustom::create("your_event_type",[](EventCustom* event){ do_some_thing(); });    dispatcher->addEventListenerWithSceneGraPHPriority(Listener,one_node);     // 3.dispatcherEvent,触发事件。    EventCustom event("your_event_type");    dispatcher->dispatchEvent(&event);  ****************************************************************************/// EventCustomclass CC_DLL EventListenerCustom : public EventListener{public:    // 当特定的事件被分发,对应callback将会被调用    static EventListenerCustom* create(const std::string& eventname,const std::function<voID(EventCustom*)>& callback);    EventListenerCustom();    bool init(const ListenerID& ListenerID,const std::function<voID(EventCustom*)>& callback);            /// OverrIDes    virtual bool checkAvailable() overrIDe;    virtual EventListenerCustom* clone() overrIDe;protected:    std::function<voID(EventCustom*)> _onCustomEvent;        frIEnd class LuaEventListenerCustom;};NS_CC_END#endif

#include "base/CCEventListenerCustom.h"#include "base/CCEventCustom.h"NS_CC_BEGINEventListenerCustom::EventListenerCustom(): _onCustomEvent(nullptr){}EventListenerCustom* EventListenerCustom::create(const std::string& eventname,const std::function<voID(EventCustom*)>& callback){    EventListenerCustom* ret = new (std::nothrow) EventListenerCustom();    if (ret && ret->init(eventname,callback))    {        ret->autorelease();    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}bool EventListenerCustom::init(const ListenerID& ListenerID,const std::function<voID(EventCustom*)>& callback){    bool ret = false;        // callback ==> Listener.    // EventListenerCustom的onCustomEvent 与 EventListener的onEvent相关联。    _onCustomEvent = callback;    auto Listener = [this](Event* event){        if (_onCustomEvent != nullptr)        {            _onCustomEvent(static_cast<EventCustom*>(event));        }    };        // event参数的传入    // EventListener::init(Type t,ListenerID ListenerID,std::function<voID(Event*)>& callback)    if (EventListener::init(EventListener::Type::CUSTOM,ListenerID,Listener))    {        ret = true;    }    return ret;}EventListenerCustom* EventListenerCustom::clone(){    EventListenerCustom* ret = new (std::nothrow) EventListenerCustom();    if (ret && ret->init(_ListenerID,_onCustomEvent))    {        ret->autorelease();    }    else    {        CC_SAFE_DELETE(ret);    }    return ret;}bool EventListenerCustom::checkAvailable(){    bool ret = false;    if (EventListener::checkAvailable() && _onCustomEvent != nullptr)    {        ret = true;    }    return ret;}NS_CC_END
EventListenerCustom是EventListener的子类,共有9个属性:

1.onCustomEvent

2.onEvent

3.type

4.ListenerID

5.registered

6.paused

7.enabled

8.node

9.fixedPriority

总结

以上是内存溢出为你收集整理的cocos2d-x 3.7 源码分析 EventDispatcher全部内容,希望文章能够帮你解决cocos2d-x 3.7 源码分析 EventDispatcher所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1076200.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存