cocos2d-x 2.2.3 CCKeypadDispatcher简单分析

前端之家收集整理的这篇文章主要介绍了cocos2d-x 2.2.3 CCKeypadDispatcher简单分析前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

最近的项目需要修改到按键相关的处理,于是顺便把这部分相关的代码看了一遍。


文件

// 支持的2种按键消息
typedef enum {
    // the back key clicked msg
    kTypeBackClicked = 1,kTypeMenuClicked,} ccKeypadMSGType;

struct _ccCArray;
// 按键分发类
class CC_DLL CCKeypadDispatcher : public CCObject
{
public:
    CCKeypadDispatcher();
    ~CCKeypadDispatcher();

    // 添加delegate  forceAddDelegate
    void addDelegate(CCKeypadDelegate* pDelegate);

    // 移除delegate  最后都是执行forceRemoveDelegate
    void removeDelegate(CCKeypadDelegate* pDelegate);

    // 添加delegate
    void forceAddDelegate(CCKeypadDelegate* pDelegate);

    // 移除delegate
    void forceRemoveDelegate(CCKeypadDelegate* pDelegate);

    // 按键分发
    bool dispatchKeypadMSG(ccKeypadMSGType nMsgType);

protected:

    // delegate数组
    CCArray* m_pDelegates;
    bool m_bLocked;	// 用于锁定
    bool m_bToAdd;	// 需要执行添加标记
    bool m_bToRemove;	// 需要执行删除标记

    struct _ccCArray *m_pHandlersToAdd;	// 需要添加的handler
    struct _ccCArray *m_pHandlersToRemove;	// 需要移除的handler
};



实现

CCKeypadDispatcher::CCKeypadDispatcher()
: m_bLocked(false),m_bToAdd(false),m_bToRemove(false)
{
    m_pDelegates = CCArray::create();
    m_pDelegates->retain();

    m_pHandlersToAdd    = ccCArrayNew(8);
    m_pHandlersToRemove = ccCArrayNew(8);
}

CCKeypadDispatcher::~CCKeypadDispatcher()
{
    CC_SAFE_RELEASE(m_pDelegates);
    if (m_pHandlersToAdd)
    {
        ccCArrayFree(m_pHandlersToAdd);
    }
    
    if (m_pHandlersToRemove)
    {
        ccCArrayFree(m_pHandlersToRemove);
    }    
}

void CCKeypadDispatcher::removeDelegate(CCKeypadDelegate* pDelegate)
{
    if (!pDelegate)
    {
        return;
    }
    // 如果当前没有锁定,直接移除
    if (! m_bLocked)
    {
        forceRemoveDelegate(pDelegate);
    }
    // 如果当前锁定,则先将要移除的加入到待移除数组,并设置标记,在锁定结束后会再移除
    else
    {
        ccCArrayAppendValue(m_pHandlersToRemove,pDelegate);
        m_bToRemove = true;
    }
}

// 思路同移除
void CCKeypadDispatcher::addDelegate(CCKeypadDelegate* pDelegate)
{
    if (!pDelegate)
    {
        return;
    }

    if (! m_bLocked)
    {
        forceAddDelegate(pDelegate);
    }
    else
    {
        ccCArrayAppendValue(m_pHandlersToAdd,pDelegate);
        m_bToAdd = true;
    }
}

void CCKeypadDispatcher::forceAddDelegate(CCKeypadDelegate* pDelegate)
{
    // 添加
    CCKeypadHandler* pHandler = CCKeypadHandler::handlerWithDelegate(pDelegate);

    if (pHandler)
    {
        m_pDelegates->addObject(pHandler);
    }
}

void CCKeypadDispatcher::forceRemoveDelegate(CCKeypadDelegate* pDelegate)
{
    // 从当前数组中查找到对应的delegate,然后执行删除,只删除从前往后第一个找到的值
    CCKeypadHandler* pHandler = NULL;
    CCObject* pObj = NULL;
    CCARRAY_FOREACH(m_pDelegates,pObj)
    {
        pHandler = (CCKeypadHandler*)pObj;
        if (pHandler && pHandler->getDelegate() == pDelegate)
        {
            m_pDelegates->removeObject(pHandler);
            break;
        }
    }
}

bool CCKeypadDispatcher::dispatchKeypadMSG(ccKeypadMSGType nMsgType)
{
    CCKeypadHandler*  pHandler = NULL;
    CCKeypadDelegate* pDelegate = NULL;
    // 锁定  防止分发的时候被莫名其妙移除了
    m_bLocked = true;

    if (m_pDelegates->count() > 0)
    {
        CCObject* pObj = NULL;
	// 按照添加顺序依次分发
        CCARRAY_FOREACH(m_pDelegates,pObj)
        {
            CC_BREAK_IF(!pObj);

            pHandler = (CCKeypadHandler*)pObj;
            pDelegate = pHandler->getDelegate();
	    // 目前只有2种事件
            switch (nMsgType)
            {
            case kTypeBackClicked:
                pDelegate->keyBackClicked();
                break;
            case kTypeMenuClicked:
                pDelegate->keyMenuClicked();
                break;
            default:
                break;
            }
        }
    }
    // 锁定解除
    m_bLocked = false;
    // 如果锁定期间有添加或者移除的,现在执行掉,执行完毕后清空待处理的数组
    if (m_bToRemove)
    {
        m_bToRemove = false;
        for (unsigned int i = 0; i < m_pHandlersToRemove->num; ++i)
        {
            forceRemoveDelegate((CCKeypadDelegate*)m_pHandlersToRemove->arr[i]);
        }
        ccCArrayRemoveAllValues(m_pHandlersToRemove);
    }

    if (m_bToAdd)
    {
        m_bToAdd = false;
        for (unsigned int i = 0; i < m_pHandlersToAdd->num; ++i)
        {
            forceAddDelegate((CCKeypadDelegate*)m_pHandlersToAdd->arr[i]);
        }
        ccCArrayRemoveAllValues(m_pHandlersToAdd);
    }

    return true;
}




总结

add和remove最终都是要执行forcexxx的处理,所以要修改的话就在forcexx里修改就可以了。

原文链接:https://www.f2er.com/cocos2dx/343310.html

猜你在找的Cocos2d-x相关文章