//------------------------------------------------------------ // Game Framework // Copyright © 2013-2021 loyalsoft. All rights reserved. // Homepage: http://www.game7000.com/ // Feedback: http://www.game7000.com/ //------------------------------------------------------------ using System.Collections.Generic; using System.IO; namespace GameFramework { /// /// 游戏框架序列化器基类。 /// /// 要序列化的数据类型。 public abstract class GameFrameworkSerializer { private readonly Dictionary m_SerializeCallbacks; private readonly Dictionary m_DeserializeCallbacks; private readonly Dictionary m_TryGetValueCallbacks; private byte m_LatestSerializeCallbackVersion; /// /// 初始化游戏框架序列化器基类的新实例。 /// public GameFrameworkSerializer() { m_SerializeCallbacks = new Dictionary(); m_DeserializeCallbacks = new Dictionary(); m_TryGetValueCallbacks = new Dictionary(); m_LatestSerializeCallbackVersion = 0; } /// /// 序列化回调函数。 /// /// 目标流。 /// 要序列化的数据。 /// 是否序列化数据成功。 public delegate bool SerializeCallback(Stream stream, T data); /// /// 反序列化回调函数。 /// /// 指定流。 /// 反序列化的数据。 public delegate T DeserializeCallback(Stream stream); /// /// 尝试从指定流获取指定键的值回调函数。 /// /// 指定流。 /// 指定键。 /// 指定键的值。 /// 是否从指定流获取指定键的值成功。 public delegate bool TryGetValueCallback(Stream stream, string key, out object value); /// /// 注册序列化回调函数。 /// /// 序列化回调函数的版本。 /// 序列化回调函数。 public void RegisterSerializeCallback(byte version, SerializeCallback callback) { if (callback == null) { throw new GameFrameworkException("Serialize callback is invalid."); } m_SerializeCallbacks[version] = callback; if (version > m_LatestSerializeCallbackVersion) { m_LatestSerializeCallbackVersion = version; } } /// /// 注册反序列化回调函数。 /// /// 反序列化回调函数的版本。 /// 反序列化回调函数。 public void RegisterDeserializeCallback(byte version, DeserializeCallback callback) { if (callback == null) { throw new GameFrameworkException("Deserialize callback is invalid."); } m_DeserializeCallbacks[version] = callback; } /// /// 注册尝试从指定流获取指定键的值回调函数。 /// /// 尝试从指定流获取指定键的值回调函数的版本。 /// 尝试从指定流获取指定键的值回调函数。 public void RegisterTryGetValueCallback(byte version, TryGetValueCallback callback) { if (callback == null) { throw new GameFrameworkException("Try get value callback is invalid."); } m_TryGetValueCallbacks[version] = callback; } /// /// 序列化数据到目标流中。 /// /// 目标流。 /// 要序列化的数据。 /// 是否序列化数据成功。 public bool Serialize(Stream stream, T data) { if (m_SerializeCallbacks.Count <= 0) { throw new GameFrameworkException("No serialize callback registered."); } return Serialize(stream, data, m_LatestSerializeCallbackVersion); } /// /// 序列化数据到目标流中。 /// /// 目标流。 /// 要序列化的数据。 /// 序列化回调函数的版本。 /// 是否序列化数据成功。 public bool Serialize(Stream stream, T data, byte version) { byte[] header = GetHeader(); stream.WriteByte(header[0]); stream.WriteByte(header[1]); stream.WriteByte(header[2]); stream.WriteByte(version); SerializeCallback callback = null; if (!m_SerializeCallbacks.TryGetValue(version, out callback)) { throw new GameFrameworkException(Utility.Text.Format("Serialize callback '{0}' is not exist.", version)); } return callback(stream, data); } /// /// 从指定流反序列化数据。 /// /// 指定流。 /// 反序列化的数据。 public T Deserialize(Stream stream) { byte[] header = GetHeader(); byte header0 = (byte)stream.ReadByte(); byte header1 = (byte)stream.ReadByte(); byte header2 = (byte)stream.ReadByte(); if (header0 != header[0] || header1 != header[1] || header2 != header[2]) { throw new GameFrameworkException(Utility.Text.Format("Header is invalid, need '{0}{1}{2}', current '{3}{4}{5}'.", (char)header[0], (char)header[1], (char)header[2], (char)header0, (char)header1, (char)header2)); } byte version = (byte)stream.ReadByte(); DeserializeCallback callback = null; if (!m_DeserializeCallbacks.TryGetValue(version, out callback)) { throw new GameFrameworkException(Utility.Text.Format("Deserialize callback '{0}' is not exist.", version)); } return callback(stream); } /// /// 尝试从指定流获取指定键的值。 /// /// 指定流。 /// 指定键。 /// 指定键的值。 /// 是否从指定流获取指定键的值成功。 public bool TryGetValue(Stream stream, string key, out object value) { value = null; byte[] header = GetHeader(); byte header0 = (byte)stream.ReadByte(); byte header1 = (byte)stream.ReadByte(); byte header2 = (byte)stream.ReadByte(); if (header0 != header[0] || header1 != header[1] || header2 != header[2]) { return false; } byte version = (byte)stream.ReadByte(); TryGetValueCallback callback = null; if (!m_TryGetValueCallbacks.TryGetValue(version, out callback)) { return false; } return callback(stream, key, out value); } /// /// 获取数据头标识。 /// /// 数据头标识。 protected abstract byte[] GetHeader(); } }