Skip to content

Instantly share code, notes, and snippets.

@enue
Last active May 24, 2019 09:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enue/f1a044386c9ffef0a239bd306a55fb31 to your computer and use it in GitHub Desktop.
Save enue/f1a044386c9ffef0a239bd306a55fb31 to your computer and use it in GitHub Desktop.
for Unity2018.4.0f1
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TSKT
{
public class UnlimitedArray2<T>
{
T[,] array;
public Vector2Int Min { get; private set; }
public Vector2Int Size { get; private set; }
public int Width => Size.x;
public int Height => Size.y;
public int MinX => Min.x;
public int MinY => Min.y;
public int MaxX => Size.x + Min.x - 1;
public int MaxY => Size.y + Min.y - 1;
public UnlimitedArray2(int width, int height)
: this(0, 0, width, height)
{
}
public UnlimitedArray2(int minX, int minY, int width, int height)
{
array = new T[width, height];
Min = new Vector2Int(minX, minY);
Size = new Vector2Int(width, height);
}
public T this[int x, int y]
{
get
{
if (!Contains(x, y))
{
return default;
}
return array[x - Min.x, y - Min.y];
}
set
{
EnsureCapacity(x, y);
array[x - Min.x, y - Min.y] = value;
}
}
public bool Contains(int x, int y)
{
return x >= MinX
&& y >= MinY
&& x <= MaxX
&& y <= MaxY;
}
void EnsureCapacity(int x, int y)
{
EnsureCapacity(new RectInt(x, y, 0, 0));
}
void EnsureCapacity(RectInt rect)
{
var oldMin = Min;
var shouldReplace = false;
if (Min.x > rect.xMin)
{
Size = new Vector2Int(MaxX - rect.xMin + 1, Height);
Min = new Vector2Int(rect.xMin, Min.y);
shouldReplace = true;
}
if (MaxX < rect.xMax)
{
Size = new Vector2Int(rect.xMax - Min.x + 1, Height);
shouldReplace = true;
}
if (Min.y > rect.yMin)
{
Size = new Vector2Int(Width, MaxY - rect.yMin + 1);
Min = new Vector2Int(Min.x, rect.yMin);
shouldReplace = true;
}
if (MaxY < rect.yMax)
{
Size = new Vector2Int(Width, rect.yMax - Min.y + 1);
shouldReplace = true;
}
if (shouldReplace)
{
var oldArray = array;
array = new T[Width, Height];
Copy(oldMin, oldArray, Min, array);
}
}
static void Copy(Vector2Int srcMin, T[,] src, Vector2Int destMin, T[,] dest)
{
for (int i = 0; i < src.GetLength(0); ++i)
{
for (int j = 0; j < src.GetLength(1); ++j)
{
var v = src[i, j];
dest[i + srcMin.x - destMin.x, j + srcMin.y - destMin.y] = v;
}
}
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
namespace TSKT.Tests
{
public class UnlimitedArray2
{
[Test]
public void Test()
{
var container = new UnlimitedArray2<int>(-1, -1, 10, 10);
Assert.True(container.Contains(0, 0));
Assert.False(container.Contains(10, 0));
container[10, 0] = 42;
Assert.True(container.Contains(10, 0));
Assert.AreEqual(42, container[10, 0]);
container[-2, -5] = 97;
Assert.AreEqual(97, container[-2, -5]);
Assert.AreEqual(42, container[10, 0]);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment