Лучшая практика для сохранения связанных констант? - PullRequest
4 голосов
/ 18 февраля 2011

В моей игре есть enum (длиной около 200 записей) с разными GameEntityType s.

Когда игра сохраняется, в файл сохранения записывается только массив GameEntityType.

Для реконструкции игрового мира и отображения различной информации о GameEntityTypes Мне нужно иметь список довольно много дополнительных деталей (постоянные значения). Это означает, что с каждым GameEntityType связаны другие значения. Эти значения доступны очень часто каждый кадр. Моя цель - иметь простой способ получить всю дополнительную информацию из GameEntityTypeID (перечисление). Например, когда я читаю 0x1 из файла сохранения, я могу просто получить доступ к Имени и всем остальным информация, которая подразумевается с числом / перечислением из массива, подобного этому: "Constants.TextureList [GameEntityType]", возвращает строку "Stone_Texture.DDS"

Пример для дополнительной / связанной информации о первой записи перечисления:

Типы: string, строка, Flag-Enum: "Visual-Classification", bool, bool Ценности: "StoneBlock", "Stone_Texture.DDS", 0x0102, false, true

Мой первый подход к этому заключался в создании статического класса GameEntityTypeInfo, который для каждого дополнительного типа информации был член, подобный следующему:

public static const string [] = {"StoneBlock", ... [more entrys]};

Конечно, это ужасное решение, потому что я не могу просто добавить GameEntityType's везде, где я хочу, без необходимости обновлять все остальные списки тоже. Я также должен разделить логические единицы на единицы типа данных (что является проблемой! Потому что, когда я решаю, что мне больше не нужен конкретный тип EntityType, мне нужно пройти более 6 списков!)

Затем я попытался решить эту проблему, создав структуру из этих наборов данных. и добавив их в статический массив. Но создание списка с дополнительной информацией во время конструктора (пока игра запускается) все еще не кажется лучшим решением.

Вопрос: Как создать быстрый (поиск по названию / классификации будет использоваться в каждом кадре не менее 5000 раз) и легкий доступ (предпочтительно с индексаторами) к этим постоянным значениям?

Поиск, подобный этому, будет лучшим "Constants.TextureList [GameEntityType]"

Ответы [ 2 ]

2 голосов
/ 18 февраля 2011

Подклассами:

public abstract class Enumeration : IComparable
{
private readonly int _value;
private readonly string _displayName;

protected Enumeration()
{
}

protected Enumeration(int value, string displayName)
{
    _value = value;
    _displayName = displayName;
}

public int Value
{
    get { return _value; }
}

public string DisplayName
{
    get { return _displayName; }
}

public override string ToString()
{
    return DisplayName;
}

public static IEnumerable<T> GetAll<T>() where T : Enumeration, new()
{
    var type = typeof(T);
    var fields = type.GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);

    foreach (var info in fields)
    {
        var instance = new T();
        var locatedValue = info.GetValue(instance) as T;

        if (locatedValue != null)
        {
            yield return locatedValue;
        }
    }
}

public override bool Equals(object obj)
{
    var otherValue = obj as Enumeration;

    if (otherValue == null)
    {
        return false;
    }

    var typeMatches = GetType().Equals(obj.GetType());
    var valueMatches = _value.Equals(otherValue.Value);

    return typeMatches && valueMatches;
}

public override int GetHashCode()
{
    return _value.GetHashCode();
}

public static int AbsoluteDifference(Enumeration firstValue, Enumeration secondValue)
{
    var absoluteDifference = Math.Abs(firstValue.Value - secondValue.Value);
    return absoluteDifference;
}

public static T FromValue<T>(int value) where T : Enumeration, new()
{
    var matchingItem = parse<T, int>(value, "value", item => item.Value == value);
    return matchingItem;
}

public static T FromDisplayName<T>(string displayName) where T : Enumeration, new()
{
    var matchingItem = parse<T, string>(displayName, "display name", item => item.DisplayName == displayName);
    return matchingItem;
}

private static T parse<T, K>(K value, string description, Func<T, bool> predicate) where T : Enumeration, new()
{
    var matchingItem = GetAll<T>().FirstOrDefault(predicate);

    if (matchingItem == null)
    {
        var message = string.Format("'{0}' is not a valid {1} in {2}", value, description, typeof(T));
        throw new ApplicationException(message);
    }

    return matchingItem;
}

public int CompareTo(object other)
{
    return Value.CompareTo(((Enumeration)other).Value);
}
}

Статья здесь: http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx

0 голосов
/ 18 февраля 2011

Не уверен, что я точно понимаю, к чему вы пытаетесь, но звучит так, как будто вы ищете Dictionary<string, List<string>>, если вы ищете быстрый поиск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...