Last active
August 5, 2021 13:04
-
-
Save choeehb/b9ce9677bff1e6c1aec466e779dc53b1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Sirenix.OdinInspector; | |
using Sirenix.Utilities; | |
using UnityEngine; | |
namespace Common | |
{ | |
public abstract class DictionaryTable<TId, TValue> where TId : IComparable | |
{ | |
protected abstract TId GetId(TValue value); | |
private bool dirty; | |
private List<TValue> list = new List<TValue>(); | |
public TValue FindById(TId id) | |
{ | |
SortIfDirty(); | |
var index = BinarySearch(id); | |
return list[index]; | |
} | |
public IReadOnlyCollection<TValue> FindAll() | |
{ | |
SortIfDirty(); | |
return list; | |
} | |
private void SortIfDirty() | |
{ | |
if (dirty) | |
list.Sort(CompareValue); | |
dirty = false; | |
} | |
private int CompareValue(TValue value1, TValue value2) | |
{ | |
var id1 = GetId(value1); | |
var id2 = GetId(value2); | |
return id1.CompareTo(id2); | |
} | |
// return index | |
private int BinarySearch(TId id) | |
{ | |
int search(int left, int right) | |
{ | |
if (right < left) | |
return -1; | |
int mid = (left + right) / 2; | |
var target = list[mid]; | |
var targetId = GetId(target); | |
var compared = id.CompareTo(targetId); | |
if (compared == -1) | |
return search(left, mid - 1); | |
if (compared == 1) | |
return search(mid + 1, right); | |
return mid; | |
} | |
if (list.Count == 0) | |
return -1; | |
return search(0, list.Count); | |
} | |
protected void Add(TValue value) | |
{ | |
list.Add(value); | |
dirty = true; | |
} | |
protected void AddAll(IEnumerable<TValue> list) | |
{ | |
list.ForEach(Add); | |
} | |
} | |
//-------------------------------------------------------- | |
public struct MySheet | |
{ | |
public int Id; | |
public string Value; | |
} | |
public class MyTable : DictionaryTable<int, MySheet> | |
{ | |
protected override int GetId(MySheet value) => value.Id; | |
public MyTable() | |
{ | |
Add(new MySheet { Id = 4, Value = "4" }); | |
Add(new MySheet { Id = 1, Value = "1" }); | |
Add(new MySheet { Id = 5, Value = "5" }); | |
Add(new MySheet { Id = 3, Value = "3" }); | |
Add(new MySheet { Id = 2, Value = "2" }); | |
} | |
} | |
public class TestTest | |
{ | |
[TestCase(1, "1")] | |
[TestCase(2, "2")] | |
[TestCase(3, "3")] | |
[TestCase(4, "4")] | |
[TestCase(5, "5")] | |
public void Test_FindById(int id, string expected) | |
{ | |
var table = new MyTable(); | |
var value = table.FindById(id).Value; | |
Assert.AreEqual(expected, value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment