2016-09-12 3 views
1

작은 엔티티/구성 요소 시스템을 C++에서 작동 시키려고합니다. 지금까지는 괜찮습니다.별로 도움이되지 않지만 문제가 있습니다. 각 구성 요소는 기본 클래스 Component에서 파생하고 다음과 같이 사용, 그것은 매우 간단합니다,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; 
}; 

위에서 볼 수 있듯이 :
여기 내 현재 코드입니다

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입니까?

간단한 시도/캐치가 충분합니까? 여기에 어떻게 구현해야합니까?

답변

0

당신은 포인터를 확인할 수 있습니다 :

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

을 아니면 HasComponent 방법 추가 :이지도에서 nullptr를 삽입하지 않는

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

당신은 또한 너무 GetComponent을 수정할 수 있습니다 :

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]); 
} 
+0

나는 '컴포넌트'가 매 t마다 존재하는지 확인하는 것 외에는 선택의 여지가 없다고 생각합니다. 예! 작은 일로,'HasComponent'가'std :: shared_ptr <>'대신에 부울을 반환하지 않아야합니까? – Usiten

+0

@Usiten 네, 맞습니다. 복사하여 붙여 넣기에 오류가 있습니다. 고맙습니다. – skypjack