开发者

Best practice for saving related constants?

开发者 https://www.devze.com 2023-02-11 00:37 出处:网络
In my game I have a enum (about 200 entrys long) with different GameEntityTypes. When the game is saved, only an array of GameEntityType is written to the savefile.

In my game I have a enum (about 200 entrys long) with different GameEntityTypes.

When the game is saved, only an array of GameEntityType is written to the savefile.

To reconstruct the gameworld, and to display various information about the GameEntityTypes I need to have a list of quite a few more extra details (constant values). This means that each GameEntityType has other values associated with it. These values are accessed very often every frame. My goal is to have a simple way to get all the extra information out of the GameEntityTypeID (the enum). For example, when I read a 0x1 out of the savefile, I can simply access the Name and all other information that is implied with the number/enum from an array like this: "Constants.TextureList[GameEntityType]", Would return the string "Stone_Texture.DDS"

Example for additional/associated information of the first enum entry:

Types: string, string, Flag-Enum: "Visual-Classification", bool, bool Values: "StoneBlock", "Stone_Texture.DDS", 0x0102, false, true

My first approach to this was to create a static GameEntityTypeInfo class that had a member like the following for every additional info type:

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

Of course this is a terrible solution, because I can't just add GameEntityType's wherever I want without having to update all other lists too. I also have to separate logical units into datatype units (which is a problem! because when I decide that I don't need an specific EntityType anymore, I have to go trough more than 6 lists!)

Next, I tried to tackle this problem by making a struct out of these datasets and adding them to a static array. But creating a List with the additional info while the constructor (while the game is starting)开发者_如何学Go still doesn't seem like the best solution.

Question: How can I create a fast(Name/Classification lookups will be used every frame at least 5000 times in total) and easy access (preferably with indexers) to these constant values?

A lookup similar to this would be best "Constants.TextureList[GameEntityType]"


By subclassing:

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

An article here: http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx


Not sure if I understand exactly what you're trying to get at but it sounds like what you're looking for is a Dictionary<string, List<string>> if you're after fast lookups.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号