c# - Best practice for saving related constants? -
in game have enum (about 200 entrys long) different gameentitytype
s.
when game saved, array of gameentitytype
written savefile.
to reconstruct gameworld, , display various information gameentitytypes
need have list of quite few more details (constant values). means each gameentitytype
has other values associated it. these values accessed every frame. goal have simple way information out of gameentitytypeid (the enum). example, when read 0x1 out of savefile, can access name , other information implied number/enum array this: "constants.texturelist[gameentitytype
]", return string "stone_texture.dds"
example additional/associated information of first enum entry:
types: string
, string, flag-enum: "visual-classification"
, bool
, bool
values: "stoneblock"
, "stone_texture.dds"
, 0x0102
, false
, true
my first approach create static gameentitytypeinfo class had member following every additional info type:
public static const string[] = {"stoneblock", ...[more entrys]
};
of course terrible solution, because can't add gameentitytype's wherever want without having update other lists too. have separate logical units datatype units (which problem! because when decide don't need specific entitytype anymore, have go trough more 6 lists!)
next, tried tackle problem making struct out of these datasets , adding them static array. creating list additional info while constructor (while game starting) still doesn't seem best solution.
question: how can create fast(name/classification lookups used every frame @ least 5000 times in total) , easy access (preferably indexers) these constant values?
a lookup similar 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 { { return _value; } } public string displayname { { return _displayname; } } public override string tostring() { return displayname; } public static ienumerable<t> getall<t>() 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) t; if (locatedvalue != null) { yield return locatedvalue; } } } public override bool equals(object obj) { var othervalue = obj 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) t : enumeration, new() { var matchingitem = parse<t, int>(value, "value", item => item.value == value); return matchingitem; } public static t fromdisplayname<t>(string displayname) 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) t : enumeration, new() { var matchingitem = getall<t>().firstordefault(predicate); if (matchingitem == null) { var message = string.format("'{0}' not 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
Comments
Post a Comment