1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
void CCTouchDispatcher::touches(CCSet *pTouches, CCEvent *pEvent, unsigned int uIndex)
{
CCAssert(uIndex >= 0 && uIndex < 4, "");
CCSet *pMutableTouches;
//一个标示,当true的时候不允许直接添加新的handler对象
m_bLocked = true;
// optimization to prevent a mutable copy when it is not necessary
unsigned int uTargetedHandlersCount = m_pTargetedHandlers->count();
unsigned int uStandardHandlersCount = m_pStandardHandlers->count();
bool bNeedsMutableSet = (uTargetedHandlersCount && uStandardHandlersCount);
pMutableTouches = (bNeedsMutableSet ? pTouches->mutableCopy() : pTouches);
struct ccTouchHandlerHelperData sHelper = m_sHandlerHelperData[uIndex];
//
// process the target handlers 1st
//
if (uTargetedHandlersCount > 0)
{
CCTouch *pTouch;
CCSetIterator setIter;
for (setIter = pTouches->begin(); setIter != pTouches->end(); ++setIter)
{
//遍历所有传进来的本地化touch对象
pTouch = (CCTouch *)(*setIter);
CCTargetedTouchHandler *pHandler = NULL;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pTargetedHandlers, pObj)
{
//遍历所有已经注册的toucheHandler
pHandler = (CCTargetedTouchHandler *)(pObj);
if (! pHandler)
{
break;
}
bool bClaimed = false;
if (uIndex == CCTOUCHBEGAN)
{
//调用handler的ccTouchBegan方法.
//并捕获返回值
bClaimed = pHandler->getDelegate()->ccTouchBegan(pTouch, pEvent);
if (bClaimed)
{
//如果handler返回true
//把touch对象标记到handler的处理数组中
pHandler->getClaimedTouches()->addObject(pTouch);
}
}
else if (pHandler->getClaimedTouches()->containsObject(pTouch))
{
//该touch对象在handler的处理数据中
// moved ended canceled
bClaimed = true;
//根据不同状态,调用handler的不同函数
switch (sHelper.m_type)
{
case CCTOUCHMOVED:
pHandler->getDelegate()->ccTouchMoved(pTouch, pEvent);
break;
case CCTOUCHENDED:
pHandler->getDelegate()->ccTouchEnded(pTouch, pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);
break;
case CCTOUCHCANCELLED:
pHandler->getDelegate()->ccTouchCancelled(pTouch, pEvent);
pHandler->getClaimedTouches()->removeObject(pTouch);
break;
}
}
//这里涉及到是否处理下一个handler
//一定是同时两个条件满足才会停止处理下一个
//bClaimed 被handler处理了
//isSwallowsTouches 是swallows的,也可以理解为handler是阻挡touch继续传递的
//isSwallowsTouches 是怎么设置的呢,稍候会说
if (bClaimed && pHandler->isSwallowsTouches())
{
if (bNeedsMutableSet)
{
pMutableTouches->removeObject(pTouch);
}
break;
}
}
}
}
//
// process standard handlers 2nd
//
//这里是处理多点触控了,原理差不多
if (uStandardHandlersCount > 0 && pMutableTouches->count() > 0)
{
CCStandardTouchHandler *pHandler = NULL;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pStandardHandlers, pObj)
{
pHandler = (CCStandardTouchHandler*)(pObj);
if (! pHandler)
{
break;
}
switch (sHelper.m_type)
{
case CCTOUCHBEGAN:
pHandler->getDelegate()->ccTouchesBegan(pMutableTouches, pEvent);
break;
case CCTOUCHMOVED:
pHandler->getDelegate()->ccTouchesMoved(pMutableTouches, pEvent);
break;
case CCTOUCHENDED:
pHandler->getDelegate()->ccTouchesEnded(pMutableTouches, pEvent);
break;
case CCTOUCHCANCELLED:
pHandler->getDelegate()->ccTouchesCancelled(pMutableTouches, pEvent);
break;
}
}
}
if (bNeedsMutableSet)
{
pMutableTouches->release();
}
//
// Optimization. To prevent a [handlers copy] which is expensive
// the add/removes/quit is done after the iterations
//
m_bLocked = false;
//这里是处理touch期间不能添加和删除handler的地方了
//touch期间handler的rm和add都会放在一个数组里,这里touch处理完了
//就开始处理这些数组了
if (m_bToRemove)
{
m_bToRemove = false;
for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
{
forceRemoveDelegate((CCTouchDelegate*)m_pHandlersToRemove->arr[i]);
}
ccCArrayRemoveAllValues(m_pHandlersToRemove);
}
if (m_bToAdd)
{
m_bToAdd = false;
CCTouchHandler* pHandler = NULL;
CCObject* pObj = NULL;
CCARRAY_FOREACH(m_pHandlersToAdd, pObj)
{
pHandler = (CCTouchHandler*)pObj;
if (! pHandler)
{
break;
}
if (dynamic_cast<CCTargetedTouchHandler*>(pHandler) != NULL)
{
forceAddHandler(pHandler, m_pTargetedHandlers);
}
else
{
forceAddHandler(pHandler, m_pStandardHandlers);
}
}
m_pHandlersToAdd->removeAllObjects();
}
if (m_bToQuit)
{
m_bToQuit = false;
forceRemoveAllDelegates();
}
}
|