不可能在结构的std :: vector中存储cocos2d :: Animation *?

时间:2018-03-31 20:10:55

标签: c++ pointers vector cocos2d-x std

我在使用cocos2d-x framework(c ++)创建的项目。 在我的Player类中,我必须管理动画。 最初我有这个代码没有任何问题:

首先,动画对象是cocos2d类cocos2d::Animation。请记住,此对象包含cocos2d::Vector<AnimationFrame*> _frames;成员。 Doc:http://www.cocos2d-x.org/reference/native-cpp/V3.5/d3/dc5/classcocos2d_1_1_animation.html#a0fdc0be158df7e09d04644be353db056

class Player : public cocos2d::Sprite {
private:
    cocos2d::Map<std::string, cocos2d::Animation*> animations;
    cocos2d::Vector<cocos2d::SpriteFrame*> getAnimation(const char *format, int frameStart, int count);
    void update(float delta) override;
    bool init() override;

public:
    static Player* create();
    bool init() override;
    //...
};

执行方:

bool Player::init() {
    //...
    animations.insert("idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1));
    //...
}

Vector<SpriteFrame*> Player::getAnimation(const char *format, int frameStart, int count) {
    auto spriteCache = SpriteFrameCache::getInstance();
    Vector<SpriteFrame*> animFrames;
    char str[100] = {0};
    for (int i = 1; i <= count; i++)
    {
        sprintf(str, format, frameStart);
        log("%s", str);
        animFrames.pushBack(spriteCache->getSpriteFrameByName(str));
        frameStart++;
    }
    return animFrames;
}

//later in the code execution
void Player::manageIdle() {
        auto idleAnim = Animate::create(animations[0].anim);
        runAction(idleAnim);
}

你可以看到每个动画都包含在cocos2d::Map<std::string, cocos2d::Animation*>中,正如我之前所说,这段代码完美无缺,没有错误。

但除了名称和对象本身之外我还需要更多信息,所以我决定使用一个结构来存储每个动画的所有信息。我将cocos2d::Map<std::string, cocos2d::Animation*>替换为std::vector<animData>并将animData替换为class Player : public cocos2d::Sprite { public: typedef struct animation { std::string name; cocos2d::Animation* anim; //all others info needed, not relevant here, (just several enum type variables) } animData; private: std::vector<animData > animations; //the new container //rest of code stay unchanged }; 作为结构。我像这样重构了代码:

bool Player::init() {
    //...
    animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)});
    //no problem here...
}

执行方面的变化:

void Player::manageIdle() {
        auto idleAnim = Animate::create(animations[0].anim); //SegV here, in Animate::create() funct
        runAction(idleAnim);
}

但是现在,当我尝试使用保存在我的容器(矢量)中的动画创建一个新的动画时,我在这一行上获得了一个SegV:

anim

搜索之后,我发现每个结构成员cocos2d::Vector<AnimationFrame*> _frames;都是cocos2d :: Animation *的类型,现在包含一个空的cocos2d::Vector<AnimationFrame*>并且存在问题! 好像他们失去了cocos2d::Vector<AnimationFrame*> ref或类似的东西。

所以我的问题是为什么auto test = animList[0].anim->getFrames(); if (test.empty()) { log("empty"); //The test output empty } 会因为我的重构代码变空而不是之前的代码?

我通过这样的测试找到了这个:

animations.back().anim->retain();

init()功能结束时的Debugguer屏幕:

enter image description here

Player :: manageIdle()功能中的Debugguer屏幕:

enter image description here

修改:当我在行后面添加animations.push_back({"idleN", Animation::createWithSpriteFrames(getAnimation("%04d", 207, 9), 0.1)}); animations.back().anim->retain(); 以在向量中添加元素时,它解决了问题!

cocos2d::Animation*

因为animations.back().anim->retain();继承自cocos2d :: Ref,所以它是一个自动释放对象。当在cocos2d容器中使用时,如cocos2d :: Map或cocos2d :: Vector,它由容器本身自动管理。但是我使用了std :: vector,所以我失去了我认为的参考。这样的事情。 现在我需要找到一种方法来摆脱这个额外的代码行,因为这个倍数是我的行数的两倍!

这里有一个新问题:每次在向量中添加新元素时,如何摆脱我必须调用const vue2 = new Vue({ el: '#vue2', data: function() { return { modalShow: false } }, methods: { showModal() { this.$refs.myModal.show() } }, render() { return( <div> <b-btn on-click={this.showModal}>Show Modal</b-btn> <b-modal ref="myModal"> Hello From My Modal! </b-modal> </div> ) } 的事实?

1 个答案:

答案 0 :(得分:0)

你可以在Ref周围创建一个“保留”所有权的包装器,然后存储这个包装器,排序为std::unique_ptr,例如。

template<typename T> class RefOwner {
public:
    RefOwner(T *t) : ref(t) {
        ref->retain();
    }

    ~RefOwner() {
        ref->release();
    }

    T *operator->() { return ref; }
private:
    T *ref;
};

然后将其用作

struct animData {
    std::string name;
    RefOwner<cocos2d::Animation> anim;
    //all others info needed, not relevant here, (just several enum type variables)
};

免责声明:我对cocos2d-x没有经验,只看了AnimationRef