Я создал физическую систему, которая обрабатывает любой объект столкновения с любым объектом столкновения следующим образом:
namespace Collision
{
template <typename T, typename U>
inline void Check(T& t, U& u)
{
if(u.CheckCollision(t.GetCollider()))
{
u.HitBy(t);
t.Hit(u);
}
}
}
, и есть несколько других вспомогательных объектов, которые облегчают его использование, но суть в том, что естьявляются динамическими объектами, которые необходимо проверять на соответствие статическим объектам и другим динамическим объектам, но статические объекты проверять не нужно.
Я хотел бы получить что-то вроде этого:
void func()
{
PhysicsWorld world;
shared_ptr<CSphere> ballPhysics(new CSphere(0,0,ballSprite->Width()));
BallCommand ballBehavior;
CBounds bounds(0, 0, 640, 480);
CBox obstacle(200, 150, 10, 10);
Collision::Collidable<CBounds> boundC(bounds);
Collision::Collidable<std::shared_ptr<CSphere>, BallCommand&> ballC(ballPhysics, ballBehavior);
Collision::Collidable<CBox> obstC(obstacle);
world.addStatic(boundC);
world.addDynamic(ballC);
world.addStatic(obstC);
...
...
world.Update();
...
...
}
Я бы хотел вывести контейнеры с помощью функций добавления, чтобы при использовании системы автоматически обновлялись списки типов.Я думаю, что понимаю, как сгенерировать список типов с помощью функции шаблона, но не как потом получить его там, где он мне нужен, или на каком этапе компиляции он завершен.
Если нет, то какая-то система, использующая двасписки типов, которые затем внутренне записывают функцию обновления, чтобы перебирать все списки, объединяя их друг с другом.
Я прочитал некоторые книги по ускоренному MPL и прочитал книгу Андрея несколько раз.Но я, кажется, увлекся тем, как это работает, и не перевожу это на то, как мне это использовать.Хотелось бы, чтобы у них был еще один раздел о реальных примерах в книге MPL.
Мне удалось заставить все части игрового движка взаимодействовать с рендерингом, физикой, столкновениями (я отделяю обнаружение от реакции), вводом, сетью, звуком и т. Д. Все в общих чертах.Теперь мне просто нужно обобщить все вещи.После всей этой общей работы было бы глупо требовать наследования, просто чтобы я мог что-то хранить в контейнере, и я не хочу передавать код каждой возможности сбора, так как это одно из больших преимуществ универсального программирования.
Я видел, что Джальф указал, что он / она использовал MPL, чтобы сделать что-то подобное, но не вдавался в подробности, чтобы я мог это выяснить.Если кто-нибудь знает пример практического использования или где я могу получить больше информации об использовании MPL, я был бы благодарен.
Еще раз спасибо!
Обновление
повышение MPL и повышение Fusion оба, кажется, делают то, что я хочу, но, похоже, очень мало вспособ хороших примеров из реальной жизни любой библиотеки.Документация по MPL немного больше, чем этот шаблон, и удачи в понимании последствий этого.Fusion немного лучше с «Вот пример, но это только верхушка айсберга!»
Типичный пример MPL для повышения - has_xxx.В этом примере они используют XXX и xxx, что затрудняет понимание разницы, где вместо xxx можно использовать XXX (требуемый текст) и Test или CheckType или любой более различимый тип пользователя.Кроме того, нет упоминания о том, что ничего этого нет в пространстве имен.Теперь я знаю, почему Скотт Мейерс сравнил это с душевой в «Психо».
Это действительно позор, потому что то, что я получил, чтобы собрать и понять, действительно полезно, но так сложно понять, что я никогдаПотратьте столько усилий, если бы я занимался доставкой товара.
Если кто-то знает примеры из реального мира или лучшие ссылки, объяснения или учебное пособие, я был бы признателен.
Обновление
Вот еще код:
template <typename T, typename V = VictimEffect, typename M = MenaceEffect>
class Collidable
{
T m_Collider;
V m_HitBy;
M m_Hit;
public:
Collidable(T collide, V victim, M menace) : m_Collider(collide), m_HitBy(victim), m_Hit(menace) {;}
Collidable(T collide) : m_Collider(collide) {;}
Collidable(T collide, V victim) : m_Collider(collide), m_HitBy(victim) {;}
T& GetCollider()
{
return m_Collider;
}
template <typename V>
void HitBy(V& menace)
{
m_HitBy.HitBy(menace.GetCollider());
}
template <typename V>
void Hit(V& victim)
{
m_Hit.Hit(victim.GetCollider());
}
template <typename V>
bool CheckCollision(V& menace)
{
return m_Collider.CheckCollision(menace);
}
};
Затем, чтобы использовать его, я делаю это
Collidable<Boundary, BallCommand> boundC(boundary, ballBehavior);
Collidable<CollisionBox> ballC(circle);
Затем всеМне нужно вызвать callide со всеми моими активными объектами, которые могут быть сопоставлены со всеми моими активными и пассивными объектами.
Я не использую std :: function, потому что добавление имен функций делает код более понятным для меня.Но, возможно, это просто устаревшее мышление.