Skip to content

Commit

Permalink
finished creating the test and improved some caching with it. the 2 t…
Browse files Browse the repository at this point in the history
…ile components are ensured stable
  • Loading branch information
Cammin committed Apr 29, 2024
1 parent e0c86a9 commit 73f9314
Show file tree
Hide file tree
Showing 3 changed files with 177 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ namespace LDtkUnity
[AddComponentMenu("")]
public sealed class LDtkComponentLayerTilesetTiles : MonoBehaviour
{
//todo this needs more actual data, the TileInstance
//todo this needs more actual data, the TileInstance. A or T values

[SerializeField] private List<Tilemap> _tilemaps = new List<Tilemap>();

private Dictionary<Type, Vector3Int[]> _positionsOfEnumValues;

public IReadOnlyList<Tilemap> Tilemaps => _tilemaps;

internal void OnImport(List<Tilemap> tilemaps)
{
_tilemaps = tilemaps;
Expand All @@ -24,46 +26,68 @@ internal void OnImport(List<Tilemap> tilemaps)
/// Get all Tilemap positions in this layer that use a particular Enum value
/// </summary>
/// <returns></returns>
/// todo we might be able to improve this by caching all coordinates for every tile
/// todo needs a unit test
public List<Vector3Int> GetCoordinatesOfEnumValue<TEnum>(TEnum value) where TEnum : struct
public Vector3Int[] GetCoordinatesOfEnumValue<TEnum>() where TEnum : struct
{
Type type = typeof(TEnum);
if (!type.IsEnum)
{
LDtkDebug.LogError($"Input type {type.Name} is not an enum");
return null;
}

TryCacheCoordsOfType(type);

return _positionsOfEnumValues[type];
}

private void TryCacheCoordsOfType(Type enumType)
{
if (_positionsOfEnumValues == null || !_positionsOfEnumValues.ContainsKey(enumType))
{
CacheCoordsOfType(enumType);
}
}

private void CacheCoordsOfType(Type enumType)
{
List<Vector3Int> positions = new List<Vector3Int>();
Vector3Int coordinate = Vector3Int.zero;

List<Vector3Int> coords = new List<Vector3Int>();
foreach (Tilemap tilemap in _tilemaps)
{
BoundsInt bounds = tilemap.cellBounds;
Vector3Int coord = bounds.min;
for (; coord.x < bounds.xMax; coord.x++)
for (int x = bounds.xMin; x < bounds.xMax; x++)
{
for (; coord.y < bounds.yMax; coord.y++)
coordinate.x = x;
for (int y = bounds.yMin; y < bounds.yMax; y++)
{
LDtkTilesetTile tile = tilemap.GetTile<LDtkTilesetTile>(coord);
if (tile && tile.HasEnumTagValue(value))
coordinate.y = y;

LDtkTilesetTile tile = tilemap.GetTile<LDtkTilesetTile>(coordinate);
if (tile != null && tile.HasEnumTagValue(enumType))
{
coords.Add(coord);
positions.Add(coordinate);
}
}
}
}
return coords;

if (_positionsOfEnumValues == null)
{
_positionsOfEnumValues = new Dictionary<Type, Vector3Int[]>(1);
}

_positionsOfEnumValues[enumType] = positions.ToArray();
}

/// <summary>
/// Get tiles at the coordinate from all tilemaps, even null tiles.
/// Typically there will only be one tile within a coordinate, but there can be multiple if rules had generated it.
/// Typically, there will only be one tile within a coordinate, but there can be multiple if rules had generated it.
/// </summary>
/// todo needs a unit test
public LDtkTilesetTile[] GetTilesetTiles(Vector3Int coord)
{
LDtkTilesetTile[] tiles = new LDtkTilesetTile[_tilemaps.Count];
for (int i = 0; i < tiles.Length; i++)
for (int i = 0; i < _tilemaps.Count; i++)
{
tiles[i] = _tilemaps[i].GetTile<LDtkTilesetTile>(coord);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ public TEnum[] GetEnumTagValues<TEnum>() where TEnum : struct
/// If a tile has an enum tag value
/// </summary>
/// <typeparam name="TEnum">Use an enum type that was generated by the project importer.</typeparam>
/// <returns>The enum values convert</returns>
public bool HasEnumTagValue<TEnum>(TEnum enumValue) where TEnum : struct
public bool HasEnumTagValue<TEnum>() where TEnum : struct
{
Type type = typeof(TEnum);
if (!type.IsEnum)
Expand All @@ -141,5 +140,4 @@ internal bool HasEnumTagValue(Type type)
return _enumTagValues.Any(enumTagValue => Enum.IsDefined(type, enumTagValue));
}
}

}
177 changes: 136 additions & 41 deletions Assets/Tests/EditMode/Tests/ComponentTilesetTilesTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,9 @@ namespace LDtkUnity.Tests
public class ComponentTilesTest
{
[Test]
public void TestExpectedCoordsTileset()
public void EnsureComponentExistences()
{
//const string lvlName = "Level";

string path = "Assets/Samples/Samples/Test_file_for_API_showing_all_features.ldtk";
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);

LDtkComponentProject project = prefab.GetComponent<LDtkComponentProject>();
LDtkComponentProject project = LoadProjectComponent();
LDtkComponentLayer[] layers = project.Worlds[0].Levels[0].LayerInstances;

foreach (LDtkComponentLayer layer in layers)
Expand All @@ -27,7 +22,48 @@ public void TestExpectedCoordsTileset()
Assert.NotNull(intGrid);
Assert.IsNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
if (layer.Identifier == "IntGrid_with_rules")
{
Assert.NotNull(intGrid);
Assert.NotNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
if (layer.Identifier == "PureAutoLayer")
{
Assert.IsNull(intGrid);
Assert.NotNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
if (layer.Identifier == "Tiles")
{
Assert.IsNull(intGrid);
Assert.IsNull(layer.AutoLayerTiles);
Assert.NotNull(layer.GridTiles);
}
if (layer.Identifier == "IntGrid_8px_grid")
{
Assert.NotNull(intGrid);
Assert.IsNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
}
}

[Test]
public void TestIntGridWithoutRules()
{
LDtkComponentProject project = LoadProjectComponent();
LDtkComponentLayer[] layers = project.Worlds[0].Levels[0].LayerInstances;

Assert.True(layers.Any(p => p.Identifier == "IntGrid_without_rules"));

foreach (LDtkComponentLayer layer in layers)
{
LDtkComponentLayerIntGridValues intGrid = layer.IntGrid;

if (layer.Identifier == "IntGrid_without_rules")
{
Vector3Int[] allValidItems1 = new Vector3Int[]
{
new Vector3Int(3,28,0),
Expand Down Expand Up @@ -132,57 +168,101 @@ public void TestExpectedCoordsTileset()
TestIntGridPosition(intGrid, new Vector3Int(5, 26, 0), true, 2, allValidItems2);
TestIntGridPosition(intGrid, new Vector3Int(20, 27, 0), true, 3, allValidItems3);
}
}
}

[Test]
public void TestIntGridWithRules()
{
LDtkComponentProject project = LoadProjectComponent();
LDtkComponentLayer[] layers = project.Worlds[0].Levels[0].LayerInstances;

Assert.True(layers.Any(p => p.Identifier == "IntGrid_with_rules"));

foreach (LDtkComponentLayer layer in layers)
{
LDtkComponentLayerIntGridValues intGrid = layer.IntGrid;

if (layer.Identifier == "IntGrid_with_rules")
{
Assert.NotNull(intGrid);
Assert.NotNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
if (layer.Identifier == "PureAutoLayer")
{
Assert.IsNull(intGrid);
Assert.NotNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
}
if (layer.Identifier == "Tiles")
{
Assert.IsNull(intGrid);
Assert.IsNull(layer.AutoLayerTiles);
Assert.NotNull(layer.GridTiles);
}
if (layer.Identifier == "IntGrid_8px_grid")
{
Assert.NotNull(intGrid);
Assert.IsNull(layer.AutoLayerTiles);
Assert.IsNull(layer.GridTiles);
Vector3Int[] allValidItems = new Vector3Int[]
{
new Vector3Int(11,28,0),
new Vector3Int(11,27,0),
new Vector3Int(11,26,0),
new Vector3Int(11,25,0),
new Vector3Int(11,24,0),
new Vector3Int(11,23,0),

new Vector3Int(12,28,0),
new Vector3Int(12,27,0),
new Vector3Int(12,26,0),
new Vector3Int(12,25,0),
new Vector3Int(12,24,0),
new Vector3Int(12,23,0),

new Vector3Int(13,28,0),
new Vector3Int(13,27,0),
new Vector3Int(13,26,0),
new Vector3Int(13,25,0),
new Vector3Int(13,24,0),
new Vector3Int(13,23,0),

new Vector3Int(14,28,0),
new Vector3Int(14,27,0),
new Vector3Int(14,26,0),
new Vector3Int(14,25,0),
new Vector3Int(14,24,0),
new Vector3Int(14,23,0),

new Vector3Int(15,28,0),
new Vector3Int(15,27,0),
new Vector3Int(15,26,0),
new Vector3Int(15,25,0),
new Vector3Int(15,24,0),
new Vector3Int(15,23,0),

new Vector3Int(16,28,0),
new Vector3Int(16,27,0),
new Vector3Int(16,26,0),
new Vector3Int(16,25,0),
new Vector3Int(16,24,0),
new Vector3Int(16,23,0),
};

TestIntGridPosition(intGrid, new Vector3Int(12,28,0), true, 1, allValidItems);

TestTilesetTilePosition(layer.AutoLayerTiles, new Vector3Int(10,28,0), 0);
TestTilesetTilePosition(layer.AutoLayerTiles, new Vector3Int(11,28,0), 1);
TestTilesetTilePosition(layer.AutoLayerTiles, new Vector3Int(13,28,0), 2);
}
}
}

/*Level level = project.UnityWorlds.First().Levels.FirstOrDefault();
Assert.NotNull(level, "null level");
//LayerInstance layer = level.LayerInstances.FirstOrDefault(p => p.IsIntGridLayer);
//Assert.NotNull(layer);
Rect levelBounds = level.UnityWorldSpaceBounds(WorldLayout.Free, (int)16);
private static LDtkComponentProject LoadProjectComponent()
{
string path = "Assets/Samples/Samples/Test_file_for_API_showing_all_features.ldtk";
GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);

//Debug.Log(levelBounds);*/
LDtkComponentProject project = prefab.GetComponent<LDtkComponentProject>();
return project;
}

private static void TestIntGridPosition(LDtkComponentLayerIntGridValues intGrid, Vector3Int pos, bool assertHas, int assertIs = 0, Vector3Int[] assertAllTilesExist = null)
{
Debug.Log($"TestIntGridPosition {pos}, shouldExist: {assertHas}");

LDtkDefinitionObjectIntGridValue valueObj = intGrid.GetValueDefinition(pos);
int value = intGrid.GetValue(pos);

Debug.Log($"\tExpect value {assertIs}. {assertIs} == {value}");
Assert.AreEqual(assertIs, value);
Debug.Log($"{assertIs} == {value}");

if (assertHas)
{
Assert.NotNull(valueObj);
Assert.AreNotEqual(0, value);
Debug.Log($"{assertIs} != 0");
Debug.Log($"\t{assertIs} != 0");

Vector3Int[] positionsObj = intGrid.GetPositionsOfValueDefinition(valueObj);
Vector3Int[] positions = intGrid.GetPositionsOfValue(value);
Expand All @@ -191,19 +271,34 @@ private static void TestIntGridPosition(LDtkComponentLayerIntGridValues intGrid,
Assert.True(positionsObj.SequenceEqual(positions));

Assert.True(ArraysContainSameValues(positionsObj, assertAllTilesExist));
Debug.Log($"ArraysContainSameValues!");
Debug.Log($"\tArraysContainSameValues!");
}
else
{
Assert.IsNull(valueObj);
Assert.AreEqual(0, value);
Debug.Log($"{value} == 0");
Debug.Log($"\t{value} == 0");
}
}

public static bool ArraysContainSameValues<T>(T[] array1, T[] array2)
{
return array1.Length == array2.Length && array1.All(array2.Contains) && array2.All(array1.Contains);
}

private static void TestTilesetTilePosition(LDtkComponentLayerTilesetTiles tilesComponent, Vector3Int pos, int assertTileCount = 0)
{
Debug.Log($"Test TilesetPosition {pos}");
Vector3Int[] coords = tilesComponent.GetCoordinatesOfEnumValue<SomeEnum>();
Debug.Log($"\tExpecting array empty. {coords.Length}");
Assert.IsEmpty(coords);

LDtkTilesetTile[] tiles = tilesComponent.GetTilesetTiles(pos);

Assert.IsTrue(tiles.Length == tilesComponent.Tilemaps.Count);

int notNullCount = tiles.Count(p => p != null);
Debug.Log($"\tGetTilesetTiles {tiles.Length}, where not-null count is {notNullCount}, expecting {assertTileCount}");
}
}
}

0 comments on commit 73f9314

Please sign in to comment.