Terraria ModLoader  0.11.1
A framework for Terraria mods
TagSerializer.cs
Go to the documentation of this file.
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Linq;
6 using Terraria.DataStructures;
7 
8 namespace Terraria.ModLoader.IO
9 {
10  public abstract class TagSerializer
11  {
12  public abstract Type Type { get; }
13  public abstract Type TagType { get; }
14 
15  public abstract object Serialize(object value);
16  public abstract object Deserialize(object tag);
17  public abstract IList SerializeList(IList value);
18  public abstract IList DeserializeList(IList value);
19 
20  private static IDictionary<Type, TagSerializer> serializers = new Dictionary<Type, TagSerializer>();
21  private static IDictionary<string, Type> typeNameCache = new Dictionary<string, Type>();
22 
23  static TagSerializer() {
24  Reload();
25  }
26 
27  internal static void Reload() {
28  serializers.Clear();
29  typeNameCache.Clear();
30  AddSerializer(new BoolTagSerializer());
31  AddSerializer(new UShortTagSerializer());
32  AddSerializer(new UIntTagSerializer());
33  AddSerializer(new ULongTagSerializer());
34  AddSerializer(new Vector2TagSerializer());
35  AddSerializer(new Vector3TagSerializer());
36  AddSerializer(new ColorSerializer());
37  AddSerializer(new Point16Serializer());
38  AddSerializer(new RectangleSerializer());
39  }
40 
41  public static bool TryGetSerializer(Type type, out TagSerializer serializer) {
42  if (serializers.TryGetValue(type, out serializer))
43  return true;
44 
45  if (typeof(TagSerializable).IsAssignableFrom(type)) {
46  var sType = typeof(TagSerializableSerializer<>).MakeGenericType(type);
47  serializers[type] = serializer = (TagSerializer)sType.GetConstructor(new Type[0]).Invoke(new object[0]);
48  return true;
49  }
50 
51  return false;
52  }
53 
54  public static void AddSerializer(TagSerializer serializer) {
55  serializers.Add(serializer.Type, serializer);
56  }
57 
58  public static Type GetType(string name) {
59  if (typeNameCache.TryGetValue(name, out Type type))
60  return type;
61 
62  type = Type.GetType(name);
63  if (type != null)
64  return typeNameCache[name] = type;
65 
66  foreach (var mod in ModLoader.Mods) {
67  type = mod.Code?.GetType(name);
68  if (type != null)
69  return typeNameCache[name] = type;
70  }
71 
72  return null;
73  }
74  }
75 
76  public abstract class TagSerializer<T, S> : TagSerializer
77  {
78  public override Type Type => typeof(T);
79  public override Type TagType => typeof(S);
80 
81  public abstract S Serialize(T value);
82  public abstract T Deserialize(S tag);
83 
84  public override object Serialize(object value) {
85  return Serialize((T)value);
86  }
87 
88  public override object Deserialize(object tag) {
89  return Deserialize((S)tag);
90  }
91 
92  public override IList SerializeList(IList value) {
93  return ((IList<T>)value).Select(Serialize).ToList();
94  }
95 
96  public override IList DeserializeList(IList value) {
97  return ((IList<S>)value).Select(Deserialize).ToList();
98  }
99  }
100 
101  public class UShortTagSerializer : TagSerializer<ushort, short>
102  {
103  public override short Serialize(ushort value) => (short)value;
104  public override ushort Deserialize(short tag) => (ushort)tag;
105  }
106 
107  public class UIntTagSerializer : TagSerializer<uint, int>
108  {
109  public override int Serialize(uint value) => (int)value;
110  public override uint Deserialize(int tag) => (uint)tag;
111  }
112 
113  public class ULongTagSerializer : TagSerializer<ulong, long>
114  {
115  public override long Serialize(ulong value) => (long)value;
116  public override ulong Deserialize(long tag) => (ulong)tag;
117  }
118 
119  public class BoolTagSerializer : TagSerializer<bool, byte>
120  {
121  public override byte Serialize(bool value) => (byte)(value ? 1 : 0);
122  public override bool Deserialize(byte tag) => tag != 0;
123  }
124 
125  public class Vector2TagSerializer : TagSerializer<Vector2, TagCompound>
126  {
127  public override TagCompound Serialize(Vector2 value) => new TagCompound {
128  ["x"] = value.X,
129  ["y"] = value.Y,
130  };
131 
132  public override Vector2 Deserialize(TagCompound tag) => new Vector2(tag.GetFloat("x"), tag.GetFloat("y"));
133  }
134 
135  public class Vector3TagSerializer : TagSerializer<Vector3, TagCompound>
136  {
137  public override TagCompound Serialize(Vector3 value) => new TagCompound {
138  ["x"] = value.X,
139  ["y"] = value.Y,
140  ["z"] = value.Z,
141  };
142 
143  public override Vector3 Deserialize(TagCompound tag) => new Vector3(tag.GetFloat("x"), tag.GetFloat("y"), tag.GetFloat("z"));
144  }
145 
146  public class ColorSerializer : TagSerializer<Color, int>
147  {
148  public override int Serialize(Color value) {
149  return (int)value.PackedValue;
150  }
151 
152  public override Color Deserialize(int tag) {
153  return new Color(tag & 0xFF, tag >> 8 & 0xFF, tag >> 16 & 0xFF, tag >> 24 & 0xFF);
154  }
155  }
156 
157  public class Point16Serializer : TagSerializer<Point16, TagCompound>
158  {
159  public override TagCompound Serialize(Point16 value) => new TagCompound {
160  ["x"] = value.X,
161  ["y"] = value.Y
162  };
163 
164  public override Point16 Deserialize(TagCompound tag) => new Point16(tag.GetShort("x"), tag.GetShort("y"));
165  }
166 
167  public class RectangleSerializer : TagSerializer<Rectangle, TagCompound>
168  {
169  public override TagCompound Serialize(Rectangle value) => new TagCompound {
170  ["x"] = value.X,
171  ["y"] = value.Y,
172  ["width"] = value.Width,
173  ["height"] = value.Height
174  };
175 
176  public override Rectangle Deserialize(TagCompound tag) => new Rectangle(tag.GetInt("x"), tag.GetInt("y"), tag.GetInt("width"), tag.GetInt("height"));
177  }
178 }
override IList DeserializeList(IList value)
static Type GetType(string name)
static void AddSerializer(TagSerializer serializer)
override IList SerializeList(IList value)
override object Serialize(object value)
This serves as the central class which loads mods. It contains many static fields and methods related...
Definition: ModLoader.cs:24
override int Serialize(Color value)
override object Deserialize(object tag)
override Color Deserialize(int tag)
static bool TryGetSerializer(Type type, out TagSerializer serializer)