// 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;
}
}
}
}