Skip to content

Commit

Permalink
bevy sytems
Browse files Browse the repository at this point in the history
  • Loading branch information
andreakarasho committed Mar 18, 2024
1 parent a83c526 commit e51e6ba
Show file tree
Hide file tree
Showing 10 changed files with 509 additions and 451 deletions.
78 changes: 78 additions & 0 deletions plugins/TinyEcs.Plugins/BevySystems.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// using System;
// using System.Collections.Generic;
// using System.Runtime.CompilerServices;
// using TinyEcs;

// namespace BevySystems;

// // https://promethia-27.github.io/dependency_injection_like_bevy_from_scratch/introductions.html

// // public interface ISystemParam
// // {
// // //object Retrieve(Dictionary<Type, ISystemParam> resources);
// // }

// public sealed class Res<T> : ISystemParam
// {
// public T Value { get; set; }
// }

// public interface ISystem
// {
// void Run(Dictionary<Type, ISystemParam> resources);
// }

// public sealed class ErasedFunctionSystem : ISystem
// {
// private readonly Action<Dictionary<Type, ISystemParam>> f;

// public ErasedFunctionSystem(Action<Dictionary<Type, ISystemParam>> f)
// {
// this.f = f;
// }

// public void Run(Dictionary<Type, ISystemParam> resources) => f(resources);
// }

// public sealed partial class Scheduler
// {
// private readonly List<ISystem> _systems = new ();
// private readonly Dictionary<Type, ISystemParam> _resources = new ();

// public void Run()
// {
// foreach (var system in _systems)
// {
// system.Run(_resources);
// }
// }

// public void AddSystem<T0>(Action<T0> system) where T0 : ISystemParam
// {
// var fn = (Dictionary<Type, ISystemParam> res) => system((T0)res[typeof(T0)]);
// _systems.Add(new ErasedFunctionSystem(fn));
// }

// public void AddSystem<T0, T1>(Action<T0, T1> system) where T0 : ISystemParam where T1 : ISystemParam
// {
// var fn = (Dictionary<Type, ISystemParam> res) => system((T0)res[typeof(T0)], (T1)res[typeof(T1)]);
// _systems.Add(new ErasedFunctionSystem(fn));
// }

// public void AddSystem<T0, T1, T2>(Action<T0, T1, T2> system) where T0 : ISystemParam where T1 : ISystemParam where T2 : ISystemParam
// {
// var fn = (Dictionary<Type, ISystemParam> res) => system((T0)res[typeof(T0)], (T1)res[typeof(T1)], (T2)res[typeof(T2)]);
// _systems.Add(new ErasedFunctionSystem(fn));
// }


// public void AddResource<T>(T resource)
// {
// _resources[typeof(Res<T>)] = new Res<T>() { Value = resource };
// }

// public void AddSystemParam<T>(T param) where T : ISystemParam
// {
// _resources[typeof(T)] = param;
// }
// }
143 changes: 50 additions & 93 deletions samples/MyBattleground/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,94 +6,59 @@

const int ENTITIES_COUNT = (524_288 * 2 * 1);

using var ecs = new World();
var systems = new SystemManager(ecs);
var ff = systems.Add<MoveSystem>();

Console.WriteLine("system name : {0}", ff.Name);

ecs.Entity<PlayerTag>();
ecs.Entity<Likes>();

var e = ecs.Entity("Main")
.Set<Position>(new Position() {X = 2})
.Set<Velocity>(new Velocity());



var query = ecs.Query<(Position, Velocity), (Not<PlayerTag>, Not<Likes>)>();
query.Each((ref Position pos, ref Velocity vel) => {

});


// Program2.Test();
//BevySystems2.Program3.Test();

systems.Update();

var rabbit = ecs.Entity();
var eats = ecs.Entity();
var carrots = ecs.Entity();
var grass = ecs.Entity();

using var ecs = new World();

e.Disable();
var enabled = e.IsEnabled();
e.Disable();
enabled = e.IsEnabled();
e.Enable();
enabled = e.IsEnabled();

// ecs.Filter<(Position, Velocity, Not<Disabled>)>()
// .Query((EntityView entity) => {
// Console.WriteLine(entity.Name());
// });

// ecs.Query((EntityView entity, ref ComponentInfo cmp) => {
// Console.WriteLine("cmp {0} size {1}", cmp.ID, cmp.Size);
// });

// var e2 = ecs.Entity("Main");
// ref var pp = ref e2.Get<Position>();
ecs.Entity<PlayerTag>();
ecs.Entity<Likes>();
ecs.Entity<Position>();
ecs.Entity<Velocity>();

var child = ecs.Entity("child 0");
var child2 = ecs.Entity("child 1");
var child3 = ecs.Entity("child 2");


e.AddChild<Hierarchy>(child);
e.AddChild<Hierarchy>(child2);
child2.AddChild<Hierarchy>(child3);
var scheduler = new Scheduler();

// these should be added automatically somehow idk...
scheduler.AddSystemParam(ecs.Query<(Position, Velocity), (Not<PlayerTag>, Not<Likes>)>());
scheduler.AddSystemParam(ecs.Query<Position>());

e.AddChild<Chunk>(child2);
e.AddChild<Chunk>(child3);
scheduler.AddSystem(
(
Query<(Position, Velocity), (Not<PlayerTag>, Not<Likes>)> query0,
Query<Position> query1,
Res<string> myText
) =>
{
query0.Each((ref Position pos, ref Velocity vel) => {
pos.X *= vel.X;
pos.Y *= vel.Y;
});

//child2.Delete();
query1.Each((ref Position pos) => { });

Console.WriteLine("What: {0}", myText.Value);
}
);

// e.ClearChildren();
// ecs.Filter<With<Parent>>().Query((EntityView entity, ref Relationship relation) => {
// Console.WriteLine("parent {0} has {1} children", entity.Name(), relation.Count);
// scheduler.AddSystem((Commands commands) => {
// commands.Entity();
// });

for (var i = 0; i < 5; ++i)
{
var c = ecs.Entity();
Console.WriteLine("Add {0}", c.ID);
e.AddChild<Hierarchy>(c);
}
scheduler.AddResource("oh shit i made it");
scheduler.Run();

foreach (var childId in e.Children<Hierarchy>())
{
Console.WriteLine("child {0}", childId);
}
// var e = ecs.Entity("Main")
// .Set<Position>(new Position() {X = 2})
// .Set<Velocity>(new Velocity());

e.Delete();
var exists = e.Exists();

ecs.Entity()
.Set<Position>(new Position())
.Set<Velocity>(new Velocity());

for (int i = 0; i < ENTITIES_COUNT / 1; i++)
ecs.Entity()
Expand All @@ -104,17 +69,16 @@
// .Set<Likes>()
;

for (var i = 7000; i < 8000 * 2; ++i)
ecs.Entity((ulong)i).Delete();
// for (var i = 7000; i < 8000 * 2; ++i)
// ecs.Entity((ulong)i).Delete();


var sw = Stopwatch.StartNew();
var start = 0f;
var last = 0f;


while (true)
{
//var cur = (start - last) / 1000f;
for (int i = 0; i < 3600; ++i)
{
// ecs.Query<(Position, Velocity)>()
Expand All @@ -123,10 +87,14 @@
// pos.Y *= vel.Y;
// });

ecs.Each((ref Position pos, ref Velocity vel) => {
pos.X *= vel.X;
pos.Y *= vel.Y;
});
// ecs.Each((ref Position pos, ref Velocity vel) => {
// pos.X *= vel.X;
// pos.Y *= vel.Y;
// });

//ecs.Exec(fn);

scheduler.Run();
}

last = start;
Expand Down Expand Up @@ -167,25 +135,14 @@ struct Chunk;
struct ChunkTile;


sealed class MoveSystem : EcsSystem
class Systemmsss
{
private Query? _query;

public override void OnCreate(World ecs)
{
_query = ecs.Query<(Position, Velocity)>();
Console.WriteLine("system {0} created", Name);
}

public override void OnStart(World ecs)
void systemMove(Query<(Position, Velocity), (Not<PlayerTag>, Not<Likes>)> q)
{
Console.WriteLine("system {0} started", Name);
}

public override void OnUpdate(World ecs)
{
_query!.Each((ref Position pos, ref Velocity vel) => {
Console.WriteLine("aa");
q.Each((ref Position pos, ref Velocity vel) => {
pos.X *= vel.X;
pos.Y *= vel.Y;
});
}

}
2 changes: 1 addition & 1 deletion src/Commands.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace TinyEcs;

public sealed class Commands
public sealed class Commands : ISystemParam
{
private readonly World _main;
private readonly EntitySparseSet<EcsID> _despawn;
Expand Down
96 changes: 96 additions & 0 deletions src/DotnetAddons.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,100 @@
#if !NET7_0_OR_GREATER
namespace TinyEcs
{
public readonly ref struct Ref<T>
{
//
// Summary:
// The 1-length System.Span`1 instance used to track the target T value.
internal readonly Span<T> Span;

//
// Summary:
// Gets the T reference represented by the current CommunityToolkit.HighPerformance.Ref`1
// instance.
public ref T Value
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return ref MemoryMarshal.GetReference(Span);
}
}

//
// Summary:
// Initializes a new instance of the CommunityToolkit.HighPerformance.Ref`1 struct.
//
//
// Parameters:
// value:
// The reference to the target T value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Ref(ref T value)
{
Span = MemoryMarshal.CreateSpan(ref value, 1);
}

//
// Summary:
// Initializes a new instance of the CommunityToolkit.HighPerformance.Ref`1 struct.
//
//
// Parameters:
// pointer:
// The pointer to the target value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public unsafe Ref(void* pointer)
: this(ref Unsafe.AsRef<T>(pointer))
{
}

//
// Summary:
// Implicitly gets the T value from a given CommunityToolkit.HighPerformance.Ref`1
// instance.
//
// Parameters:
// reference:
// The input CommunityToolkit.HighPerformance.Ref`1 instance.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator T(Ref<T> reference)
{
return reference.Value;
}
}
}
#endif


#if !NET5_0_OR_GREATER
namespace System.Diagnostics.CodeAnalysis
{
/// <summary>
/// Used to indicate a byref escapes and is not scoped.
/// </summary>
/// <remarks>
/// There are several cases where the C# compiler treats a <see langword="ref"/> as implicitly
/// <see langword="scoped"/> - where the compiler does not allow the <see langword="ref"/> to escape the method.
/// <br/>
/// For example:
/// <list type="number">
/// <item><see langword="this"/> for <see langword="struct"/> instance methods.</item>
/// <item><see langword="ref"/> parameters that refer to <see langword="ref"/> <see langword="struct"/> types.</item>
/// <item><see langword="out"/> parameters.</item>
/// </list>
/// This attribute is used in those instances where the <see langword="ref"/> should be allowed to escape.
/// </remarks>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public sealed class UnscopedRefAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="UnscopedRefAttribute"/> class.
/// </summary>
public UnscopedRefAttribute() { }
}
}

namespace System.Runtime.CompilerServices
{
/// <summary>
Expand Down
Loading

0 comments on commit e51e6ba

Please sign in to comment.