Skip to content

Instantly share code, notes, and snippets.

@thebeardphantom
Last active August 29, 2015 14:13
Show Gist options
  • Save thebeardphantom/add5518f5b1ef34352cb to your computer and use it in GitHub Desktop.
Save thebeardphantom/add5518f5b1ef34352cb to your computer and use it in GitHub Desktop.
GameState
using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using SE = System.Environment;
using SF = System.Environment.SpecialFolder;
public static class GameState {
static string _STATE_FOLDER = CombinePaths(SE.GetFolderPath(SF.MyDocuments), "My Games");
public static string STATE_FOLDER { get { return _STATE_FOLDER; } set { _STATE_FOLDER = value; } }
static string _STATE_PATH = string.Empty;
public static string STATE_PATH {
get {
return _STATE_PATH;
}
set {
CombinePaths(STATE_FOLDER, value);
}
}
static Dictionary<string, object> stateInfo = new Dictionary<string, object>();
public static void Value(string name, object value) {
if(IsAcceptableType(value) == false)
throw new System.ArgumentException("Type of value is not a primitive type!");
stateInfo[name] = value;
}
public static T Value<T>(string name) {
return (T)stateInfo[name];
}
public static bool HasValue(string name) {
return stateInfo.ContainsKey(name);
}
public static void ClearState() {
stateInfo.Clear();
}
private static bool IsAcceptableType(object value) {
return value is bool || value is byte || value is byte[] ||
value is char || value is char[] || value is decimal ||
value is double || value is float || value is int ||
value is long || value is sbyte || value is short ||
value is string || value is uint || value is ulong ||
value is ushort;
}
public static void Load() {
Deserialize(STATE_PATH);
}
public static void Save() {
Serialize(STATE_PATH);
}
static void Serialize(string path) {
BinaryWriter bw = null;
try {
Directory.CreateDirectory(STATE_FOLDER);
bw = new BinaryWriter(new FileStream(path, FileMode.Create));
bw.Write(stateInfo.Count); //write size of dict
foreach(var si in stateInfo) {
var name = si.Key;
var value = si.Value;
bw.Write(name);
if(value is bool) {
bw.Write((byte)0); // store type
bw.Write((bool)value);
}
else if(value is byte) {
bw.Write((byte)1);
bw.Write((byte)value);
}
else if(value is byte[]) {
bw.Write((byte)2);
bw.Write(((byte[])value).Length); // write array length
bw.Write((byte[])value);
}
else if(value is char) {
bw.Write((byte)3);
bw.Write((char)value);
}
else if(value is char[]) {
bw.Write((byte)4);
bw.Write(((char[])value).Length); // write array length
bw.Write((char[])value);
}
else if(value is decimal) {
bw.Write((byte)5);
bw.Write((decimal)value);
}
else if(value is double) {
bw.Write((byte)6);
bw.Write((double)value);
}
else if(value is float) {
bw.Write((byte)7);
bw.Write((float)value);
}
else if(value is int) {
bw.Write((byte)8);
bw.Write((int)value);
}
else if(value is long) {
bw.Write((byte)9);
bw.Write((long)value);
}
else if(value is sbyte) {
bw.Write((byte)10);
bw.Write((sbyte)value);
}
else if(value is short) {
bw.Write((byte)11);
bw.Write((sbyte)value);
}
else if(value is string) {
bw.Write((byte)12);
bw.Write((string)value);
}
else if(value is uint) {
bw.Write((byte)13);
bw.Write((uint)value);
}
else if(value is ulong) {
bw.Write((byte)14);
bw.Write((ulong)value);
}
else if(value is ushort) {
bw.Write((byte)15);
bw.Write((ushort)value);
}
}
bw.Write((int)0xBADA55);
}
catch(Exception e) {
throw e;
}
finally {
if(bw != null)
bw.Close();
}
}
static void Deserialize(string path) {
BinaryReader br = null;
try {
br = new BinaryReader(new FileStream(path, FileMode.Open));
int size = br.ReadInt32(); //size of written dictionary
for(int i = 0;i < size;i++) {
var name = br.ReadString();
var type = br.ReadByte(); //read stored type
int length = 0; //for reading arrays
object value = null;
switch(type) {
case 0: value = System.Convert.ToBoolean(br.ReadByte()); break;
case 1: value = br.ReadByte(); break;
case 2: length = br.ReadInt32(); value = br.ReadBytes(length); break;
case 3: value = br.ReadChar(); break;
case 4: length = br.ReadInt32(); value = br.ReadChars(length); break;
case 5: value = br.ReadDecimal(); break;
case 6: value = br.ReadDouble(); break;
case 7: value = br.ReadSingle(); break;
case 8: value = br.ReadInt32(); break;
case 9: value = br.ReadInt64(); break;
case 10: value = br.ReadSByte(); break;
case 11: value = br.ReadInt16(); break;
case 12: value = br.ReadString(); break;
case 13: value = br.ReadUInt32(); break;
case 14: value = br.ReadUInt64(); break;
case 15: value = br.ReadUInt16(); break;
}
stateInfo[name] = value;
}
/* worst error checking ever */
int marker = br.ReadInt32();
if(marker != 0xBADA55)
throw new UnityException("Invalid state");
}
catch(Exception e) {
throw e;
}
finally {
if(br != null)
br.Close();
}
}
//How we miss you, .NET 4.0+
static string CombinePaths(params string[] paths) {
var finalPath = string.Empty;
foreach(var p in paths)
finalPath = Path.Combine(finalPath, p);
return finalPath;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment