加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2d-x 2.2.3 CCKeypadDispatcher简单分析

发布时间:2020-12-14 21:09:16 所属栏目:百科 来源:网络整理
导读:最近的项目需要修改到按键相关的处理,于是顺便把这部分相关的代码看了一遍。 头文件 // 支持的2种按键消息typedef enum { // the back key clicked msg kTypeBackClicked = 1,kTypeMenuClicked,} ccKeypadMSGType;struct _ccCArray;// 按键分发类class CC_D

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


头文件

// 支持的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里修改就可以了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读