Skip to content

Commit

Permalink
Merge pull request #34 from sondirn/main
Browse files Browse the repository at this point in the history
  • Loading branch information
IrishBruse authored Oct 9, 2024
2 parents 01671d6 + c118bfa commit 0ddf8aa
Show file tree
Hide file tree
Showing 13 changed files with 300 additions and 44 deletions.
12 changes: 12 additions & 0 deletions LDtk.Codegen/Generators/BaseGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ public void EndBlock()
Line("}");
}

public void EndBlockSeparator()
{
indent--;
Line("},");
}

public void EndCodeBlock()
{
indent--;
Line("};");
}

public static string Call(string functionName, string contents)
{
return $"{functionName}({contents})";
Expand Down
218 changes: 184 additions & 34 deletions LDtk.Codegen/Generators/ClassGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,72 +1,222 @@
namespace LDtk.Codegen.Generators;

using LDtk.Codegen;
using LDtk.Full;
using System.Globalization;
using System.Linq;
using System.Text.Json;

using Full;

public class ClassGenerator(LDtkFileFull ldtkFile, Options options) : BaseGenerator(ldtkFile, options)
{
public void Generate()
{
// Level Classes
GenClass(Options.LevelClassName, LDtkFile.Defs.LevelFields, string.Empty, false);
GenClass(Options.LevelClassName, string.Empty, fieldDefinitions: LDtkFile.Defs.LevelFields);

// Entity Classes
foreach (EntityDefinition e in LDtkFile.Defs.Entities)
{
GenClass(e.Identifier, e.FieldDefs, "Entities", true);
GenClass(e.Identifier, "Entities", e);
}
}

void GenClass(string identifier, FieldDefinition[] fields, string folder, bool isEntity)
void GenClass(string identifier, string folder, EntityDefinition entityDefinition = null,
FieldDefinition[] fieldDefinitions = null)
{
Line($"namespace {Options.Namespace};");
Blank();
Line("// This file was automatically generated, any modifications will be lost!");
Line("#pragma warning disable");
Blank();
Line("using LDtk;");
Line("using Microsoft.Xna.Framework;");
Blank();
GenHeaders();

string classDef = $"public partial class {identifier}";

if (isEntity && Options.EntityInterface)
if (entityDefinition != null && Options.EntityInterface)
{
classDef += " : ILDtkEntity";
}

Line(classDef);

StartBlock();
{
if (entityDefinition != null)
{
GenEntityFields(identifier, entityDefinition);
}
else if (fieldDefinitions != null)
{
GenFieldDefs(fieldDefinitions);
}
}
EndBlock();

Line("#pragma warning restore");
Output(folder, identifier);
}

void GenEntityFields(string identifier, EntityDefinition entityDefinition)
{
//generate the default data for fields.
Line($"public static {identifier} Default() => new()");
StartBlock();
{
if (isEntity)
Line($"Identifier = \"{identifier}\",");
Line($"Uid = {entityDefinition.Uid},");
Line($"Size = new Vector2({entityDefinition.Width}f, {entityDefinition.Height}f),");
Line($"Pivot = new Vector2({entityDefinition.PivotX}f, {entityDefinition.PivotY}f),");
if (entityDefinition.TileRect != null)
{
GenTilesetRectangle("Tile", entityDefinition.TileRect);
}

byte r = entityDefinition.Color.R;
byte g = entityDefinition.Color.G;
byte b = entityDefinition.Color.B;
byte a = entityDefinition.Color.A;

Line($"SmartColor = new Color({r}, {g}, {b}, {a}),");

//generate default data for custom fields
GenCustomFieldDefData(entityDefinition.FieldDefs);
}
EndCodeBlock();
Blank();

//generate the rest of the class
Line("public string Identifier { get; set; }");
Line("public System.Guid Iid { get; set; }");
Line("public int Uid { get; set; }");
Line("public Vector2 Position { get; set; }");
Line("public Vector2 Size { get; set; }");
Line("public Vector2 Pivot { get; set; }");
Line("public Rectangle Tile { get; set; }");
Blank();
Line("public Color SmartColor { get; set; }");

FieldDefinition[] fields = entityDefinition.FieldDefs;
GenFieldDefs(fields);
}

void GenFieldDefs(FieldDefinition[] fields)
{
if (fields.Length > 0)
{
Blank();
}

foreach (FieldDefinition value in fields)
{
string type = Converter.ConvertFieldDefinitionTypes(value._Type, Options.PointAsVector2);

if (value.CanBeNull)
{
type += "?";
}

Line($"public {type} {value.Identifier} {{ get; set; }}");
}
}

void GenCustomFieldDefData(FieldDefinition[] fieldDefs)
{
if (fieldDefs.Length > 0)
{
Blank();
}

foreach (FieldDefinition field in fieldDefs)
{
if (field.DefaultOverride == null)
{
Line("public string Identifier { get; set; }");
Line("public System.Guid Iid { get; set; }");
Line("public int Uid { get; set; }");
Line("public Vector2 Position { get; set; }");
Line("public Vector2 Size { get; set; }");
Line("public Vector2 Pivot { get; set; }");
Line("public Rectangle Tile { get; set; }");
Blank();
Line("public Color SmartColor { get; set; }");
Blank();
continue;
}

foreach (FieldDefinition value in fields)
if (field.DefaultOverride.Params.ValueKind != JsonValueKind.Array)
{
string type = Converter.ConvertFieldDefinitionTypes(value._Type, Options.PointAsVector2);
continue;
}

JsonElement defaultValue = field.DefaultOverride.Params.EnumerateArray().First();

if (field._Type.Contains("Enum"))
{
string enumName = field._Type.Replace("LocalEnum.", "");
string value = defaultValue.GetString();
string enumValue = $"{enumName}.{value}";

Line($"entity.{field.Identifier} = {enumValue};");
}

switch (field._Type)
{
case Field.IntType:
Line($"{field.Identifier} = {defaultValue.GetInt32()},");
break;

case Field.FloatType:
Line($"{field.Identifier} = {defaultValue.GetSingle().ToString(CultureInfo.InvariantCulture)}f,");
break;

case Field.BoolType:
Line($"{field.Identifier} = {defaultValue.GetBoolean().ToString().ToLower()},");
break;

if (value.CanBeNull)
case Field.StringType:
Line($"{field.Identifier} = {defaultValue.GetRawText()},");
break;

case Field.FilePathType:
Line($"{field.Identifier} = {defaultValue.GetString()},");
break;

case Field.TileType:
string[] rectValues = defaultValue.GetString()!.Split(',');
int x = int.Parse(rectValues[0]);
int y = int.Parse(rectValues[1]);
int width = int.Parse(rectValues[2]);
int height = int.Parse(rectValues[3]);
int tilesetUid = (int)field.TilesetUid!;
TilesetRectangle finalRect = new()
{
type += "?";
}
X = x,
Y = y,
W = width,
H = height,
TilesetUid = tilesetUid
};
GenTilesetRectangle(field.Identifier, finalRect);
break;

Line($"public {type} {value.Identifier} {{ get; set; }}");
case Field.ColorType:
int colorValue = defaultValue.GetInt32();
int r = (colorValue >> 16) & 0xFF;
int g = (colorValue >> 8) & 0xFF;
int b = colorValue & 0xFF;
Line($"{field.Identifier} = new Color({r}, {g}, {b}, {1}),");
break;
}
}
EndBlock();
Line("#pragma warning restore");
}

Output(folder, identifier);
void GenHeaders()
{
Line($"namespace {Options.Namespace};");
Blank();
Line("// This file was automatically generated, any modifications will be lost!");
Line("#pragma warning disable");
Blank();
Line("using LDtk;");
Line("using Microsoft.Xna.Framework;");
Blank();
}

void GenTilesetRectangle(string identifier, TilesetRectangle rect)
{
Line($"{identifier} = new TilesetRectangle()");
StartBlock();
{
Line($"X = {rect.X},");
Line($"Y = {rect.Y},");
Line($"W = {rect.W},");
Line($"H = {rect.H}");
}
EndBlockSeparator();
}
}
9 changes: 9 additions & 0 deletions LDtk.Example/Entry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,15 @@ protected override void Initialize()
_ = renderer.PrerenderLevel(world.Levels[i]);
}

// Default value instance example
var prefab = Enemy.Default();
prefab.Wander = new Vector2[] { Vector2.One * 180, Vector2.One * 120 };
enemies.Add(new EnemyEntity(prefab, spriteSheet, renderer));

var prefab2 = Enemy.Default();
prefab2.Wander = new Vector2[] { Vector2.One * 200, Vector2.One * 100 };
enemies.Add(new EnemyEntity(prefab2, spriteSheet, renderer));

Gun_Pickup gunData = world.GetEntity<Gun_Pickup>();
gun = new GunEntity(gunData, spriteSheet, renderer);

Expand Down
2 changes: 1 addition & 1 deletion LDtk.Example/LDtkTypes/World/CustomLevelDataName.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ namespace LDtkTypes;
#pragma warning disable

using LDtk;

using Microsoft.Xna.Framework;

public partial class CustomLevelDataName
{

public float Float { get; set; }
public TilesetRectangle[] Tile { get; set; }
public string? Multilines { get; set; }
Expand Down
19 changes: 18 additions & 1 deletion LDtk.Example/LDtkTypes/World/Entities/Enemy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@ namespace LDtkTypes;
#pragma warning disable

using LDtk;

using Microsoft.Xna.Framework;

public partial class Enemy : ILDtkEntity
{
public static Enemy Default() => new()
{
Identifier = "Enemy",
Uid = 98,
Size = new Vector2(16f, 16f),
Pivot = new Vector2(0.5f, 0.5f),
Tile = new TilesetRectangle()
{
X = 16,
Y = 16,
W = 16,
H = 16
},
SmartColor = new Color(255, 107, 25, 255),

Color = new Color(166, 80, 80, 1),
};

public string Identifier { get; set; }
public System.Guid Iid { get; set; }
public int Uid { get; set; }
Expand Down
18 changes: 16 additions & 2 deletions LDtk.Example/LDtkTypes/World/Entities/Gun_Pickup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,26 @@ namespace LDtkTypes;
#pragma warning disable

using LDtk;

using Microsoft.Xna.Framework;

public partial class Gun_Pickup : ILDtkEntity
{
public static Gun_Pickup Default() => new()
{
Identifier = "Gun_Pickup",
Uid = 107,
Size = new Vector2(16f, 16f),
Pivot = new Vector2(0.5f, 1f),
Tile = new TilesetRectangle()
{
X = 0,
Y = 16,
W = 16,
H = 16
},
SmartColor = new Color(75, 224, 96, 255),
};

public string Identifier { get; set; }
public System.Guid Iid { get; set; }
public int Uid { get; set; }
Expand All @@ -18,6 +33,5 @@ public partial class Gun_Pickup : ILDtkEntity
public Rectangle Tile { get; set; }

public Color SmartColor { get; set; }

}
#pragma warning restore
Loading

0 comments on commit 0ddf8aa

Please sign in to comment.