Quasar/Client/Core/NetSerializer/CodeGenContext.cs

111 lines
2.7 KiB
C#

/*
* Copyright 2015 Tomi Valkeinen
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
namespace xClient.Core.NetSerializer
{
public sealed class TypeData
{
public TypeData(ushort typeID, IDynamicTypeSerializer serializer)
{
this.TypeID = typeID;
this.TypeSerializer = serializer;
this.NeedsInstanceParameter = true;
}
public TypeData(ushort typeID, MethodInfo writer, MethodInfo reader)
{
this.TypeID = typeID;
this.WriterMethodInfo = writer;
this.ReaderMethodInfo = reader;
this.NeedsInstanceParameter = writer.GetParameters().Length == 3;
}
public readonly ushort TypeID;
public bool IsGenerated { get { return this.TypeSerializer != null; } }
public readonly IDynamicTypeSerializer TypeSerializer;
public MethodInfo WriterMethodInfo;
public MethodInfo ReaderMethodInfo;
public bool NeedsInstanceParameter { get; private set; }
}
public sealed class CodeGenContext
{
readonly Dictionary<Type, TypeData> m_typeMap;
public CodeGenContext(Dictionary<Type, TypeData> typeMap)
{
m_typeMap = typeMap;
var td = m_typeMap[typeof(object)];
this.SerializerSwitchMethodInfo = td.WriterMethodInfo;
this.DeserializerSwitchMethodInfo = td.ReaderMethodInfo;
}
public MethodInfo SerializerSwitchMethodInfo { get; private set; }
public MethodInfo DeserializerSwitchMethodInfo { get; private set; }
public MethodInfo GetWriterMethodInfo(Type type)
{
return m_typeMap[type].WriterMethodInfo;
}
public MethodInfo GetReaderMethodInfo(Type type)
{
return m_typeMap[type].ReaderMethodInfo;
}
public bool IsGenerated(Type type)
{
return m_typeMap[type].IsGenerated;
}
public IDictionary<Type, TypeData> TypeMap { get { return m_typeMap; } }
bool CanCallDirect(Type type)
{
// We can call the (De)serializer method directly for:
// - Value types
// - Array types
// - Sealed types with static (De)serializer method, as the method will handle null
// Other reference types go through the (De)serializerSwitch
bool direct;
if (type.IsValueType || type.IsArray)
direct = true;
else if (type.IsSealed && IsGenerated(type) == false)
direct = true;
else
direct = false;
return direct;
}
public TypeData GetTypeData(Type type)
{
return m_typeMap[type];
}
public TypeData GetTypeDataForCall(Type type)
{
bool direct = CanCallDirect(type);
if (!direct)
type = typeof(object);
return GetTypeData(type);
}
}
}