⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 attachentity.h.svn-base

📁 坦克大战游戏完整全套源代码
💻 SVN-BASE
字号:
#ifndef COMMON_ATTACH_ENTITY_H
#define COMMON_ATTACH_ENTITY_H

#include <vector>
#include <algorithm>
#include "common/entity.h"

using std::find;

class iAttacheeEntity : public Entity::iEntity
{
public:
    friend class Attacher;
    iAttacheeEntity(Entity &e) : Entity::iEntity(e)
    {
    }
    virtual void attach(Attacher &attacher) = 0;
    virtual void dettach(Attacher &attacher) = 0;
protected:
    void _attach(Attacher &attacher);
    void _dettach(Attacher &attacher);
};

class iSingleAttacheeEntity : public iAttacheeEntity
{
public:
    friend class Attacher;
    iSingleAttacheeEntity(Entity &e) : iAttacheeEntity(e), attacher(0)
    {
    }
    virtual ~iSingleAttacheeEntity()
    {
        if (this->attacher)
            dettach(*this->attacher);
    }
    void attach(Attacher &attacher);
    void dettach(Attacher &attacher);
protected:
    Attacher *attacher;
};

class iMultiAttacheeEntity : public iAttacheeEntity
{
public:
    friend class Attacher;
    iMultiAttacheeEntity(Entity &e) : iAttacheeEntity(e)
    {
    }
    virtual ~iMultiAttacheeEntity()
    {
        for (size_t i = 0; i < attachers.size(); i++)
        {
            _dettach(*attachers[i]);
        }
        attachers.clear();
    }
    void attach(Attacher &attacher);
    void dettach(Attacher &attacher);
protected:
    vector<Attacher *> attachers;
};

class Attacher
{
public:
    friend class iAttacheeEntity;
protected:
    virtual void attach(iAttacheeEntity &entity) = 0;
    virtual void dettach(iAttacheeEntity &entity) = 0;
    virtual void OnAttach(iAttacheeEntity &entity)
    {
        entity;
    }
    virtual void OnDettach(iAttacheeEntity &entity)
    {
        entity;
    }
};

// One on One attacher
class SingleAttacher : public virtual Attacher
{
public:
    SingleAttacher() : entity(0)
    {
    }
    virtual ~SingleAttacher()
    {
        if (isAttached())
        {
            entity->dettach(*this);
        }
    }
    bool isAttached() const
    {
        return entity != 0;
    }
    Entity* getEntity()
    {
        if (isAttached())
            return &entity->getEntity();

        return 0;
    }
    const Entity* getEntity() const
    {
        if (isAttached())
            return &entity->getEntity();

        return 0;
    }
protected:
    void attach(iAttacheeEntity &entity)
    {
        assert(this->entity == 0);

        this->entity = &entity;

        OnAttach(entity);
    }
    void dettach(iAttacheeEntity &entity)
    {
        assert(this->entity == &entity);

        OnDettach(entity);

        this->entity = 0;
    }
    iAttacheeEntity* entity;
};

class MultiAttacher : public virtual Attacher
{
public:
    virtual ~MultiAttacher()
    {
        while(!entities.empty())
        {
            entities.front()->dettach(*this);
        }
    }
    size_t getAttachedCount() const
    {
        return entities.size();
    }
protected:
    void attach(iAttacheeEntity &entity)
    {
        if (find(entities.begin(), entities.end(), &entity) != entities.end())
        {
            assert(0);
            return;
        }
        entities.push_back(&entity);

        OnAttach(entity);
    }
    void dettach(iAttacheeEntity &entity)
    {
        OnDettach(entity);

        vector<iAttacheeEntity*>::iterator ie = find(entities.begin(), entities.end(), &entity);
        if (ie == entities.end())
        {
            assert(0);
            return;
        }
        entities.erase(remove(entities.begin(), entities.end(), &entity), entities.end());
    }
    vector<iAttacheeEntity*> entities;
};

inline
void iAttacheeEntity::_attach(Attacher &attacher)
{
    attacher.attach(*this);
}

inline
void iAttacheeEntity::_dettach(Attacher &attacher)
{
    attacher.dettach(*this);
}

inline
void iSingleAttacheeEntity::attach(Attacher &attacher)
{
    if (this->attacher)
        dettach(attacher);
    _attach(attacher);
    this->attacher = &attacher;
}

inline
void iSingleAttacheeEntity::dettach(Attacher &attacher)
{
    assert(this->attacher == &attacher);
    _dettach(attacher);
    this->attacher = 0;
}

inline
void iMultiAttacheeEntity::attach(Attacher &attacher)
{
    if (!this->attachers.empty())
    {
        vector<Attacher*>::iterator ia = find(this->attachers.begin(), this->attachers.end(), &attacher);
        if (ia != this->attachers.end())
        {
            assert(0 && "already attached to the attacher");
            return;
        }
    }
    _attach(attacher);
    this->attachers.push_back(&attacher);
}

inline
void iMultiAttacheeEntity::dettach(Attacher &attacher)
{
    assert(!this->attachers.empty());
    vector<Attacher*>::iterator ia = find(this->attachers.begin(), this->attachers.end(), &attacher);
    if (ia != this->attachers.end())
    {
        _dettach(**ia);
        swap(*ia, this->attachers.back());
        this->attachers.pop_back();
    }
    else
    {
        assert(0 && "not attached to the attacher");
    }
}
#endif//COMMON_ATTACH_ENTITY_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -