Skip to content

Commit

Permalink
A proof of concept for source generation
Browse files Browse the repository at this point in the history
  • Loading branch information
thygrrr committed Nov 14, 2024
1 parent 5b8900d commit 30f2e3a
Show file tree
Hide file tree
Showing 4 changed files with 395 additions and 16 deletions.
156 changes: 156 additions & 0 deletions fennecs.tests/Conceptual/SourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
using System.Text;

namespace fennecs.tests.Conceptual;

public class SourceGeneratorExperiment(ITestOutputHelper output)
{

private static string EntityUniform(bool entity, bool uniform)
{
return $"{(uniform ? "U uniform, " : "")}{(entity ? "Entity" : "")}";
}

private static string ActionParams(int width, bool entity, bool uniform, string pattern)
{
var typeParams = new StringBuilder();

//language=C#
if (entity) typeParams.Append($"EntityRef, ");

//language=C#
if (uniform) typeParams.Append($"U, ");

//language=C#
for (var i = 0; i < width; i++)
{
var rw = pattern[i] == 'W' ? "RW" : "R";
typeParams.Append($"{rw}<C{i}>");
if (i < width - 1) typeParams.Append(", ");
}
return typeParams.ToString();
}

private static string TypeParams(int width)
{
var typeParams = new StringBuilder();

//language=C#
for (var i = 0; i < width; i++)
{
typeParams.Append($"C{i}");
if (i < width - 1) typeParams.Append(", ");
}
return typeParams.ToString();
}

private static string Select(int width)
{
var select = new StringBuilder();
if (width > 1) select.Append("(");
//language=C#
for (var i = 0; i < width; i++)
{
select.Append($"s{i}");
if (i < width - 1) select.Append(", ");
}
if (width > 1) select.Append(")");
return select.ToString();
}

private static string Deconstruct(int width, string pattern)
{
var deconstruct = new StringBuilder();
//language=C#
for (var i = 0; i < width; i++)
{
deconstruct.Append($"var span{i} = s{i}.Span; ");
if (pattern[i] == 'W') deconstruct.Append($"var type{i} = s{i}.Expression; ");
}
return deconstruct.ToString();
}

private static string LoadEntity(bool entity)
{
//language=C#
return entity ? "\n var entity = table[i];" : "";
}

private static string Parameters(bool entity, bool uniform, string pattern)
{
var parameters = new StringBuilder();

//language=C#
if (entity) parameters.Append("new(in entity), ");

//language=C#
if (uniform) parameters.Append("uniform, ");

var index = 0;
foreach (var p in pattern)
{
if (index != 0) parameters.Append(", ");
parameters.Append(
//language=C#
p switch
{
'W' => $"new(ref span{index}[i], in entity, in type{index})",
'R' => $"new(ref span{index}[i])",
_ => throw new NotImplementedException(),
}
);
index++;
}
return parameters.ToString();
}

private string GenerateFor(bool entity, bool uniform, int width, int bits)
{
var pattern = $"{bits:b16}"[(16 - width)..16].Replace("0", "W").Replace("1", "R");

//output.WriteLine($"{bits:3}:{bits:b16}:{entityRW}");

//language=C#
var code = $$"""
/// <include file='XMLdoc.xml' path='members/member[@name="T:For"]'/>
[OverloadResolutionPriority(0b_{{(entity ? 1 : 0)}}_{{bits:b8}})]
public void For{{(uniform ? "<U>(U uniform, " : "(")}}Action<{{ActionParams(width, entity, uniform, pattern)}}> action)
{
using var worldLock = World.Lock();

foreach (var table in Filtered)
{
var count = table.Count;
using var join = table.CrossJoin<{{TypeParams(width)}}>(_streamTypes.AsSpan());
if (join.Empty) continue;
do
{
var {{Select(width)}} = join.Select;
{{Deconstruct(width, pattern)}}
for (var i = 0; i < count; i++)
{ {{LoadEntity(entity)}}
action({{Parameters(entity, uniform, pattern)}});
}
} while (join.Iterate());
}
}


""";

return code;
}


[Theory]
[InlineData(3)]
private void TestFor(int width)
{
var top = (1 << width) - 1;
for (var bits = top; bits >= 0; bits--)
{
output.WriteLine(GenerateFor(true, true, width, bits));
}
//return code;
}

}
48 changes: 32 additions & 16 deletions fennecs/Delegates.3.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,48 @@ namespace fennecs;

#region For/Job: Component Actions

public delegate void ComponentActionWWW<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionWWR<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionWRW<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionWRR<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionRWW<C0, C1, C2>(R<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionRWR<C0, C1, C2>(R<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionRRW<C0, C1, C2>(R<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ComponentActionRRR<C0, C1, C2>(R<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionWWW<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionWWR<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionWRW<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionWRR<C0, C1, C2>(RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionRWW<C0, C1, C2>(R<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionRWR<C0, C1, C2>(R<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionRRW<C0, C1, C2>(R<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionRRR<C0, C1, C2>(R<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;

#endregion


#region For/Job: Entity Component Actions

public delegate void EntityComponentActionWWW<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionWWR<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionWRW<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionWRR<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionRWW<C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionRWR<C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionRRW<C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void EntityComponentActionRRR<C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEWWW<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEWWR<C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEWRW<C0, C1, C2>(EntityRef entity, RW<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEWRR<C0, C1, C2>(EntityRef entity, RW<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionERWW<C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionERWR<C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionERRW<C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionERRR<C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;

#endregion



#region For/Job: Entity Component Actions

public delegate void ActionEUWWW<in U, C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEUWWR<in U, C0, C1, C2>(EntityRef entity, RW<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEUWRW<in U, C0, C1, C2>(EntityRef entity, RW<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEUWRR<in U, C0, C1, C2>(EntityRef entity, RW<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEURWW<in U, C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEURWR<in U, C0, C1, C2>(EntityRef entity, R<C0> comp0, RW<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEURRW<in U, C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, RW<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
public delegate void ActionEURRR<in U, C0, C1, C2>(EntityRef entity, R<C0> comp0, R<C1> comp1, R<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;

#endregion



#region Raw: Memory Actions

public delegate void MemoryActionWWW<C0, C1, C2>(Memory<C0> comp0, Memory<C1> comp1, Memory<C2> comp2) where C0 : notnull where C1 : notnull where C2 : notnull;
Expand Down
Loading

0 comments on commit 30f2e3a

Please sign in to comment.