123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- //------------------------------------------------------------
- // 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
- {
- /// <summary>
- /// 游戏框架序列化器基类。
- /// </summary>
- /// <typeparam name="T">要序列化的数据类型。</typeparam>
- public abstract class GameFrameworkSerializer<T>
- {
- private readonly Dictionary<byte, SerializeCallback> m_SerializeCallbacks;
- private readonly Dictionary<byte, DeserializeCallback> m_DeserializeCallbacks;
- private readonly Dictionary<byte, TryGetValueCallback> m_TryGetValueCallbacks;
- private byte m_LatestSerializeCallbackVersion;
- /// <summary>
- /// 初始化游戏框架序列化器基类的新实例。
- /// </summary>
- public GameFrameworkSerializer()
- {
- m_SerializeCallbacks = new Dictionary<byte, SerializeCallback>();
- m_DeserializeCallbacks = new Dictionary<byte, DeserializeCallback>();
- m_TryGetValueCallbacks = new Dictionary<byte, TryGetValueCallback>();
- m_LatestSerializeCallbackVersion = 0;
- }
- /// <summary>
- /// 序列化回调函数。
- /// </summary>
- /// <param name="stream">目标流。</param>
- /// <param name="data">要序列化的数据。</param>
- /// <returns>是否序列化数据成功。</returns>
- public delegate bool SerializeCallback(Stream stream, T data);
- /// <summary>
- /// 反序列化回调函数。
- /// </summary>
- /// <param name="stream">指定流。</param>
- /// <returns>反序列化的数据。</returns>
- public delegate T DeserializeCallback(Stream stream);
- /// <summary>
- /// 尝试从指定流获取指定键的值回调函数。
- /// </summary>
- /// <param name="stream">指定流。</param>
- /// <param name="key">指定键。</param>
- /// <param name="value">指定键的值。</param>
- /// <returns>是否从指定流获取指定键的值成功。</returns>
- public delegate bool TryGetValueCallback(Stream stream, string key, out object value);
- /// <summary>
- /// 注册序列化回调函数。
- /// </summary>
- /// <param name="version">序列化回调函数的版本。</param>
- /// <param name="callback">序列化回调函数。</param>
- 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;
- }
- }
- /// <summary>
- /// 注册反序列化回调函数。
- /// </summary>
- /// <param name="version">反序列化回调函数的版本。</param>
- /// <param name="callback">反序列化回调函数。</param>
- public void RegisterDeserializeCallback(byte version, DeserializeCallback callback)
- {
- if (callback == null)
- {
- throw new GameFrameworkException("Deserialize callback is invalid.");
- }
- m_DeserializeCallbacks[version] = callback;
- }
- /// <summary>
- /// 注册尝试从指定流获取指定键的值回调函数。
- /// </summary>
- /// <param name="version">尝试从指定流获取指定键的值回调函数的版本。</param>
- /// <param name="callback">尝试从指定流获取指定键的值回调函数。</param>
- public void RegisterTryGetValueCallback(byte version, TryGetValueCallback callback)
- {
- if (callback == null)
- {
- throw new GameFrameworkException("Try get value callback is invalid.");
- }
- m_TryGetValueCallbacks[version] = callback;
- }
- /// <summary>
- /// 序列化数据到目标流中。
- /// </summary>
- /// <param name="stream">目标流。</param>
- /// <param name="data">要序列化的数据。</param>
- /// <returns>是否序列化数据成功。</returns>
- 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);
- }
- /// <summary>
- /// 序列化数据到目标流中。
- /// </summary>
- /// <param name="stream">目标流。</param>
- /// <param name="data">要序列化的数据。</param>
- /// <param name="version">序列化回调函数的版本。</param>
- /// <returns>是否序列化数据成功。</returns>
- 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);
- }
- /// <summary>
- /// 从指定流反序列化数据。
- /// </summary>
- /// <param name="stream">指定流。</param>
- /// <returns>反序列化的数据。</returns>
- 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);
- }
- /// <summary>
- /// 尝试从指定流获取指定键的值。
- /// </summary>
- /// <param name="stream">指定流。</param>
- /// <param name="key">指定键。</param>
- /// <param name="value">指定键的值。</param>
- /// <returns>是否从指定流获取指定键的值成功。</returns>
- 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);
- }
- /// <summary>
- /// 获取数据头标识。
- /// </summary>
- /// <returns>数据头标识。</returns>
- protected abstract byte[] GetHeader();
- }
- }
|