对应源码位置:(1)cocos2d-x-3.3\cocos\base\CCEvent*
先从 Event 类开头
class CC_DLL Event : public Ref
{
public:
//可想而知 对应这几个类型 分别有对应的Event子类
//以及 对应事件的 eventlistener
enum class Type
{
TOUCH,
KEYBOARD,
ACCELERATION,
MOUSE,
FOCUS,
GAME_CONTROLLER,
CUSTOM
};
/** Constructor */
Event(Type type);
public:
/** Destructor */
virtual ~Event();
/** Gets the event type */
inline Type getType() const {
return _type; };
/** Stops propagation for current event */
inline void stopPropagation() {
_isStopped = true; };
/** Checks whether the event has been stopped */
inline bool isStopped() const {
return _isStopped; };
inline Node* getCurrentTarget() {
return _currentTarget; };
protected:
/** Sets current target */
inline void setCurrentTarget(Node* target) {
_currentTarget = target; };
//事件类型
Type _type; ///< Event type
//是否阻止传播 也就是所谓的 swallow 是否吞下这个事件
bool _isStopped; ///< whether the event has been stopped.
Node* _currentTarget; ///< Current target
friend class EventDispatcher;
};
再来看看 EventCustom 这个子类,也就是所谓自定义事件
class CC_DLL EventCustom : public Event
{
public:
/** Constructor */
EventCustom(const std::string& eventName);
/** Sets user data */
inline void setUserData(void* data) {
_userData = data; };
/** Gets user data */
inline void* getUserData() const {
return _userData; };
/** Gets event name */
inline const std::string& getEventName() const {
return _eventName; };
protected:
//恕我直言 没什么东西
void* _userData; ///< User data
//事件名称
std::string _eventName;
};
那再来看看 EventMouse 这个子类,也就是鼠标事件
//鼠标的操作
#define MOUSE_BUTTON_LEFT 0
#define MOUSE_BUTTON_RIGHT 1
#define MOUSE_BUTTON_MIDDLE 2
#define MOUSE_BUTTON_4 3
#define MOUSE_BUTTON_5 4
#define MOUSE_BUTTON_6 5
#define MOUSE_BUTTON_7 6
#define MOUSE_BUTTON_8 7
class CC_DLL EventMouse : public Event
{
public:
/**
* 鼠标事件类型
*/
enum class MouseEventType
{
MOUSE_NONE,
MOUSE_DOWN,
MOUSE_UP,
MOUSE_MOVE,
MOUSE_SCROLL,
};
EventMouse(MouseEventType mouseEventCode);
/** Set mouse scroll data */
inline void setScrollData(float scrollX, float scrollY) {
_scrollX = scrollX; _scrollY = scrollY; };
inline float getScrollX() {
return _scrollX; };
inline float getScrollY() {
return _scrollY; };
//也就是 把最新的 鼠标位置保存 根据使 是否要开始捕获开始点 保存旧数据
inline void setCursorPosition(float x, float y) {
_x = x;
_y = y;
_prevPoint = _point;
_point.x = x;
_point.y = y;
if (!_startPointCaptured)
{
_startPoint = _point;
_startPointCaptured = true;
}
}
inline void setMouseButton(int button) {
_mouseButton = button; };
inline int getMouseButton() {
return _mouseButton; };
inline float getCursorX() {
return _x; };
inline float getCursorY() {
return _y; };
/** returns the current touch location in OpenGL coordinates */
Vec2 getLocation() const;
/** returns the previous touch location in OpenGL coordinates */
Vec2 getPreviousLocation() const;
/** returns the start touch location in OpenGL coordinates */
Vec2 getStartLocation() const;
/** returns the delta of 2 current touches locations in screen coordinates */
Vec2 getDelta() const;
/** returns the current touch location in screen coordinates */
Vec2 getLocationInView() const;
/** returns the previous touch location in screen coordinates */
Vec2 getPreviousLocationInView() const;
/** returns the start touch location in screen coordinates */
Vec2 getStartLocationInView() const;
private:
MouseEventType _mouseEventType;
int _mouseButton;
float _x;
float _y;
float _scrollX;
float _scrollY;
bool _startPointCaptured;
Vec2 _startPoint;
Vec2 _point;
Vec2 _prevPoint;
friend class EventListenerMouse;
};
//基本操作 没什么关键点
最后看看 EventTouch 这个类,也就是最常用的 触摸事件。
class CC_DLL EventTouch : public Event
{
public:
static const int MAX_TOUCHES = 15;
//触摸事件类型
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;
std::vector<Touch*> _touches;
friend class GLView;
};
//他的实现 没什么东西 顺便看看 Touch类
class CC_DLL Touch : public Ref
{
public:
/** how the touches are dispathced */
//分为 两种分发方式 如果你一次点击了多个点 因为人有10个手指
// 是把这些触摸点 一个个处理 还是一次处理
enum class DispatchMode {
/** All at once */
ALL_AT_ONCE,
/** one by one */
ONE_BY_ONE,
};
Touch()
: _id(0),
_startPointCaptured(false)
{
}
//省略了一部分 get set
//这个 和鼠标是一样的 毕竟触摸也只是有个触摸点
void setTouchInfo(int id, float x, float y)
{
_id = id;
_prevPoint = _point;
_point.x = x;
_point.y = y;
if (!_startPointCaptured)
{
_startPoint = _point;
_startPointCaptured = true;
_prevPoint = _point;
}
}
int getID() const
{
return _id;
}
private:
int _id;
bool _startPointCaptured;
Vec2 _startPoint;
Vec2 _point;
Vec2 _prevPoint;
};
可以看到 事件本身确实定义的很简洁,更多的处理在于各个事件的监听器。
下面介绍 EventListener
class CC_DLL EventListener : public Ref
{
public:
//监听器的类型 比事件类型 多了两个
// 一个是UNKNOWN 另一个是将TOUCH 细分为两种 总的说 是一一对应的
enum class Type
{
UNKNOWN,
TOUCH_ONE_BY_ONE,
TOUCH_ALL_AT_ONCE,
KEYBOARD,
MOUSE,
ACCELERATION,
FOCUS,
GAME_CONTROLLER,
CUSTOM
};
//这个名字 其实有点误导人 ID本来单独指向 一个listener还好
//这里用来代表的是 一种类型的事件监听器
//为什么 不直接用上面的Type呢 因为 有自定义事件这个 搅*棍
//自定义事件 不知道有哪些类型的
typedef std::string ListenerID;
/** Initializes event with type and callback function */
bool init(Type t, const ListenerID& listenerID, const std::function<void(Event*)>& callback);
public:
/** Destructor */
virtual ~EventListener();
/** Checks whether the listener is available. */
virtual bool checkAvailable() = 0;
/** Clones the listener, its subclasses have to override this method. */
virtual EventListener* clone() = 0;
//值得一读
/** 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; };
/** Checks whether the listener is enabled */
inline bool isEnabled() const {
return _isEnabled; };
protected:
//值得一读
/** 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; };
/** Checks whether the listener is paused */
inline bool isPaused() const {
return _paused; };
//是用来 表明是否是向 事件分发器 注册过
/** Marks the listener was registered by EventDispatcher */
inline void setRegistered(bool registered) {
_isRegistered = registered; };
/** Checks whether the listener was registered by EventDispatcher */
inline bool isRegistered() const {
return _isRegistered; };
/** 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; };
/** Gets the listener ID of this listener
* 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; };
/** Sets the fixed priority for this listener
* @note This method is only used for `fixed priority listeners`, it needs to access a non-zero value.
* 0 is reserved for scene graph priority listeners
*/
//非0值 0是给 scene graph priority 用的
inline void setFixedPriority(int fixedPriority) {
_fixedPriority = fixedPriority; };
/** Gets the fixed priority of this listener
* @return 0 if it's a scene graph priority listener, non-zero for fixed priority listener
*/
inline int getFixedPriority() const {
return _fixedPriority; };
/** Sets the node associated with this listener */
inline void setAssociatedNode(Node* node) {
_node = node; };
/** Gets the node associated with this listener
* @return nullptr if it's a fixed priority listener, otherwise return non-nullptr
*/
//fixed priority listener 将会返回null 因为他未与node绑定
inline Node* getAssociatedNode() const {
return _node; };
///
// Properties
//
//仿函数 实现回调 很方便 前面几篇的 Schedule也是使用这种方式
//特别是对于 lambda 成员函数 会特别方便
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
friend class EventDispatcher;
};
照例 还是先看看 EventListenerCustom
//一如既往的 没什么看头
class CC_DLL EventListenerCustom : public EventListener
{
public