C ++组件系统问题

时间:2016-09-12 09:59:34

标签: c++ entity components

我正在尝试使用一个小的实体/组件系统来使用C ++。到目前为止它没关系,但是我面临着一个问题 这是我目前的代码:

class Entity {
public:
    // [...]
    template<typename T, typename ...Args>
    bool AddComponent(Args... args) {
        std::type_index tid = std::type_index(typeid(T));
        if (_Components[tid] == nullptr) {
            _Components[tid] = std::make_shared<T>(args...);
            return true;
        }
        return false;
    }

    template<typename T>
    std::shared_ptr<T> GetComponent() {
        // Issue here
        std::type_index tid = std::type_index(typeid(T));
        return std::dynamic_pointer_cast<T>(_Components[tid]); // return nullptr if no component
    }

    template<typename T>
    bool RemoveComponent() {
        std::type_index tid = std::type_index(typeid(T));
        if (_Components.erase(tid) == 1) return true;
        return false;
    }

    private:
        std::map<std::type_index, std::shared_ptr<Component>> _Components;
};

如上所示,它非常简单,每个组件都派生自基类Component,用法如下:

class Component;
class MyComponent: public Component {
    // [...]
    MyComponent(int foo_): foo(foo_) {}
    int foo;
}

Entity e;
e.AddComponent<MyComponent>(42);
std::cout << e.GetComponent<MyComponent>()->foo; // 42
e.RemoveComponent<MyComponent>();
std::cout << e.GetComponent<MyComponent>()->foo; // Error

错误是逻辑,我理解为什么,但我的问题是如何在调用已被删除的Component时防止出现错误,因此nullptr不会导致程序崩溃?

是一个简单的尝试/捕捉足够吗?应该如何在这里实施?

1 个答案:

答案 0 :(得分:0)

您可以检查指针:

auto ptr = e.GetComponent<MyComponent>();
if(ptr) ptr->foo();

或添加HasComponent方法:

template<typename T>
bool HasComponent() {
    std::type_index tid = std::type_index(typeid(T));
    return _Components.find(tid) != _Components.cend();
}

您还可以修改GetComponent,因为它不会在地图中插入nullptr

template<typename T>
std::shared_ptr<T> GetComponent() {
    std::type_index tid = std::type_index(typeid(T));
    return (_Components.find(tid) == _Components.cend()) ? nullptr : std::dynamic_pointer_cast<T>(_Components[tid]);
}