-
-
Notifications
You must be signed in to change notification settings - Fork 95
Главная
Svelto.ECS — результат многолетних исследований и применения принципов SOLID в разработке игр на Unity. Это одна из многих реализаций паттерна ECS, доступная для C# с различными уникальными функциями, введенными для устранения недостатков самого паттерна.
Эта вики ни в коем случае не является заменой многих статей, написанных в моем блоге http://www.sebaslab.com/, но является их дополнением. Любой, кто хорошо понимает Svelto, может внести свой вклад в нее.
Самый простой способ увидеть основные возможности Svelto.ECS - загрузить Vanilla Example. Если вы хотите убедиться в простоте его использования, я покажу вам пример:
//Устанавливаем фреймворк
void ApplicationCompositionRoot()
{
var simpleSubmissionEntityViewScheduler = new SimpleSubmissionEntityViewScheduler();
_enginesRoot = new EnginesRoot(simpleSubmissionEntityViewScheduler);
var entityFactory = _enginesRoot.GenerateEntityFactory();
var entityFunctions = _enginesRoot.GenerateEntityFunctions();
_enginesRoot.AddEngine(new BehaviourForSimpleEntityEngine(entityFunctions));
entityFactory.BuildEntity<SimpleEntityDescriptor>(new EGID(1), new[]
{
new SimpleImplementor()
});
}
//Определяем сущность
class SimpleEntityDescriptor : GenericEntityDescriptor<BehaviourEntityViewForSimpleEntity>
{
}
public class BehaviourEntityViewForSimpleEntity : EntityView
{
public ISimpleComponent simpleComponent;
}
public interface ISimpleComponent
{
public int counter {get; set;}
}
class SimpleImplementor : ISimpleComponent
{
public int counter { get; set; }
}
//Определяем движок (систему) как поведение сущности
public class BehaviourForSimpleEntityAsStructEngine : IQueryingEntityViewEngine
{
public IEntityViewsDB entityViewsDB { private get; set; }
public void Ready()
{
Update().Run();
}
//Так выглядит цикл движка.
//Движок предназначен для обработки N сущностей, где N также может быть 0 и 1.
IEnumerator Update()
{
Console.Log("Task Waiting");
while (true)
{
var entityViews =
entityViewsDB
.QueryGroupedEntityViews<BehaviourEntityViewForSimpleEntity>(0);
if (entityViews.Length> 0)
{
for (var i = 0; i < entityViews.Length; i++)
AddOne(entityViews[i].counter);
Console.Log("Task Done");
yield break;
}
yield return null;
}
}
static void AddOne(int counter)
{
counter += 1;
}
}
К сожалению, невозможно быстро понять теорию, лежащую в основе этого кода, который может выглядеть простым, но одновременно запутанным. Для понимания потребуется потратить время на чтение «стены текста» и опробовать приведенные примеры.
В последнее время я много обсуждал Svelto.ECS с несколькими, более или менее опытными программистами. Я собрал много отзывов и сделал много заметок, которые буду использовать в качестве отправной точки для своих следующих статей, где я буду больше говорить о теории и хороших практиках. Небольшой спойлер: я понял, что, когда начинаешь использовать Svelto.ECS, самое большое препятствие — смена парадигмы программирования. Удивительно, сколько я должен написать, чтобы объяснить новые концепции, представленные Svelto.ECS, по сравнению с тем небольшим количеством кода, написанного для разработки фреймворка. Фактически, в то время как сам фреймворк очень простой и облегченный, переход от ООП с активным применением наследования или обычных компонентов Unity, к «новому» модульному и слабосвязанному дизайну, который Svelto.ECS предлагает использовать, мешает людям адаптироваться к фреймворку.
Svelto.ECS активно используется в Freejam (прим. переводчика - Автор является техническим директором в этой компании). Поскольку я всегда могу объяснить коллегам основные концепции фреймворка, у них уходит меньше времени на понимание работы с ним. Хотя Svelto.ECS является настолько жестким, насколько это возможно, вредные привычки трудно побороть, поэтому пользователи склонны злоупотреблять некоторой гибкостью, позволяющей адаптировать фреймворк к «старым» парадигмам, с которыми им удобно. Это может привести к катастрофе из-за недопонимания или извращения концепций, лежащих в основе логики фреймворка. Вот почему я намерен написать как можно больше статей, тем более, что я уверен, что парадигма ECS - лучшее на данный момент решение, для написания эффективного и поддерживаемого кода для крупных проектов, которые меняются и переделываются по многу раз за несколько лет. Robocraft и Cardlife являются тому доказательством.
Я не собираюсь много говорить о теориях, лежащих в основе этой статьи. Я лишь напомню, почему я отказался от использования IoC контейнера и начал использовать исключительно ECS фреймворк: IoC контейнер - это очень опасный инструмент, если он используется без понимания самой сути инверсии управления. Как вы могли узнать из моих предыдущих статей, я различаю между собой инверсию управления созданием (Inversion of Creation Control) и инверсию управления потоком (Inversion of Flow Control). Инверсия управления потоком - это как принцип Голливуда: «Не звоните нам, мы позвоним вам». Это означает, что внедренные зависимости никогда не должны использоваться напрямую через публичные методы, так как при этом вы просто используете IoC контейнер в качестве замены любой другой формы глобальной инъекции, например синглтонов. Однако, если IoC контейнер используется по принципу Инверсии управления (IoC), то в основном всё сводится к многократному использованию паттерна “Шаблонный метод” для внедрения менеджеров, используемых только для регистрации объектов, которыми они управляют. В реальном контексте инверсии управления потоком менеджеры всегда отвечают за управление сущностями. Это похоже на паттерн ECS? Безусловно. Исходя из этого рассуждения я взял паттерн ECS и разработал на его основе жесткий фреймворк, и его использование равносильно применению новой парадигмы программирования.