Я экспериментировал с созданием системы на основе компонентов, похожей на Unity, но на С++. Мне интересно, как метод GetComponent(), который Unity реализует, работает. Это очень мощная функция. В частности, я хочу знать, какой контейнер он использует для хранения своих компонентов.
Два критерия, которые мне нужны в моем клоне этой функции, следующие. 1. Мне нужны любые унаследованные компоненты, которые нужно вернуть. Например, если SphereCollider наследует коллайдер, GetComponent <Collider> () вернет SphereCollider, прикрепленный к GameObject, но GetComponent <SphereCollider> () не вернет прикрепленный коллайдер. 2. Мне нужно, чтобы функция была быстрой. Предпочтительно, он использовал бы какую-то хэш-функцию.
Для критериев один, я знаю, что я мог бы использовать что-то похожее на следующую реализацию
std::vector<Component*> components
template <typename T>
T* GetComponent()
{
for each (Component* c in components)
if (dynamic_cast<T>(*c))
return (T*)c;
return nullptr;
}
Но это не соответствует второму критерию бытия. Для этого я знаю, что могу сделать что-то вроде этого.
std::unordered_map<type_index, Component*> components
template <typename T>
T* GetComponent()
{
return (T*)components[typeid(T)];
}
Но опять же, это не соответствует первым критериям.
Если кто-нибудь знает какой-то способ объединить эти две функции, даже если он будет немного медленнее второго примера, я бы хотел пожертвовать немного. Спасибо!