源码版本来自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
- enum class Type
- {
- TOUCH,
- KEYBOARD,
- ACCELERATION,
- MOUSE,
- FOCUS,
- CUSTOM
- };
- Type _type; ///< Event type
- bool _isStopped; ///< whether the event has been stopped.
- Node* _currentTarget;
Event主要包含了三个重要的变量,type,是一个enum变量,里面定义了类型;isStopped定义该event是否已经停止,当一个event发生停止时,与其相关的Listener都要停止callback的调用;currentTarget是与该Event相关联的node。
2.1.2 EventTouch
EventTouch是cocos2d-x引擎中非常非常重要的事件。对应于四种touch操作,该类内部定义了四种EventCode
- enum class EventCode
- {
- BEGAN,
- MOVED,
- ENDED,
- CANCELLED
- };
不同的EventCode可以告诉Listener来调用不同的callback。
除此之外,EventTouch中含有std::vector<Touch*> _touches 来记录该事件相关的touch,值得注意的是,本版本默认含有的触摸点最大是5个。
2.1.3 EventCustom
EventCustom的出现取代了统治2.x版本多年的NotificationCenter,来看下EventCustom的两个重要成员变量。
- void* _userData; ///< User data
- std::string _eventName;
有没有似曾相识的感觉,还是一样的key,还是一样的userData(有点不一样。原来是CCObject*)。
其他的Event因为重要性以及使用度的原因,这里不再赘述,如果以后笔者对他们有新的认识,将会在这里进行添加。
2.2 EventListener相关
2.2.1 EventListener
- 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
重要的成员变量:
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。
- /** Enables or disables the listener
- * @note Only listeners with `enabled` state will be able to receive events.
- * When an listener was initialized, it's enabled by default.
- * An event listener can receive events when it is enabled and is not paused.
- * paused state is always false when it is a fixed priority listener.
- */
- inline void setEnabled(bool enabled) { _isEnabled = enabled; };
- /** 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 `true`,
- * while `EventDispatcher::pauseAllEventListenersForTarget(node)` will set it to `false`.
- * @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.
- */
- 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
- /// Overrides
- virtual EventListenerTouchOneByOne* clone() override;
- virtual bool checkAvailable() override;
- //
- public:
- std::function<bool(Touch*, Event*)> onTouchBegan;
- std::function<void(Touch*, Event*)> onTouchMoved;
- std::function<void(Touch*, Event*)> onTouchEnded;
- std::function<void(Touch*, Event*)> onTouchCancelled;
上面的是OneByOne重载父类的方法,以及自己本身需要被绑定4个callBack 函数。
- EventListenerTouchOneByOne* EventListenerTouchOneByOne::clone()
- {
- //深拷贝
- auto ret = new 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;
- }
- 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.
- //OneByOne只需要onTouchBegan不为空,则可以认为其是可用的。
- if (onTouchBegan == nullptr)
- {
- CCASSERT(false, "Invalid EventListenerTouchOneByOne!");
- return false;
- }
- return true;
- }
- std::vector<Touch*> _claimedTouches;
- bool _needSwallow;
OneByOne的touch是可以设置吞噬属性的。
2.2.3 EventListenerAllAtOnce
- std::function<void(const std::vector<Touch*>&, Event*)> onTouchesBegan;
- std::function<void(const std::vector<Touch*>&, Event*)> onTouchesMoved;
- std::function<void(const std::vector<Touch*>&, Event*)> onTouchesEnded;
- std::function<void(const std::vector<Touch*>&, Event*)> onTouchesCancelled;
AllAtOnce就是所谓的standard touch处理机制,一次性处理所有的touch。
值得注意的是AllAtOnce的checkAvailable要求,上述四个函数指针都不能为空。
- bool EventListenerTouchAllAtOnce::checkAvailable()
- {
- if (onTouchesBegan == nullptr && onTouchesMoved == nullptr
- && onTouchesEnded == nullptr && onTouchesCancelled == nullptr)
- {
- CCASSERT(false, "Invalid EventListenerTouchAllAtOnce!");
- return false;
- }
- return true;
- }
2.3 EventListenerCustom
同样的,EventListenerID是根据独特的Name进行命名的,值得注意的是请确保你的name是具有唯一性的,否在在DispatchCustomEvent时会有问题。
3. EventDispatcher
从头到尾写了这么多,才开始进入主题,上面的东西都是为了看EventDispatcher源码的开胃菜!!!在介绍这个之前,我们必须要看一个内部类
3.1 EventListenerVector
- class EventListenerVector
- {
- public:
- EventListenerVector();
- ~EventListenerVector();
- size_t size() const;
- bool empty() const;
- void push_back(EventListener* item);
- void clearSceneGraphListeners();
- void clearFixedListeners();
- void clear();
- inline std::vector<EventListener*>* getFixedPriorityListeners() const { return _fixedListeners; };
- inline std::vector<EventListener*>* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; };
- inline ssize_t getGt0Index() const { return _gt0Index; };
- inline void setGt0Index(ssize_t index) { _gt0Index = index; };
- private:
- std::vector<EventListener*>* _fixedListeners;
- std::vector<EventListener*>* _sceneGraphListeners;
- ssize_t _gt0Index;
- };
继续
最新回复 (0)