うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【C#】グローバルに数値を管理する

モックを作ってる際にわざわざ値を管理するクラスを複数作るのが面倒だったので、
enum を指定 して手軽に利用できるクラスを作成しました

使い方

enum を定義してこれを Key に利用する

public enum ValueType
{
    Score,
    Life,
}

値の初期化

Value<ValueType>.Set(ValueType.Score, 0);
Value<ValueType>.Set(ValueType.Life, 10);

変更の監視

Value<ValueType>.AddListener(ValueType.Score, UpdateScore);

private void UpdateScore(int value, int diff)
{

}

値の変更

// スコアを 1増やす
Value<ValueType>.Add(ValueType.Score, 1);

値の取得

var score = Value<ValueType>.Get(ValueType.Score);

値の削除&イベントの解除

// 指定したKey の値を削除 & イベントの解除
Value<ValueType>.Clear(ValueType.Score);
 
// 全Key の値を削除 & イベントの解除
Value<ValueType>.Clear();

コード

using System;
using System.Collections.Generic;

public static class Value<T> where T : Enum
{
    private static readonly Dictionary<int, int> _dictionary;
    private static readonly Dictionary<int, Action<int, int>> _actionDictionary;
 
    static Value()
    {
        _dictionary = new Dictionary<int, int>();
        _actionDictionary = new Dictionary<int, Action<int, int>>();
    }
 
    public static int Get(T t)
    {
        var key = t.GetHashCode();
        return _dictionary.TryGetValue(key, out var v) ? v : 0;
    }
 
    public static int Add(T t, int value, int max = int.MaxValue)
    {
        var diff = 0;
        var key = t.GetHashCode();
        if (_dictionary.TryGetValue(key, out var v))
        {
            diff = v + value - _dictionary[key];
            _dictionary[key] = v + value;
        }
        else
        {
            _dictionary.Add(key, value);
        }

        if (_dictionary[key] > max)
            _dictionary[key] = max;

        if (_actionDictionary.TryGetValue(key, out var c))
            c?.Invoke(_dictionary[key], diff);

        return _dictionary[key];
    }
 
    public static void Set(T t, int value = 0, int max = int.MaxValue)
    {
        Add(t, value, max);
    }
 
    public static void AddListener(T t, Action<int, int> action)
    {
        var key = t.GetHashCode();
        if (_actionDictionary.TryGetValue(key, out var a))
        {
            a += action;
            _actionDictionary[key] = a;
        }
        else
        {
            _actionDictionary.Add(key, action);
        }
    }
 
    public static void RemoveListener(T t, Action<int, int> action)
    {
        var key = t.GetHashCode();
        if (!_actionDictionary.TryGetValue(key, out var a))
            return;

        if (a == null)
            return;

        a -= action;
        if (a == null)
            _actionDictionary.Remove(key);
        else
            _actionDictionary[key] = a;
    }
 
    public static void Clear(T t)
    {
        var key = t.GetHashCode();
        if (_dictionary.ContainsKey(key))
            _dictionary.Remove(key);
        if (_actionDictionary.ContainsKey(key))
            _actionDictionary.Remove(key);
    }
 
    public static void Clear()
    {
        _dictionary.Clear();
        _actionDictionary.Clear();
    }
}