//------------------------------------------------------------
// 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();
}
}