Может ли кто-нибудь помочь мне создать контейнер переменных с помощью Boost :: MPL?

Я создал физическую систему, которая обрабатывает любой объект столкновения с любым объектом столкновения следующим образом:

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();
    ...
    ...
}

Мне бы хотелось вывести контейнеры с помощью функций добавления, чтобы система автоматически обновляла списки типов. Думаю, я понимаю, как создать список типов с помощью функции шаблона, но не знаю, как затем получить его там, где он мне нужен, или в какой момент компиляции он завершен.

Если не это, то некоторая система, использующая два списка типов, n внутренне записывает функцию обновления для перебора всех списков, сопоставляя их друг с другом.

Я читал некоторые книги о повышении MPL и несколько раз читал книгу Андрея. Но я, кажется, зациклен на том, как это работает, и не очень понимаю, как я его использую. Я бы хотел, чтобы у них был еще один раздел о реальных примерах в книге MPL.

Мне удалось заставить все части игрового движка взаимодействовать с рендерингом, физикой, столкновениями (я отделяю обнаружение от реакции), вводом, сетью, звуком и т. Д. Все в общих чертах. Теперь мне просто нужно держать все в общих чертах.После всей этой общей работы было бы глупо требовать наследования только для того, чтобы я мог что-то хранить в контейнере, и я не хочу передавать код для каждой возможности сбора, поскольку это одно из больших преимуществ универсального программирования.

Я видел, как Джалф указал, что он / она использовал MPL для чего-то подобного, но не вдавался в подробности достаточно, чтобы я мог это понять. Если кто-нибудь знает пример практического использования или где я могу получить дополнительную информацию об использовании MPL, я был бы признателен.

Еще раз спасибо!

Обновление

ускоряет MPL и ускоряет Fusion, кажется, что я делаю то, что я хочу, но, похоже, очень мало хороших примеров из реальной жизни обеих библиотек. Документация для MPL немного больше, чем этот шаблон, и удачи в понимании последствий этого. Fusion немного лучше: «Вот пример, но это только верхушка айсберга!»

Типичным примером ускоренного MPL является has_xxx. Они используют XXX и xxx в примере, что затрудняет понимание разницы, где XXX (требуемый текст) и Test или CheckType или любой другой различимый тип пользователя может использоваться вместо xxx. Плюс нет упоминания о том, что ничего из этого не находится в пространстве имен. Теперь я знаю, почему Скотт Мейерс сравнил это со сценой в душе в «Психо».

Это действительно позор, потому что то немногое, что я получил для компиляции и понимания, действительно полезно, но это так сложно понять, что я бы никогда не потратил столько усилий, если бы я работал с готовым продуктом.

Если кто-нибудь знает примеры из реального мира или лучшие ссылки, объяснения или учебные пособия, я был бы признателен.

Обновление

Вот еще код:

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);

Затем все, что мне нужно, это вызвать collide со всеми моими активными сталкивающимися объектами против всех моих активных и пассивных объектов.

Я не использую std :: function, потому что добавление имен функций делает код более понятным для меня. Но, возможно, это просто устаревшее мышление.

6
задан Luc Touraille 2 December 2011 в 09:11
поделиться