2025-07-30 07:30:00 +07:00
|
|
|
using System.Buffers;
|
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
using StitchATon2.Infra;
|
|
|
|
|
using StitchATon2.Infra.Buffers;
|
|
|
|
|
|
|
|
|
|
namespace StitchATon2.Domain;
|
|
|
|
|
|
2025-08-01 09:51:39 +07:00
|
|
|
public sealed class TileManager
|
2025-07-30 07:30:00 +07:00
|
|
|
{
|
2025-08-01 09:51:39 +07:00
|
|
|
private readonly Tile[] _tiles;
|
2025-07-30 07:30:00 +07:00
|
|
|
|
|
|
|
|
public Configuration Configuration { get; }
|
|
|
|
|
|
|
|
|
|
public TileManager(Configuration config)
|
|
|
|
|
{
|
|
|
|
|
Configuration = config;
|
2025-08-01 09:51:39 +07:00
|
|
|
_tiles = new Tile[Configuration.TileCount];
|
2025-07-30 07:30:00 +07:00
|
|
|
for (var id = 0; id < config.TileCount; id++)
|
2025-08-01 09:51:39 +07:00
|
|
|
_tiles[id] = CreateTile(id);
|
2025-07-30 07:30:00 +07:00
|
|
|
|
|
|
|
|
Console.WriteLine("Tile manager created");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Tile CreateTile(int id)
|
|
|
|
|
{
|
|
|
|
|
var (row, column) = int.DivRem(id, Configuration.Columns);
|
2025-08-01 22:13:13 +07:00
|
|
|
var coordinate = $"{Utils.GetSbsNotationRow(++row)}{++column}";
|
2025-07-30 07:30:00 +07:00
|
|
|
return new Tile
|
|
|
|
|
{
|
|
|
|
|
Id = id,
|
|
|
|
|
Row = row,
|
|
|
|
|
Column = column,
|
|
|
|
|
Coordinate = coordinate,
|
|
|
|
|
Integral = new ImageIntegral(
|
|
|
|
|
imagePath: Configuration.GetAssetPath($"{coordinate}.png"),
|
|
|
|
|
outputDirectory: Configuration.CachePath,
|
|
|
|
|
width: Configuration.Width,
|
|
|
|
|
height: Configuration.Height
|
|
|
|
|
),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
private int GetId(int column, int row) => column - 1 + (row - 1) * Configuration.Columns;
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
2025-08-01 09:51:39 +07:00
|
|
|
public Tile GetTile(int id) => _tiles[id];
|
2025-07-30 07:30:00 +07:00
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public Tile GetTile(int column, int row) => GetTile(GetId(column, row));
|
|
|
|
|
|
|
|
|
|
public Tile GetTile(string coordinate)
|
|
|
|
|
{
|
2025-08-01 22:13:13 +07:00
|
|
|
var (column, row) = Utils.GetSbsNotationCoordinate(coordinate);
|
2025-07-30 07:30:00 +07:00
|
|
|
return GetTile(column, row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Tile? TryGetAdjacent(Tile tile, int columnOffset, int rowOffset)
|
|
|
|
|
{
|
|
|
|
|
var column = tile.Column + columnOffset;
|
|
|
|
|
if(column <= 0 || column > Configuration.Columns)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var row = tile.Row + rowOffset;
|
|
|
|
|
if(row <= 0 || row > Configuration.Rows)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return GetTile(column, row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public (Tile TopLeft, Tile BottomRight) GetTilePair(string coordinatePair)
|
|
|
|
|
{
|
|
|
|
|
var index = coordinatePair.IndexOf(':');
|
|
|
|
|
var topLeft = GetTile(coordinatePair[..index++]);
|
|
|
|
|
var bottomRight = GetTile(coordinatePair[index..]);
|
|
|
|
|
|
|
|
|
|
return (topLeft, bottomRight);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
|
|
public Tile GetAdjacent(Tile tile, int columnOffset, int rowOffset)
|
|
|
|
|
{
|
|
|
|
|
return GetTile(tile.Column + columnOffset, tile.Row + rowOffset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public GridSection CreateSection(
|
|
|
|
|
string coordinatePair,
|
|
|
|
|
float cropX,
|
|
|
|
|
float cropY,
|
|
|
|
|
float cropWidth,
|
|
|
|
|
float cropHeight)
|
|
|
|
|
=> new(
|
|
|
|
|
this,
|
|
|
|
|
coordinatePair,
|
|
|
|
|
cropX,
|
|
|
|
|
cropY,
|
|
|
|
|
cropWidth,
|
|
|
|
|
cropHeight);
|
|
|
|
|
}
|