• Cocos2d-x 学习笔记(8) ActionManager


    1. 概述

    ActionManager管理所有的action,调度所有的action,删除指定的action。每个action对应一个node对象,action存储在actions中,actions和node绑定在一个element中。

    2. 学习

    2.1 在哪使用

    Director类中有成员ActionManager类单例对象指针_actionManager。

    Director类在创建时调用到Director::init(void)方法,有以下操作:

    _actionManager = new (std::nothrow) ActionManager();
    _scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);

    scheduleUpdate方法是执行了schedulePerFrame方法,_actionManager的update方法作为回调函数,故该update方法在每帧被调用。

    schedulePerFrame方法执行后,_actionManager作为target,update方法作为回调函数新建优先级最高的Timer。

    2.2 一些成员

    ActionManager类成员变量:

    struct _hashElement *_targets; // Element容器
    struct _hashElement *_currentTarget; // 当前的Element
    bool _currentTargetSalvaged;

    ActionManager类结构体变量:

    typedef struct _hashElement
    {
        struct _ccArray     *actions;
        Node                *target;
        int                 actionIndex;
        Action              *currentAction; // 当前Action
        bool                currentActionSalvaged;
        bool                paused;
        UT_hash_handle      hh;
    } tHashElement;

    2.3 update方法

    简要的说,update方法是对哈希链表_targets的每个element作为_currentTarget,再把每个element的action作为currentAction,其中包含对action和element的延后release()。

    ActionManager的update(float dt)方法执行大致流程:

    2.4 addAction方法

    addAction(Action *action, Node *target, bool paused)方法执行流程:

    新建element时,会对target执行retain()。

    action添加到actions时,执行ccArrayAppendObject(element->actions, action),对action执行retain()。

    2.5 pause resume

    pauseTarget(Node *target)
    resumeTarget(Node *target)
    resumeTargets(const Vector<Node*>& targetsToResume)

    上面这3个方法对target对应的element的paused变量置true或false。

    pauseAllRunningActions()方法,对哈希链表_targets的每个element的成员pause置true,并用Vector<Node*> idsWithActions保存暂停了的target。添加到容器时,这些target执行retain(),在手动调用恢复方法resumeTargets(const Vector<Node*>& targetsToResume)后,对Vector容器执行clear()方法,此时对target执行release()。

    2.6 remove

    删除action操作归纳到以下两种方法:

    removeAllActionsFromTarget(Node *target)
    removeActionAtIndex(ssize_t index, tHashElement *element)

    removeAllActionsFromTarget方法

    首先通过target从哈希链表_targets中查找对应的element。如果是element的currentAction且currentActionSalvaged为false,说明该action被target执行,对于这个action要retain(),并currentActionSalvaged置true,下一步的release()延后执行。再执行ccArrayRemoveObjectAtIndex,所有action执行release(),之后只有currentAction没被删除。actions为空就要删除element了,此时若_currentTarget为当前element,即target正在执行,_currentTargetSalvaged置true,暂不删除element。

    removeActionAtIndex方法

    从element的actions中对指定的action执行release(),若currentAction为当前action则延后release(),并修改标志currentActionSalvaged为true。之后若actions为空,在删除element之前,若_currentTarget为当前element,_currentTargetSalvaged置true并暂不删除。

    2.7 currentActionSalvaged _currentTargetSalvaged

    currentActionSalvaged属于element,_currentTargetSalvaged属于ActionManager。

    在ActionManager的update方法中,在对当前遍历到的element进行所有操作之前,_currentTargetSalvaged置false,在对element的actions遍历结束后,判断_currentTargetSalvaged。若在遍历actions时,有action被remove操作,之后需要判断actions是否为空,为空则置_currentTargetSalvaged为true。即在对element的actions遍历结束后才能对release()无action的element。

    在对action执行step(dt)之前,currentActionSalvaged置false,执行step(dt)结束之后,再判断currentActionSalvaged,即对removeAction方法指定的action执行release()需要在step(dt)执行之后真正执行。

  • 相关阅读:
    小白逆袭的真实故事,句句干货不看损失一个亿!
    CODEFORCES 1367F2 FLYING SORT (HARD VERSION)
    整理:iOS开发知识点
    EBS-子库存转移和物料搬运单区别
    Oracle ERP系統借贷关系表
    ORACLE ERP各模块会计分录
    SQL Queries and Multi-Org Architecture in Release 12
    ORALCE EBS ALERT 初体验
    工作流邮件审批设置
    How to Send an Email Using UTL_SMTP with Authenticated Mail Server
  • 原文地址:https://www.cnblogs.com/deepcho/p/cocos2dx-actionmanager.html
Copyright © 2020-2023  润新知