Skip to content

Instantly share code, notes, and snippets.

@rossimo
Created July 23, 2021 17:48
Show Gist options
  • Save rossimo/d967d84ea5cfddcc48939696ae56aeb8 to your computer and use it in GitHub Desktop.
Save rossimo/d967d84ea5cfddcc48939696ae56aeb8 to your computer and use it in GitHub Desktop.
using Godot;
using Leopotam.EcsLite;
public class Game : Godot.YSort
{
public EcsWorld world;
public EcsSystems systems;
public override void _Ready()
{
world = new EcsWorld();
systems = new EcsSystems(world, this)
.Add(new Renderer(world));
var sprites = world.GetPool<Sprite>();
var positions = world.GetPool<Position>();
{
var player = world.NewEntity();
ref var sprite = ref sprites.Create(world, player);
sprite.Image = "res://resources/tiles/tile072.png";
ref var position = ref positions.Create(world, player);
position.X = 50;
position.Y = 50;
}
}
public override void _PhysicsProcess(float delta)
{
systems.Run();
}
}
using Godot;
using Leopotam.EcsLite;
public struct Sprite
{
public string Image;
}
public struct Position
{
public float X;
public float Y;
}
public class Renderer : IEcsRunSystem
{
private UpdateQueue<Sprite> _spriteUpdates;
private UpdateQueue<Position> _positionUpdates;
public Renderer(EcsWorld world)
{
_spriteUpdates = new UpdateQueue<Sprite>(world);
_positionUpdates = new UpdateQueue<Position>(world);
}
public void Run(EcsSystems systems)
{
var game = systems.GetShared<Game>();
foreach (int entity in _spriteUpdates)
{
ref var sprite = ref _spriteUpdates.Get(entity);
game.AddChild(new Godot.Sprite()
{
Name = $"{entity}",
Texture = GD.Load<Texture>(sprite.Image)
});
}
foreach (int entity in _positionUpdates)
{
ref var position = ref _positionUpdates.Get(entity);
var node = game.GetNodeOrNull<Godot.Sprite>($"{entity}");
node.Position = new Vector2(position.X, position.Y);
}
}
}
using System;
using Leopotam.EcsLite;
using System.Runtime.CompilerServices;
public struct Update<T>
{
public EcsPackedEntity Entity;
}
public class UpdateQueue<C>
where C : struct
{
private EcsWorld World;
private EcsFilter Filter;
private EcsPool<C> ComponentsPool;
private EcsPool<Update<C>> UpdatePool;
public UpdateQueue(EcsWorld world)
{
World = world;
ComponentsPool = World.GetPool<C>();
UpdatePool = World.GetPool<Update<C>>();
Filter = World.Filter<C>().Inc<Update<C>>().End();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator<C> GetEnumerator()
{
return new Enumerator<C>(Filter.GetEnumerator(), World, UpdatePool);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref C Get(int entity)
{
return ref ComponentsPool.Get(entity);
}
public struct Enumerator<X> : IDisposable
where X : struct
{
EcsFilter.Enumerator _enumerator;
int _current;
readonly EcsPool<Update<X>> _updatePool;
readonly EcsWorld _world;
public Enumerator(EcsFilter.Enumerator enumerator, EcsWorld world, EcsPool<Update<X>> updatePool)
{
_enumerator = enumerator;
_updatePool = updatePool;
_world = world;
_current = -1;
}
public int Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _current;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
while (_enumerator.MoveNext())
{
var current = _enumerator.Current;
var update = _updatePool.Get(current);
_updatePool.Del(current);
if (update.Entity.Unpack(_world, out var entity))
{
_current = entity;
return true;
}
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose()
{
_enumerator.Dispose();
}
}
}
public static class UpdateUtils
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref C Create<C>(this EcsPool<C> pool, EcsWorld world, int entity)
where C : struct
{
ref var component = ref pool.Add(entity);
Update(pool, world, entity);
return ref component;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Update<C>(this EcsPool<C> pool, EcsWorld world, int entity)
where C : struct
{
ref var update = ref world.GetPool<Update<C>>().Add(entity);
update.Entity = world.PackEntity(entity);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment