Начал изучать tiny-ecs:
Решил перевести API:
Если время найду, то под этим постом буду кидать простые примеры с использованием ecs.
Вот несколько небольших примеров на данный момент:
defolder/forum/solutions/tiny_ecs at main · dprogrb/defolder
Contribute to dprogrb/defolder development by creating an account on GitHub.
Пока что они просто как примеры, т.к я ещё не уверен в том, что я делаю правильно некоторые вещи.
По мере изучения ECS, буду выкладывать сюда больше примеров.
Мировые функции
World - это контейнер, который управляет объектами и системами. Как правило, программа использует один мир за раз.
Для всех мировых функций, кроме tiny.world(...), вместо документированного синтаксиса может использоваться объектно-ориентированный синтаксис. Например, tiny.add(world, e1, e2, e3) - это то же самое, что и world:add(e1, e2, e3).
Системные функции
Система - это оболочка для обратных вызовов функций для управления объектами. Системы реализованы в виде таблиц, содержащих по крайней мере один метод; функция обновления, которая принимает параметры типа:
function system:update(dt).
Есть также несколько других необязательных обратных вызовов:
-
function system:filter(entity)- Возвращает значениеtrue, если эта система должна включать эту сущность, в противном случае должно быть возвращено значениеfalse. Если это не указано, сущности в Систему не включены. -
function system:onAdd(entity)- вызывается при добавлении сущности в Систему. -
function system:onRemove(entity)- вызывается при удалении сущности из системы. -
function system:onModify(dt)- Вызывается при изменении Системы путем добавления или удаления сущности из системы. -
function system:onAddToWorld(world)- Вызывается при добавлении Системы в World, перед добавлением каких-либо объектов в систему. -
function system:onRemoveFromWorld(world)- Вызывается, когда Система удаляется из мира, после того, как все объекты удалены из Системы. -
function system:preWrap(dt)- вызывается в каждой системе перед вызовом обновления в любой системе. -
function system:postWrap(dt)- Вызывается в каждой системе в обратном порядке после того, как в каждой системе будет запущено обновление. Идея предварительной и последующей обработки состоит в том, чтобы разрешить использование систем, которые изменяют поведение других систем. Допустим, есть система рисования, которая выводит спрайты на экран, и система постобработки, которая добавляет некоторые эффекты размытия и цветения. В методе предварительной обработкиPostProcessingSystemсистема могла бы установить целевой объект рисования дляDrawingSystemв специальный буфер вместо экрана. В методеpostWrapсистема постпроцессинга может затем изменить буфер и отобразить его на экране. При такой настройкеPostProcessingSystemбудет добавлена вWorldпослеdrawingSystem(аналогичное, но менее гибкое поведение можно было бы реализовать с помощью одной пользовательской функции обновления вDrawingSystem).
Для фильтров удобно использовать tiny.RequireAll или tiny.RequireAny, но можно написать и свои собственные фильтры. Установите фильтр системы следующим образом:
system.filter = tiny.requireAll("a", "b", "c")
Или
function system:filter(entity)
return entity.myRequiredComponentName ~= nil
end
Во всех системах также есть несколько важных полей, которые инициализируются при добавлении системы в World. Некоторые из них важны, но их следует использовать реже.
- Поле “Мир” указывает на мир, к которому принадлежит Система. Полезно для динамического добавления и удаления объектов из мира с помощью Системы.
- Активный флаг указывает, обновляется ли система автоматически. Неактивные системы следует обновлять вручную или не обновлять вообще с помощью
system:update(dt). Значение по умолчанию равноtrue. - Поле сущности представляет собой упорядоченный список сущностей в системе. Этот список можно использовать для быстрого просмотра всех сущностей в системе.
- Поле интервал - это необязательное поле, которое позволяет обновлять системы с определенными интервалами, используя буферизованное время, независимо от частоты обновления в мире. Например, чтобы обновлять систему раз в секунду, установите системный интервал равным 1.
- Поле индекс - это индекс системы в мире. Системы с более низким индексом обрабатываются раньше, чем системы с более высоким индексом. Индекс - это поле, доступное только для чтения; чтобы задать индекс, используйте
tiny.setSystemIndex(world, system). - Поле “Индексы” представляет собой таблицу ключей сущностей к их индексам в списке сущностей. Большинство систем могут игнорировать это.
- Флаг modified указывает на то, что Система была изменена в последнем обновлении. Если это так, то обратный вызов onModify будет вызван в Системе при следующем обновлении, если оно есть. Обычно этим занимается tiny-ecs, поэтому пользователям в основном также следует игнорировать это.
Есть еще один способ (надеюсь) повысить производительность в системах, в которые часто добавляются или удаляются элементы, а также в которых много объектов. Установка поля nocache в системе может повысить производительность. Это все еще экспериментальный вариант. Однако существуют некоторые ограничения для систем без кэширования.
- Нет таблицы “сущности”.
- Обратные вызовы, такие как onAdd, onRemove и onModify, никогда не будут вызываться
- Некэшированные системы не могут быть отсортированы (нет списка сущностей для сортировки).
Функции фильтрации
Фильтр - это функция, которая выбирает, какие сущности применяются к системе. Фильтры принимают два параметра, Систему и Сущность, и возвращают логическое значение, указывающее, должна ли сущность обрабатываться Системой. Истинное значение включает сущность, в то время как ложное значение (nil или false) исключает сущность.
Фильтры должны быть добавлены в системы путем установки поля filter в системе. Фильтры, возвращаемые функциями фильтрации tiny-ecs, являются неизменяемыми и могут использоваться несколькими системами.
```
local f1 = tiny.requireAll("position", "velocity", "size")
local f2 = tiny.requireAny("position", "velocity", "size")
local e1 = {
position = {2, 3},
velocity = {3, 3},
size = {4, 4}
}
local entity2 = {
position = {4, 5},
size = {4, 4}
}
local e3 = {
position = {2, 3},
velocity = {3, 3}
}
print(f1(nil, e1), f1(nil, e2), f1(nil, e3)) -- prints true, false, false
print(f2(nil, e1), f2(nil, e2), f2(nil, e3)) -- prints true, true, true
Фильтры также можно передавать в качестве аргументов другим конструкторам фильтров. Это эффективный способ создания сложных пользовательских фильтров, которые выбирают очень специфический набор объектов.
-- Selects Entities with an "image" Component, but not Entities with a
-- "Player" or "Enemy" Component.
filter = tiny.requireAll("image", tiny.rejectAny("Player", "Enemy"))
World functions
Развернуть
tiny.world (…)
Создаёт новый Мир. При желании можно добавить Системы и Сущности по умолчанию.
Возвращает новый мир вместе с Сущностями и Системами.
tiny.addEntity (world, entity)
Добавляет объект в мир. Также вызывайте это для Сущностей, компоненты которых были изменены таким образом, чтобы они соответствовали различным Фильтрам. Возвращает Сущность.
tiny.addSystem (world, system)
Добавляет объект в мир. Также вызывайте это для Сущностей, Компоненты которых были изменены таким образом, чтобы они соответствовали различным фильтрам.
Возвращает Сущность.
tiny.add (world, …)
Ярлык для добавления нескольких Сущностей и Систем в World. Возвращает все добавленные Сущности и Системы.
tiny.removeEntity (world, entity)
Удаляет сущность из Мира. Возвращает сущность.
tiny.removeSystem (world, system)
Удаляет Систему из мира. Возвращает Систему.
tiny.remove (world, …)
Ярлык для удаления нескольких Сущностей и Систем из мира. Возвращает все удаленные Системы и Сущности.
tiny.refresh (world)
Управляет Сущностями и Системами, помеченными для удаления или добавления. Вызывайте это перед изменением Систем и Сущностей вне вызова tiny.update. Не вызывайте это в рамках вызова tiny.update.
tiny.update (world, dt, filter)
Обновляет мир по времени dt (delta time). Принимает необязательный параметр filter, который является Фильтром, который выбирает Системы из мира и обновляет только эти Системы. Если filter не указан, обновляются все Системы. Включите эту функцию в свой основной цикл.
tiny.clearEntities (world)
Удаляет все Сущности из Мира.
tiny.clearSystems (world)
Удаляет все Системы из мира.
tiny.getEntityCount (world)
Получает количество Сущностей в Мире.
tiny.getSystemCount (world)
Получает количество Систем в мире.
tiny.setSystemIndex (world, system, index)
Устанавливает индекс Системы в мире и возвращает старый индекс. Изменяет порядок обработки этих Систем, поскольку сначала обрабатываются Системы с более низким индексом. Возвращает старый system.index.
System functions
Развернуть
tiny.system (table)
Создает новую Cистему или Cистемный класс на основе предоставленной таблицы. Если значение таблицы равно нулю, создает новую таблицу.
tiny.processingSystem (table)
Создает новую Cистему обработки или класс Cистемы обработки. Системы обработки обрабатывают каждый объект индивидуально и обычно являются тем, что требуется. Системы обработки имеют три дополнительных обратных вызова, помимо тех, которые унаследованы от стандартных систем.
function system:preProcess(dt) -- Called before iteration. function system:process(entity, dt) -- Process each entity. function system:postProcess(dt) -- Called after iteration.Системы обработки имеют свой собственный метод обновления, поэтому не реализовывайте обратный вызов пользовательского обновления для систем обработки.
tiny.sortedSystem (table)
Создает новую отсортированную систему или класс Sorted System. Отсортированные системы сортируют свои объекты в соответствии с определенным пользователем методом system:compare(e1, e2), который должен возвращать значение true, если e1 должно предшествовать e2, и значение false в противном случае. Отсортированные системы также переопределяют обратный вызов onModify в системе по умолчанию, поэтому будьте осторожны при определении пользовательского обратного вызова. Однако для обработки отсортированных объектов рассмотрите tiny.sortedProcessingSystem(таблица).
tiny.sortedProcessingSystem (table)
Создает новую систему сортированной обработки или класс систем сортированной обработки. Системы сортированной обработки имеют как аспекты систем обработки, так и сортированных систем.
Filter functions
Развернуть
tiny.requireAll (…)
Создает Фильтр, который выбирает Сущности со всеми указанными Компонентами и Фильтрами.
tiny.requireAny (…)
Создает фильтр, который выбирает Сущности со всеми указанными Компонентами и Фильтрами.
tiny.rejectAll (…)
Создает фильтр, который отклоняет сущности со всеми указанными компонентами и фильтрами и выбирает все остальные сущностями.
tiny.rejectAny (…)
Создает фильтр, который отклоняет сущности, содержащие хотя бы один из указанных компонентов и фильтров, и выбирает все остальные сущности.
tiny.filter (pattern)
Создает фильтр из строки. Синтаксис шаблона следующий.
Токены представляют собой буквенно-цифровые строки, включая символы подчеркивания.
Токены могут быть разделены символами |, & или заключены в круглые скобки.
К токенам может быть добавлен префикс !, а затем они могут быть инвертированы.
Примеры являются лучшими:
```
'a|b|c' - Matches entities with an 'a' OR 'b' OR 'c'.
'a&!b&c' - Matches entities with an 'a' AND NOT 'b' AND 'c'.
'a|(b&c&d)|e - Matches 'a' OR ('b' AND 'c' AND 'd') OR 'e'
```


