Skip to content

Instantly share code, notes, and snippets.

@DCFApixels
Last active April 18, 2024 10:38
Show Gist options
  • Save DCFApixels/46d512dbcf96c115b94c3af502461f60 to your computer and use it in GitHub Desktop.
Save DCFApixels/46d512dbcf96c115b94c3af502461f60 to your computer and use it in GitHub Desktop.
using static DCFApixels.DragonECS.EcsOneFrameComponentConsts;
namespace DCFApixels.DragonECS
{
[MetaTags(MetaTags.HIDDEN)]
[MetaColor(MetaColor.Grey)]
public class DeleteOneFrameComponentSystem<TComponent> : IEcsRun, IEcsInject<EcsWorld>
where TComponent : struct, IEcsComponent
{
private sealed class Aspect : EcsAspect
{
public EcsPool<TComponent> pool = Inc;
}
private readonly List<EcsWorld> _worlds = new List<EcsWorld>();
public void Inject(EcsWorld obj) => _worlds.Add(obj);
public void Run()
{
for (int i = 0, iMax = _worlds.Count; i < iMax; i++)
{
EcsWorld world = _worlds[i];
if (world.IsComponentTypeDeclared<TComponent>())
{
foreach (var e in world.Where(out Aspect a))
{
a.pool.Del(e);
}
}
}
}
}
[MetaTags(MetaTags.HIDDEN)]
[MetaColor(MetaColor.Grey)]
public class DeleteOneFrameTagComponentSystem<TComponent> : IEcsRun, IEcsInject<EcsWorld>
where TComponent : struct, IEcsTagComponent
{
private sealed class Aspect : EcsAspect
{
public EcsTagPool<TComponent> pool = Inc;
}
private readonly List<EcsWorld> _worlds = new List<EcsWorld>();
public void Inject(EcsWorld obj) => _worlds.Add(obj);
public void Run()
{
for (int i = 0, iMax = _worlds.Count; i < iMax; i++)
{
EcsWorld world = _worlds[i];
if (world.IsComponentTypeDeclared<TComponent>())
{
foreach (var e in world.Where(out Aspect a))
{
a.pool.Del(e);
}
}
}
}
}
public static class EcsOneFrameComponentConsts
{
public const string AUTO_DEL_LAYER = nameof(AUTO_DEL_LAYER);
}
public static class DeleteOneFrameComponentSystemExtensions
{
public static EcsPipeline.Builder AutoDel<TComponent>(this EcsPipeline.Builder b, string layerName = null)
where TComponent : struct, IEcsComponent
{
if (AUTO_DEL_LAYER == layerName)
{
b.Layers.InsertAfter(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
}
b.AddUnique(new DeleteOneFrameComponentSystem<TComponent>(), layerName);
return b;
}
public static EcsPipeline.Builder AutoDelToEnd<TComponent>(this EcsPipeline.Builder b)
where TComponent : struct, IEcsComponent
{
b.Layers.InsertAfter(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
b.AddUnique(new DeleteOneFrameComponentSystem<TComponent>(), AUTO_DEL_LAYER);
return b;
}
}
public static class DeleteOneFrameTagComponentSystemExtensions
{
public static EcsPipeline.Builder AutoDel<TComponent>(this EcsPipeline.Builder b, string layerName = null)
where TComponent : struct, IEcsTagComponent
{
if (AUTO_DEL_LAYER == layerName)
{
b.Layers.InsertAfter(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
}
b.AddUnique(new DeleteOneFrameTagComponentSystem<TComponent>(), layerName);
return b;
}
public static EcsPipeline.Builder AutoDelToEnd<TComponent>(this EcsPipeline.Builder b)
where TComponent : struct, IEcsTagComponent
{
b.Layers.InsertAfter(EcsConsts.POST_END_LAYER, AUTO_DEL_LAYER);
b.AddUnique(new DeleteOneFrameTagComponentSystem<TComponent>(), AUTO_DEL_LAYER);
return b;
}
}
}

Однокадровые компоненты

Этот небольшой скрипт реализует упрощенный механизм отчистки однокадровых компонентов.

_world = new EcsDefaultWorld();
_eventWorld = new EcsEventWorld();

_pipeline = EcsPipeline.New()
    .Add(new SomeSystem1())
    .Add(new SomeSystem2())
    // Добавит автоматическое удаление компонентов SomeEvent1 в самый конец пайплайна, 
    // на специальный слой после EcsConsts.POST_END_LAYER.
    .AutoDelToEnd<SomeEvent1>();
    // Добавит автоматическое удаление компонентов SomeEvent2 до системы SomeSystem3, 
    // так как SomeSystem3 тоже добавится на слой EcsConsts.BASIC_LAYER.
    .AutoDel<SomeEvent2>();
    .Add(new SomeSystem3())
    // Удаление будет происходить во всех мирах внедренных в пайплайн через `EcsPipeline.Inject`. 
    .Inject(_world, _eventWorld)
    .BuildAndInit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment