// Magica Cloth. // Copyright (c) MagicaSoft, 2020-2022. // https://magicasoft.jp using System; using System.Collections.Generic; using Unity.Collections; namespace MagicaCloth { /// /// NativeHashMapの機能拡張版 /// /// /// public class ExNativeHashMap where TKey : struct, IEquatable where TValue : struct { NativeHashMap nativeHashMap; /// /// ネイティブリストの配列数 /// ※ジョブでエラーが出ないように事前に確保しておく /// int nativeLength; /// /// 使用キーの記録 /// HashSet useKeySet = new HashSet(); //========================================================================================= public ExNativeHashMap() { nativeHashMap = new NativeHashMap(1, Allocator.Persistent); nativeLength = NativeCount; } public void Dispose() { if (nativeHashMap.IsCreated) { nativeHashMap.Dispose(); } } private int NativeCount { get { return nativeHashMap.Count(); } } //========================================================================================= /// /// データ追加 /// /// /// public void Add(TKey key, TValue value) { if (nativeHashMap.TryAdd(key, value) == false) { // すでにデータが存在するため一旦削除して再追加 nativeHashMap.Remove(key); nativeHashMap.TryAdd(key, value); } useKeySet.Add(key); nativeLength = NativeCount; } /// /// データ取得 /// /// /// public TValue Get(TKey key) { TValue data; nativeHashMap.TryGetValue(key, out data); return data; } /// /// 条件判定削除 /// /// trueを返せば削除 public void Remove(Func func) { List removeKey = new List(); foreach (TKey key in useKeySet) { TValue data; if (nativeHashMap.TryGetValue(key, out data)) { // 削除判定 if (func(key, data)) { // 削除 nativeHashMap.Remove(key); removeKey.Add(key); } } } foreach (var key in removeKey) useKeySet.Remove(key); nativeLength = NativeCount; } /// /// データ置き換え /// /// trueを返せば置換 /// 引数にデータを受け取り、修正したデータを返し置換する public void Replace(Func func, Func datafunc) { foreach (var key in useKeySet) { TValue data; if (nativeHashMap.TryGetValue(key, out data)) { // 置換判定 if (func(key, data)) { // 置き換え var newdata = datafunc(data); nativeHashMap.Remove(key); // 一旦削除しないと置き換えられない nativeHashMap.TryAdd(key, newdata); return; } } } } /// /// キーの削除 /// /// public void Remove(TKey key) { nativeHashMap.Remove(key); nativeLength = 0; useKeySet.Remove(key); } /// /// 実際に利用されている要素数を返す /// public int Count { get { return nativeLength; } } public void Clear() { nativeHashMap.Clear(); nativeLength = 0; useKeySet.Clear(); } /// /// 内部のNativeHashMapを取得する /// /// public NativeHashMap Map { get { return nativeHashMap; } } /// /// 使用キーセットを取得する /// public HashSet UseKeySet { get { return useKeySet; } } } }