I'm writing a Data-Oriented programming registry, which kind of looks like a ECS registry and works like this:
void KillEnemy(EnemyList &enemies, ProjectileList &projectiles);
int main() {
auto registry
= Registry{}
.add_data(EnemyList{})
.add_data(ProjectileList{})
.add_data(TerrainList{});
//automatically call KillEnemy with proper arguments.
registry.call(KillEnemy);
}
I haven't figured out the add_data
part yet, but I think it could be done with constexpr
and std::tuple
. My current implementation for Registry
looks like this:
struct Registry {
std::tuple<int, double, float> data;
template<typename R, typename... Args>
R call(R (*f)(Args...)) {
return f(std::get<Args>(data)...);
}
};
This works for function pointers, but it would be more ergonomic if I could use it with lambdas. I can't figure out a way to deduce the parameters. Is it possible?
Update: I just wrote add_data
. This is my current implementation:
template <typename... DataType>
struct Reg {
std::tuple<DataType...> data;
template<typename R, typename... Args>
R call(R (*f)(Args...)) {
return f(std::get<std::remove_reference_t<Args>>(data)...);
}
template<typename T>
constexpr Reg<T, DataType...> add_data(T new_data = {}) &&{
return {std::tuple_cat(std::move(data), std::tuple<T>(new_data))};
}
};
int main() {
auto r = Reg<>{}
.add_data<int>()
.add_data<double>()
.add_data<float>();
r.call(system_with_duble);
r.call(system_with_float);
r.call(system_with_double_and_float);
}