Я пытаюсь реализовать универсальную библиотеку ECS на C++ для обучения. Я думал о многих способах реализации, но всегда сталкивался с проблемой. Так что, если бы вы могли помочь мне с этим :
Допустим, у меня есть constexpr hana::tuple
из hana::type_c
компонентов, например:
struct C1 {};
struct C2 {};
struct C3 {};
constexpr auto components = hana::to_tuple(hana::tuple_t<C1, C2, C3>);
И теперь у меня есть тип хранилища компонента, что здесь не проблема, поэтому назовем его Storage (тип отличается для каждого компонента):
struct Storage {};
Я хочу связать каждый компонент или каждую группу компонентов с их типом Storage
. Итак, простой способ - сделать что-то вроде этого:
constexpr auto component_storage = hana::make_tuple(
hana::make_pair(hana::to_tuple(hana::tuple_t<C1, C2>), type_c<Storage>),
hana::make_pair(hana::to_tuple(hana::tuple_t<C3>), type_c<Storage>)
);
Но теперь проблема во времени выполнения. Если я инициализирую этот кортеж, но с реальным хранилищем, а не с type_c<Storage>
, мне придется пройтись по кортежу, чтобы найти нужный мне Storage
. Все это во время выполнения нет? И это очень плохо, в моей последней версии было что-то вроде Component::getStorage()
, и она была бесплатной (но с более строгими ограничениями).
Таким образом, возникает вопрос: как я могу получить некоторую getStorage<Component>()
функцию, которая ничего не будет стоить во время выполнения? Ну, под "ничего" я подразумеваю просто вернуть ссылку на Хранилище.
РЕДАКТИРОВАТЬ: единственный способ, которым я до сих пор думал, довольно прост (звучит как хороший момент).
Псевдокод
struct LinkedStorage {
hana::tuple<...> storages;
hana::tuple<hana::pair...> index;
};
По крайней мере, что-то вроде:
constexpr auto components = hana::to_tuple(hana::tuple_t<C1, C2, C3>);
constexpr auto storage = hana::to_tuple(hana::tuple_t<Storage, Storage>);
constexpr auto index = hana::make_tuple(
hana::make_pair(hana::to_tuple(hana::tuple_t<C1>, 0),
hana::make_pair(hana::to_tuple(hana::tuple_t<C2, C3>, 1)
);
Таким образом, я должен иметь возможность найти индекс во время компиляции и просто получить доступ к нужному элементу во время выполнения. Но я новичок в метапрограммировании, так что думаю, кто-то мог бы сделать что-то намного лучше.