Фокусы с Compound

Недавно столкнулся с интересной задачей: описанием класса, который инкапсулирует неизвестный заранее набор объектов. Типы этих объектов задаются через variadic template – то есть, шаблон с переменным количеством параметров. Статические массивы для этой задачи, ясное дело, не годятся, но тут идеально подошел Compound из dlib.core.compound. Это своеобразный “гибрид” кортежа и структуры – составной тип данных, который можно создавать в шаблонах. Ему можно передавать кортеж параметров variadic-шаблона, и это позволяет проделывать замечательные вещи.

class Collection(C...)
{
    protected Compound!C _components;

    this(C comps)
    {
        _components = comps;
    }
}

auto inc = new Collection!(int, char, bool)(10, 'a', false); 

Проблема с обычными кортежами (Tuple) в том, что их нельзя возвращать из функции. Но Compound – можно. Таким образом, для ридонли-доступа к _components мы можем объявить следующий метод:

auto components() @property
{
    return _components;
}

А еще мы можем заполнять Compound в цикле, читая значения, например, из массива:

this(int[] arr)
{
    foreach(i, T; C)
    {
        _components[i] = cast(T)arr[i];
    }
}

auto inc = new Collection!(int, char, bool)([5, 40, 0]);

Пример бессмысленный, но наглядный – мы проходим по всем типам кортежа C и записываем входное значение в наш Compound, конвертируя в нужный тип. Без дополнительных проверок это небезопасно, но если вы знаете, что делаете – очень полезно.

Dagon

Прошу читателей этого блога извинить меня за редкие посты. Более полугода я не отчитывался по работе над Atrium — спешу заверить, что проект не похоронен, прогресс понемногу идет, просто чуть медленнее, чем хотелось бы. Последние несколько месяцев я был занят дипломной работой в институте, поэтому свободного времени для геймдева было крайне мало.

Те, кто следит за моей активностью на GitHub, могли заметить, что у меня появился новый репозиторий dagon — проект, который позиционируется как новая эволюционная ступень DGL. В процессе работы над Atrium я пришел к выводу, что в движке не хватает средств автоматизации некоторых рутинных задач. Например, управление памятью в типичном игровом приложении может быть почти полностью автоматизировано, поскольку выделение и высвобождение памяти происходит в специально задуманных паузах, таких как переключение между локациями (это не относится к играм с открытым миром с фоновой подгрузкой, но это уже специфический случай). Кроме того, в обсуждении на Reddit звучал вопрос, почему DGL не использует SDL2. Так родилась новая ветка движка, которую я решил сделать отдельным экспериментальным проектом.

На сегодняшний день Dagon включает следующие возможности:

  • Использование SDL2
  • Новая модель памяти на основе концепции владельца (owner), позаимствованной из Delphi
  • Модель образцов и компонентов (entity-component), позволяющая расширять функциональность объектов динамически, без наследования классов
  • Динамическая перезагрузка ресурсов при их модификации сторонним приложением без перезапуска игры
  • Поддержка форматов OBJ и IQM
  • Поддержка текстур PNG, JPG, TGA, BMP
  • Поддержка контейнера Box для ресурсов
  • Новая система материалов с разделением на фронтенд (набор параметров) и бэкенд (передатчик параметров графическому конвейеру — фиксированному или шейдерному, в зависимости от выбранной реализации бэкенда). Система позволяет использовать как стандартные материалы с известным набором параметров, так и создавать свои, специализированные
  • Некоторые компоненты, напрямую портированные из DGL — например, система событий, система освещения, рендеринг текста.
Как только будет дописана система материалов и поддержка формата DGL3, я начну портировать Atrium на новый движок.