cocos2dx學習原始碼之介面iOS事件分發(2)
阿新 • • 發佈:2019-01-22
今天看看事件是如何分發的。程式碼版本:cocos2dx-3.9
上次說到GLView接手touch事件:handleTouchesBegin。
原始碼:
上面紅色程式碼,是事件分發的關鍵。void GLView::handleTouchesBegin(int num, intptr_t ids[], float xs[], float ys[]) { intptr_t id = 0; float x = 0.0f; float y = 0.0f; int unusedIndex = 0; EventTouch touchEvent; for (int i = 0; i < num; ++i) { id = ids[i]; x = xs[i]; y = ys[i]; auto iter = g_touchIdReorderMap.find(id); // it is a new touch if (iter == g_touchIdReorderMap.end()) { unusedIndex = getUnUsedIndex(); // The touches is more than MAX_TOUCHES ? if (unusedIndex == -1) { CCLOG("The touches is more than MAX_TOUCHES, unusedIndex = %d", unusedIndex); continue; } Touch* touch = g_touches[unusedIndex] = new (std::nothrow) Touch(); touch->setTouchInfo(unusedIndex, (x - _viewPortRect.origin.x) / _scaleX, (y - _viewPortRect.origin.y) / _scaleY); CCLOGINFO("x = %f y = %f", touch->getLocationInView().x, touch->getLocationInView().y); g_touchIdReorderMap.insert(std::make_pair(id, unusedIndex<span style="color:#ffffff;">));</span> touchEvent._touches.push_back(touch); } } if (touchEvent._touches.size() == 0) { CCLOG("touchesBegan: size = 0"); return; } touchEvent._eventCode = EventTouch::EventCode::BEGAN; auto dispatcher = Director::getInstance()->getEventDispatcher(); <span style="color:#ff6666;">dispatcher->dispatchEvent(&touchEvent);</span> }
首先是g_touchIdReorderMap這個用於儲存touch資訊,其次dispatcher用於對事件分發。g_touchIdReorderMap很好理解。重點看看dispatcher。點選getEventIdspatcher(),看看dispatcher的獲取:
<span style="white-space:pre"> </span>EventDispatcher* getEventDispatcher() const { return _eventDispatcher; }
找到_eventDispatcher這個變數的初始化,在Director::init()裡面:
bool Director::init(void) { //....省略 _eventDispatcher = new (std::nothrow) EventDispatcher();
//...
return true;
}
下面是我們獲取touch事件的程式碼。
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesMoved = CC_CALLBACK_2(CameraArcBallDemo::onTouchsMoved, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
我們在Node裡面可以找到一個宣告:
EventDispatcher
找到它的初始化,發現這個東西就是Director裡面的_eventDispatcher。
導演是一個單例,事件分發變數也是隻有一個。
接著看看addEventListtenerWithSceneGraphpriority, 對lisnter進行設定,判斷是否正在進行分發。
<pre name="code" class="cpp">void EventDispatcher::dispatchTouchEvent(EventTouch* event)
{
//方便閱讀,此處用虛擬碼進行代替
對多點觸控進行排序
對單點觸控進行排序
if(單點觸控)
{
<span style="white-space:pre"> </span>1.遍歷事件
<span style="white-space:pre"> </span>2.根據事件型別進行分發
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>if(多點觸控)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>根據事件型別進行分發
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>更新事件,對之前的儲存事件資料,進行刪除。
}