2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-27 05:23:13 +00:00
This commit is contained in:
2022-03-09 21:55:30 +03:00
parent 530df018ec
commit 9a174f406f
106 changed files with 5166 additions and 4398 deletions

View File

@ -9,18 +9,24 @@ public class ArgumentTemplate
{
public string Name { get; set; }
public TemplateDataType Type { get; set; }
public bool Optional { get; set; }
public RepresentationType Type { get; set; }
public ParameterInfo ParameterInfo { get; set; }
public static (uint, ArgumentTemplate) Parse(byte[] data, uint offset)
public int Index { get; set; }
public static (uint, ArgumentTemplate) Parse(byte[] data, uint offset, int index)
{
var optional = (data[offset++] & 0x1) == 0x1;
var cs = (uint)data[offset++];
var name = data.GetString(offset, cs);
offset += cs;
var (size, type) = TemplateDataType.Parse(data, offset);
var (size, type) = RepresentationType.Parse(data, offset);
return (cs + 1 + size, new ArgumentTemplate(name, type));
return (cs + 2 + size, new ArgumentTemplate(name, index, type, optional));
}
public ArgumentTemplate()
@ -28,10 +34,12 @@ public class ArgumentTemplate
}
public ArgumentTemplate(string name, TemplateDataType type)
public ArgumentTemplate(string name, int index, RepresentationType type, bool optional)
{
Name = name;
Index = index;
Type = type;
Optional = optional;
}
public byte[] Compose()
@ -39,6 +47,7 @@ public class ArgumentTemplate
var name = DC.ToBytes(Name);
return new BinaryList()
.AddUInt8(Optional ? (byte)1 : (byte)0)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddUInt8Array(Type.Compose())

View File

@ -16,8 +16,8 @@ public class AttributeTemplate : MemberTemplate
}
public AttributeTemplate(TypeTemplate template, byte index, string name)
: base(template, MemberType.Attribute, index, name)
public AttributeTemplate(TypeTemplate template, byte index, string name, bool inherited)
: base(template, index, name, inherited)
{
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Data;
namespace Esiur.Resource.Template;
public class ConstantTemplate : MemberTemplate
{
public readonly object Value;
//public readonly byte[] ValueData;
public readonly string Expansion;
public readonly RepresentationType ValueType;
public ConstantTemplate(TypeTemplate template, byte index, string name, bool inherited, RepresentationType valueType, object value, string expansion)
: base(template, index, name, inherited)
{
Expansion = expansion;
ValueType = valueType;
Value = value;
//try
//{
// Codec.Compose(value, null);
// Value = value;
//}
//catch
//{
// throw new Exception($"Constant `{template.ClassName}.{name}` can't be serialized.");
//}
}
public override byte[] Compose()
{
var name = base.Compose();
var hdr = Inherited ? (byte)0x80 : (byte)0;
if (Expansion != null)
{
var exp = DC.ToBytes(Expansion);
hdr |= 0x70;
return new BinaryList()
.AddUInt8(hdr)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddUInt8Array(ValueType.Compose())
.AddUInt8Array(Codec.Compose(Value, null))
.AddInt32(exp.Length)
.AddUInt8Array(exp)
.ToArray();
}
else
{
hdr |= 0x60;
return new BinaryList()
.AddUInt8(hdr)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddUInt8Array(ValueType.Compose())
.AddUInt8Array(Codec.Compose(Value, null))
.ToArray();
}
}
}

View File

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource.Template
{
internal class CustomEventOccurredEvent
{
}
}

View File

@ -19,17 +19,23 @@ public class EventTemplate : MemberTemplate
public EventInfo EventInfo { get; set; }
public TemplateDataType ArgumentType { get; set; }
public RepresentationType ArgumentType { get; set; }
public override byte[] Compose()
{
var name = base.Compose();
var hdr = Inherited ? (byte)0x80 : (byte)0;
if (Listenable)
hdr |= 0x8;
if (Expansion != null)
{
var exp = DC.ToBytes(Expansion);
hdr |= 0x50;
return new BinaryList()
.AddUInt8(Listenable ? (byte)0x58 : (byte)0x50)
.AddUInt8(hdr)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddUInt8Array(ArgumentType.Compose())
@ -38,17 +44,17 @@ public class EventTemplate : MemberTemplate
.ToArray();
}
else
hdr |= 0x40;
return new BinaryList()
.AddUInt8(Listenable ? (byte)0x48 : (byte)0x40)
.AddUInt8(hdr)
.AddUInt8((byte)name.Length)
.AddUInt8Array(name)
.AddUInt8Array(ArgumentType.Compose())
.ToArray();
}
public EventTemplate(TypeTemplate template, byte index, string name, TemplateDataType argumentType, string expansion = null, bool listenable = false)
: base(template, MemberType.Property, index, name)
public EventTemplate(TypeTemplate template, byte index, string name,bool inherited, RepresentationType argumentType, string expansion = null, bool listenable = false)
: base(template, index, name, inherited)
{
this.Expansion = expansion;
this.Listenable = listenable;

View File

@ -22,7 +22,7 @@ public class FunctionTemplate : MemberTemplate
// set;
//}
public TemplateDataType ReturnType { get; set; }
public RepresentationType ReturnType { get; set; }
public ArgumentTemplate[] Arguments { get; set; }
@ -54,17 +54,16 @@ public class FunctionTemplate : MemberTemplate
var exp = DC.ToBytes(Expansion);
bl.AddInt32(exp.Length)
.AddUInt8Array(exp);
bl.InsertUInt8(0, 0x10);
bl.InsertUInt8(0, Inherited ? (byte)0x90 : (byte)0x10);
}
else
bl.InsertUInt8(0, 0x0);
bl.InsertUInt8(0, Inherited ? (byte)0x80 : (byte)0x0);
return bl.ToArray();
}
public FunctionTemplate(TypeTemplate template, byte index, string name, ArgumentTemplate[] arguments, TemplateDataType returnType, string expansion = null)
: base(template, MemberType.Property, index, name)
public FunctionTemplate(TypeTemplate template, byte index, string name, bool inherited, ArgumentTemplate[] arguments, RepresentationType returnType, string expansion = null)
: base(template, index, name, inherited)
{
//this.IsVoid = isVoid;
this.Arguments = arguments;

View File

@ -8,34 +8,21 @@ using System.Threading.Tasks;
namespace Esiur.Resource.Template;
public class MemberTemplate
{
public enum MemberType
public readonly byte Index;
public readonly string Name;
public readonly bool Inherited;
public readonly TypeTemplate Template;
public MemberTemplate(TypeTemplate template, byte index, string name, bool inherited)
{
Function = 0,
Property = 1,
Event = 2,
Attribute = 3
Template = template;
Index = index;
Name = name;
Inherited = inherited;
}
public byte Index => index;
public string Name => name;
public MemberType Type => type;
TypeTemplate template;
string name;
MemberType type;
byte index;
public TypeTemplate Template => template;
public MemberTemplate(TypeTemplate template, MemberType type, byte index, string name)
{
this.template = template;
this.type = type;
this.index = index;
this.name = name;
}
public string Fullname => template.ClassName + "." + Name;
public string Fullname => Template.ClassName + "." + Name;
public virtual byte[] Compose()
{

View File

@ -23,7 +23,7 @@ public class PropertyTemplate : MemberTemplate
set;
}
public TemplateDataType ValueType { get; set; }
public RepresentationType ValueType { get; set; }
/*
@ -40,6 +40,7 @@ public class PropertyTemplate : MemberTemplate
set;
}
public bool IsNullable { get; set; }
public bool Recordable
{
@ -79,6 +80,9 @@ public class PropertyTemplate : MemberTemplate
var name = base.Compose();
var pv = ((byte)(Permission) << 1) | (Recordable ? 1 : 0);
if (Inherited)
pv |= 0x80;
if (WriteExpansion != null && ReadExpansion != null)
{
var rexp = DC.ToBytes(ReadExpansion);
@ -129,12 +133,14 @@ public class PropertyTemplate : MemberTemplate
}
}
public PropertyTemplate(TypeTemplate template, byte index, string name, TemplateDataType valueType, string read = null, string write = null, bool recordable = false)
: base(template, MemberType.Property, index, name)
public PropertyTemplate(TypeTemplate template, byte index, string name, bool inherited,
RepresentationType valueType, string read = null, string write = null, bool recordable = false)
: base(template, index, name, inherited)
{
this.Recordable = recordable;
//this.Storage = storage;
this.ReadExpansion = read;
if (read != null)
this.ReadExpansion = read;
this.WriteExpansion = write;
this.ValueType = valueType;
}

View File

@ -1,107 +1,131 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Text;
//using Esiur.Data;
//using System;
//using System.Collections;
//using System.Collections.Generic;
//using System.Dynamic;
//using System.Linq;
//using System.Text;
namespace Esiur.Resource.Template;
public struct TemplateDataType
{
public DataType Type { get; set; }
//public string TypeName { get; set; }
public TypeTemplate TypeTemplate => TypeGuid == null ? null : Warehouse.GetTemplateByClassId((Guid)TypeGuid);
//namespace Esiur.Resource.Template;
//public struct TemplateDataType
//{
// public DataType Type { get; set; }
// //public string TypeName { get; set; }
// public TypeTemplate TypeTemplate => TypeGuid == null ? null : Warehouse.GetTemplateByClassId((Guid)TypeGuid);
public Guid? TypeGuid { get; set; }
//public TemplateDataType(DataType type, string typeName)
//{
// Type = type;
// TypeName = typeName;
//}
// public Guid? TypeGuid { get; set; }
// public bool IsNullable { get; set; }
// //public TemplateDataType(DataType type, string typeName)
// //{
// // Type = type;
// // TypeName = typeName;
// //}
public static TemplateDataType FromType(Type type)
{
var t = type switch
{
{ IsArray: true } => type.GetElementType(),
{ IsEnum: true } => type.GetEnumUnderlyingType(),
(_) => type
};
DataType dt = t switch
{
_ when t == typeof(bool) => DataType.Bool,
_ when t == typeof(char) => DataType.Char,
_ when t == typeof(byte) => DataType.UInt8,
_ when t == typeof(sbyte) => DataType.Int8,
_ when t == typeof(short) => DataType.Int16,
_ when t == typeof(ushort) => DataType.UInt16,
_ when t == typeof(int) => DataType.Int32,
_ when t == typeof(uint) => DataType.UInt32,
_ when t == typeof(long) => DataType.Int64,
_ when t == typeof(ulong) => DataType.UInt64,
_ when t == typeof(float) => DataType.Float32,
_ when t == typeof(double) => DataType.Float64,
_ when t == typeof(decimal) => DataType.Decimal,
_ when t == typeof(string) => DataType.String,
_ when t == typeof(DateTime) => DataType.DateTime,
_ when t == typeof(IResource) => DataType.Void, // Dynamic resource (unspecified type)
_ when t == typeof(IRecord) => DataType.Void, // Dynamic record (unspecified type)
_ when typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => DataType.Structure,
_ when Codec.ImplementsInterface(t, typeof(IResource)) => DataType.Resource,
_ when Codec.ImplementsInterface(t, typeof(IRecord)) => DataType.Record,
_ => DataType.Void
};
// public static TemplateDataType FromType(Type type)
// {
Guid? typeGuid = null;
// bool isList = typeof(ICollection).IsAssignableFrom(type);
if (dt == DataType.Resource || dt == DataType.Record)
typeGuid = TypeTemplate.GetTypeGuid(t);
// var t = type switch
// {
if (type.IsArray)
dt = (DataType)((byte)dt | 0x80);
// { IsArray: true } => type.GetElementType(),
// { IsEnum: true } => type.GetEnumUnderlyingType(),
// _ when isList => Codec.GetGenericListType(type),
// (_) => type
// };
return new TemplateDataType()
{
Type = dt,
TypeGuid = typeGuid
};
}
public byte[] Compose()
{
if (Type == DataType.Resource ||
Type == DataType.ResourceArray ||
Type == DataType.Record ||
Type == DataType.RecordArray)
{
var guid = DC.ToBytes((Guid)TypeGuid);
return new BinaryList()
.AddUInt8((byte)Type)
.AddUInt8Array(guid).ToArray();
}
else
return new byte[] { (byte)Type };
}
public override string ToString() => Type.ToString() + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
// DataType dt = t switch
// {
// _ when t == typeof(bool) => DataType.Bool,
// _ when t == typeof(char) => DataType.Char,
// _ when t == typeof(byte) => DataType.UInt8,
// _ when t == typeof(sbyte) => DataType.Int8,
// _ when t == typeof(short) => DataType.Int16,
// _ when t == typeof(ushort) => DataType.UInt16,
// _ when t == typeof(int) => DataType.Int32,
// _ when t == typeof(uint) => DataType.UInt32,
// _ when t == typeof(long) => DataType.Int64,
// _ when t == typeof(ulong) => DataType.UInt64,
// _ when t == typeof(float) => DataType.Float32,
// _ when t == typeof(double) => DataType.Float64,
// _ when t == typeof(decimal) => DataType.Decimal,
// _ when t == typeof(string) => DataType.String,
// _ when t == typeof(DateTime) => DataType.DateTime,
// _ when t == typeof(IResource) => DataType.Void, // Dynamic resource (unspecified type)
// _ when t == typeof(IRecord) => DataType.Void, // Dynamic record (unspecified type)
// _ when typeof(Structure).IsAssignableFrom(t) || t == typeof(ExpandoObject) => DataType.Structure,
// _ when Codec.ImplementsInterface(t, typeof(IResource)) => DataType.Resource,
// _ when Codec.ImplementsInterface(t, typeof(IRecord)) => DataType.Record,
// _ => DataType.Void
// };
public static (uint, TemplateDataType) Parse(byte[] data, uint offset)
{
var type = (DataType)data[offset++];
if (type == DataType.Resource ||
type == DataType.ResourceArray ||
type == DataType.Record ||
type == DataType.RecordArray)
{
var guid = data.GetGuid(offset);
return (17, new TemplateDataType() { Type = type, TypeGuid = guid });
}
else
return (1, new TemplateDataType() { Type = type });
}
}
// Guid? typeGuid = null;
// if (dt == DataType.Resource || dt == DataType.Record)
// typeGuid = TypeTemplate.GetTypeGuid(t);
// if (type.IsArray || isList)
// dt = (DataType)((byte)dt | 0x80);
// return new TemplateDataType()
// {
// Type = dt,
// TypeGuid = typeGuid,
// IsNullable = Nullable.GetUnderlyingType(type) != null
// };
// }
// public byte[] Compose()
// {
// if (Type == DataType.Resource ||
// Type == DataType.ResourceArray ||
// Type == DataType.Record ||
// Type == DataType.RecordArray)
// {
// var guid = DC.ToBytes((Guid)TypeGuid);
// if (IsNullable)
// {
// return new BinaryList()
// .AddUInt8((byte)((byte)Type | 0x40))
// .AddUInt8Array(guid).ToArray();
// } else
// {
// return new BinaryList()
// .AddUInt8((byte)Type)
// .AddUInt8Array(guid).ToArray();
// }
// }
// else if (IsNullable)
// return new byte[] { (byte)((byte)Type | 0x40) };
// else
// return new byte[] { (byte)Type };
// }
// public override string ToString() => Type.ToString() + (IsNullable ? "?":"" )
// + TypeTemplate != null ? "<" + TypeTemplate.ClassName + ">" : "";
// public static (uint, TemplateDataType) Parse(byte[] data, uint offset)
// {
// bool isNullable = (data[offset] & 0x40) > 0;
// var type = (DataType)(data[offset++] & 0xBF);
// if (type == DataType.Resource ||
// type == DataType.ResourceArray ||
// type == DataType.Record ||
// type == DataType.RecordArray)
// {
// var guid = data.GetGuid(offset);
// return (17, new TemplateDataType() { Type = type, TypeGuid = guid , IsNullable = isNullable});
// }
// else
// return (1, new TemplateDataType() { Type = type, IsNullable = isNullable });
// }
//}

View File

@ -9,4 +9,5 @@ public enum TemplateType : byte
Resource,
Record,
Wrapper,
Enum
}

View File

@ -22,20 +22,26 @@ public class TypeTemplate
{
protected Guid classId;
protected string className;
protected List<MemberTemplate> members = new List<MemberTemplate>();
protected List<FunctionTemplate> functions = new List<FunctionTemplate>();
protected List<EventTemplate> events = new List<EventTemplate>();
protected List<PropertyTemplate> properties = new List<PropertyTemplate>();
protected List<AttributeTemplate> attributes = new List<AttributeTemplate>();
protected int version;
protected TemplateType templateType;
protected Guid? parentId;
string className;
List<MemberTemplate> members = new List<MemberTemplate>();
List<FunctionTemplate> functions = new List<FunctionTemplate>();
List<EventTemplate> events = new List<EventTemplate>();
List<PropertyTemplate> properties = new List<PropertyTemplate>();
List<AttributeTemplate> attributes = new List<AttributeTemplate>();
List<ConstantTemplate> constants = new();
int version;
TemplateType templateType;
// protected TemplateType
//bool isReady;
protected byte[] content;
public Guid? ParentId => parentId;
public byte[] Content
{
get { return content; }
@ -45,9 +51,7 @@ public class TypeTemplate
public Type DefinedType { get; set; }
public Type ParentDefinedType { get; set; }
//public MemberTemplate GetMemberTemplate(MemberInfo member)
//{
@ -145,7 +149,7 @@ public class TypeTemplate
get { return properties.ToArray(); }
}
public ConstantTemplate[] Constants => constants.ToArray();
public TypeTemplate()
{
@ -166,7 +170,7 @@ public class TypeTemplate
static Type GetElementType(Type type) => type switch
{
{ IsArray: true } => type.GetElementType(),
{ IsEnum: true } => type.GetEnumUnderlyingType(),
// { IsEnum: true } => type.GetEnumUnderlyingType(),
(_) => type
};
@ -177,8 +181,20 @@ public class TypeTemplate
var list = new List<TypeTemplate>();
// Add self
list.Add(template);
// Add parents
var parentType = template.ParentDefinedType;
// Get parents
while (parentType != null)
{
var parentTemplate = Warehouse.GetTemplateByType(parentType);
list.Add(parentTemplate);
parentType = parentTemplate.ParentDefinedType;
}
Action<TypeTemplate, List<TypeTemplate>> getDependenciesFunc = null;
getDependenciesFunc = (TypeTemplate tmp, List<TypeTemplate> bag) =>
@ -186,8 +202,8 @@ public class TypeTemplate
if (template.DefinedType == null)
return;
// functions
foreach (var f in tmp.functions)
// functions
foreach (var f in tmp.functions)
{
var frtt = Warehouse.GetTemplateByType(GetElementType(f.MethodInfo.ReturnType));
if (frtt != null)
@ -214,8 +230,8 @@ public class TypeTemplate
}
}
// skip DistributedConnection argument
if (args.Length > 0)
// skip DistributedConnection argument
if (args.Length > 0)
{
var last = args.Last();
if (last.ParameterType != typeof(DistributedConnection))
@ -234,8 +250,8 @@ public class TypeTemplate
}
// properties
foreach (var p in tmp.properties)
// properties
foreach (var p in tmp.properties)
{
var pt = Warehouse.GetTemplateByType(GetElementType(p.PropertyInfo.PropertyType));
if (pt != null)
@ -248,8 +264,8 @@ public class TypeTemplate
}
}
// events
foreach (var e in tmp.events)
// events
foreach (var e in tmp.events)
{
var et = Warehouse.GetTemplateByType(GetElementType(e.EventInfo.EventHandlerType.GenericTypeArguments[0]));
@ -268,6 +284,15 @@ public class TypeTemplate
return list.ToArray();
}
public string GetTypeAnnotationName(Type type)
{
var nullType = Nullable.GetUnderlyingType(type);
if (nullType == null)
return type.Name;
else
return type.Name + "?";
}
public TypeTemplate(Type type, bool addToWarehouse = false)
{
if (Codec.InheritsClass(type, typeof(DistributedResource)))
@ -276,6 +301,8 @@ public class TypeTemplate
templateType = TemplateType.Resource;
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
templateType = TemplateType.Record;
else if (type.IsEnum)
templateType = TemplateType.Enum;
else
throw new Exception("Type must implement IResource, IRecord or inherit from DistributedResource.");
@ -291,32 +318,56 @@ public class TypeTemplate
className = type.FullName;
//Console.WriteLine($"Creating {className}");
// set guid
classId = GetTypeGuid(className);
if (addToWarehouse)
Warehouse.PutTemplate(this);
#if NETSTANDARD
PropertyInfo[] propsInfo = type.GetTypeInfo().GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetTypeInfo().GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetTypeInfo().GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly);
#else
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
#endif
PropertyInfo[] propsInfo = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
EventInfo[] eventsInfo = type.GetEvents(BindingFlags.Public | BindingFlags.Instance);// | BindingFlags.DeclaredOnly);
MethodInfo[] methodsInfo = type.GetMethods(BindingFlags.Public | BindingFlags.Instance); // | BindingFlags.DeclaredOnly);
FieldInfo[] constantsInfo = type.GetFields(BindingFlags.Public | BindingFlags.Static);
bool classIsPublic = type.IsEnum || (type.GetCustomAttribute<PublicAttribute>() != null);
bool classIsPublic = type.GetCustomAttribute<PublicAttribute>() != null;
byte i = 0;
if (classIsPublic)
{
foreach (var ci in constantsInfo)
{
var privateAttr = ci.GetCustomAttribute<PrivateAttribute>(true);
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
if (privateAttr != null)
continue;
var valueType = RepresentationType.FromType(ci.FieldType);
if (valueType == null)
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
var value = ci.GetValue(null);
if (templateType == TemplateType.Enum)
value = Convert.ChangeType(value, ci.FieldType.GetEnumUnderlyingType());
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
constants.Add(ct);
}
i = 0;
foreach (var pi in propsInfo)
{
var privateAttr = pi.GetCustomAttribute<PrivateAttribute>(true);
@ -326,7 +377,12 @@ public class TypeTemplate
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
var pt = new PropertyTemplate(this, i++, pi.Name, TemplateDataType.FromType(pi.PropertyType));
var attrType = RepresentationType.FromType(pi.PropertyType);
if (attrType == null)
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
var pt = new PropertyTemplate(this, i++, pi.Name, pi.DeclaringType != type, attrType);
if (storageAttr != null)
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
@ -334,7 +390,7 @@ public class TypeTemplate
if (annotationAttr != null)
pt.ReadExpansion = annotationAttr.Annotation;
else
pt.ReadExpansion = pi.PropertyType.Name;
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
pt.PropertyInfo = pi;
//pt.Serilize = publicAttr.Serialize;
@ -346,7 +402,7 @@ public class TypeTemplate
if (attributeAttr != null)
{
var an = attributeAttr.Name ?? pi.Name;
var at = new AttributeTemplate(this, 0, an);
var at = new AttributeTemplate(this, 0, an, pi.DeclaringType != type);
at.PropertyInfo = pi;
attributes.Add(at);
}
@ -356,69 +412,109 @@ public class TypeTemplate
if (templateType == TemplateType.Resource)
{
i = 0;
foreach (var ei in eventsInfo)
{
var privateAttr = ei.GetCustomAttribute<PrivateAttribute>(true);
if (privateAttr == null)
{
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
if (privateAttr != null)
continue;
var argType = ei.EventHandlerType.GenericTypeArguments[0];
var et = new EventTemplate(this, i++, ei.Name, TemplateDataType.FromType(argType));
et.EventInfo = ei;
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
if (annotationAttr != null)
et.Expansion = annotationAttr.Annotation;
var argType = ei.EventHandlerType.GenericTypeArguments[0];
var evtType = RepresentationType.FromType(argType);
if (listenableAttr != null)
et.Listenable = true;
if (evtType == null)
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
events.Add(et);
}
var et = new EventTemplate(this, i++, ei.Name, ei.DeclaringType != type, evtType);
et.EventInfo = ei;
if (annotationAttr != null)
et.Expansion = annotationAttr.Annotation;
if (listenableAttr != null)
et.Listenable = true;
events.Add(et);
}
i = 0;
foreach (MethodInfo mi in methodsInfo)
{
var privateAttr = mi.GetCustomAttribute<PrivateAttribute>(true);
if (privateAttr == null)
if (privateAttr != null)
continue;
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
var returnType = RepresentationType.FromType(mi.ReturnType);
if (returnType == null)
throw new Exception($"Unsupported type {mi.ReturnType} in method {type.Name}.{mi.Name} return");
var args = mi.GetParameters();
if (args.Length > 0)
{
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
if (args.Last().ParameterType == typeof(DistributedConnection))
args = args.Take(args.Count() - 1).ToArray();
}
var returnType = TemplateDataType.FromType(mi.ReturnType);
var arguments = args.Select(x =>
{
var argType = RepresentationType.FromType(x.ParameterType);
if (argType == null)
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
var args = mi.GetParameters();
if (args.Length > 0)
{
if (args.Last().ParameterType == typeof(DistributedConnection))
args = args.Take(args.Count() - 1).ToArray();
}
var arguments = args.Select(x => new ArgumentTemplate()
return new ArgumentTemplate()
{
Name = x.Name,
Type = TemplateDataType.FromType(x.ParameterType),
ParameterInfo = x
}).ToArray();
Type = argType,
ParameterInfo = x,
Optional = x.IsOptional
};
}).ToArray();
var ft = new FunctionTemplate(this, i++, mi.Name, arguments, returnType);// mi.ReturnType == typeof(void));
var ft = new FunctionTemplate(this, i++, mi.Name, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
if (annotationAttr != null)
ft.Expansion = annotationAttr.Annotation;
else
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
if (annotationAttr != null)
ft.Expansion = annotationAttr.Annotation;
else
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
ft.MethodInfo = mi;
functions.Add(ft);
}
ft.MethodInfo = mi;
functions.Add(ft);
}
}
}
else
{
foreach (var ci in constantsInfo)
{
var publicAttr = ci.GetCustomAttribute<PublicAttribute>(true);
var annotationAttr = ci.GetCustomAttribute<AnnotationAttribute>(true);
if (publicAttr == null)
continue;
var valueType = RepresentationType.FromType(ci.FieldType);
if (valueType == null)
throw new Exception($"Unsupported type `{ci.FieldType}` in constant `{type.Name}.{ci.Name}`");
var value = ci.GetValue(null);
var ct = new ConstantTemplate(this, i++, ci.Name, ci.DeclaringType != type, valueType, value, annotationAttr?.Annotation);
constants.Add(ct);
}
i = 0;
foreach (var pi in propsInfo)
{
@ -428,17 +524,22 @@ public class TypeTemplate
{
var annotationAttr = pi.GetCustomAttribute<AnnotationAttribute>(true);
var storageAttr = pi.GetCustomAttribute<StorageAttribute>(true);
var valueType = TemplateDataType.FromType(pi.PropertyType);
var valueType = RepresentationType.FromType(pi.PropertyType);
if (valueType == null)
throw new Exception($"Unsupported type `{pi.PropertyType}` in property `{type.Name}.{pi.Name}`");
var pn = publicAttr.Name ?? pi.Name;
var pt = new PropertyTemplate(this, i++, pn, valueType);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
var pt = new PropertyTemplate(this, i++, pn, pi.DeclaringType != type, valueType);//, rp.ReadExpansion, rp.WriteExpansion, rp.Storage);
if (storageAttr != null)
pt.Recordable = storageAttr.Mode == StorageMode.Recordable;
if (annotationAttr != null)
pt.ReadExpansion = annotationAttr.Annotation;
else
pt.ReadExpansion = pi.PropertyType.Name;
pt.ReadExpansion = GetTypeAnnotationName(pi.PropertyType);
pt.PropertyInfo = pi;
//pt.Serilize = publicAttr.Serialize;
@ -450,7 +551,7 @@ public class TypeTemplate
if (attributeAttr != null)
{
var pn = attributeAttr.Name ?? pi.Name;
var at = new AttributeTemplate(this, 0, pn);
var at = new AttributeTemplate(this, 0, pn, pi.DeclaringType != type);
at.PropertyInfo = pi;
attributes.Add(at);
}
@ -464,65 +565,85 @@ public class TypeTemplate
foreach (var ei in eventsInfo)
{
var publicAttr = ei.GetCustomAttribute<PublicAttribute>(true);
if (publicAttr != null)
{
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
var argType = ei.EventHandlerType.GenericTypeArguments[0];
if (publicAttr == null)
continue;
var en = publicAttr.Name ?? ei.Name;
var et = new EventTemplate(this, i++, en, TemplateDataType.FromType(argType));
et.EventInfo = ei;
var annotationAttr = ei.GetCustomAttribute<AnnotationAttribute>(true);
var listenableAttr = ei.GetCustomAttribute<ListenableAttribute>(true);
if (annotationAttr != null)
et.Expansion = annotationAttr.Annotation;
var argType = ei.EventHandlerType.GenericTypeArguments[0];
if (listenableAttr != null)
et.Listenable = true;
var en = publicAttr.Name ?? ei.Name;
events.Add(et);
}
var evtType = RepresentationType.FromType(argType);
if (evtType == null)
throw new Exception($"Unsupported type `{argType}` in event `{type.Name}.{ei.Name}`");
var et = new EventTemplate(this, i++, en, ei.DeclaringType != type, evtType);
et.EventInfo = ei;
if (annotationAttr != null)
et.Expansion = annotationAttr.Annotation;
if (listenableAttr != null)
et.Listenable = true;
events.Add(et);
}
i = 0;
foreach (MethodInfo mi in methodsInfo)
{
var publicAttr = mi.GetCustomAttribute<PublicAttribute>(true);
if (publicAttr != null)
if (publicAttr == null)
continue;
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
var returnType = RepresentationType.FromType(mi.ReturnType);
if (returnType == null)
throw new Exception($"Unsupported type `{mi.ReturnType}` in method `{type.Name}.{mi.Name}` return");
var args = mi.GetParameters();
if (args.Length > 0)
{
var annotationAttr = mi.GetCustomAttribute<AnnotationAttribute>(true);
var returnType = TemplateDataType.FromType(mi.ReturnType);
if (args.Last().ParameterType == typeof(DistributedConnection))
args = args.Take(args.Count() - 1).ToArray();
}
var args = mi.GetParameters();
var arguments = args.Select(x =>
{
var argType = RepresentationType.FromType(x.ParameterType);
if (argType == null)
throw new Exception($"Unsupported type `{x.ParameterType}` in method `{type.Name}.{mi.Name}` parameter `{x.Name}`");
if (args.Length > 0)
{
if (args.Last().ParameterType == typeof(DistributedConnection))
args = args.Take(args.Count() - 1).ToArray();
}
var arguments = args.Select(x => new ArgumentTemplate()
return new ArgumentTemplate()
{
Name = x.Name,
Type = TemplateDataType.FromType(x.ParameterType),
ParameterInfo = x
})
.ToArray();
Type = argType,
ParameterInfo = x,
Optional = x.IsOptional
};
})
.ToArray();
var fn = publicAttr.Name ?? mi.Name;
var fn = publicAttr.Name ?? mi.Name;
var ft = new FunctionTemplate(this, i++, fn, arguments, returnType);// mi.ReturnType == typeof(void));
var ft = new FunctionTemplate(this, i++, fn, mi.DeclaringType != type, arguments, returnType);// mi.ReturnType == typeof(void));
if (annotationAttr != null)
ft.Expansion = annotationAttr.Annotation;
else
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
if (annotationAttr != null)
ft.Expansion = annotationAttr.Annotation;
else
ft.Expansion = "(" + String.Join(",", mi.GetParameters().Where(x => x.ParameterType != typeof(DistributedConnection)).Select(x => "[" + x.ParameterType.Name + "] " + x.Name)) + ") -> " + mi.ReturnType.Name;
ft.MethodInfo = mi;
functions.Add(ft);
ft.MethodInfo = mi;
functions.Add(ft);
}
}
}
}
@ -537,15 +658,41 @@ public class TypeTemplate
for (i = 0; i < properties.Count; i++)
members.Add(properties[i]);
// append constants
for (i = 0; i < constants.Count; i++)
members.Add(constants[i]);
// bake it binarily
var b = new BinaryList();
b.AddUInt8((byte)templateType)
.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
// find the first parent type that implements IResource
if (HasParent(type))
{
// find the first parent type that implements IResource
var ParentDefinedType = ResourceProxy.GetBaseType(type.BaseType);
var parentId = GetTypeGuid(ParentDefinedType.FullName);
b.AddUInt8((byte)(0x80 | (byte)templateType))
.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddGuid(parentId)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
}
else
{
b.AddUInt8((byte)templateType)
.AddGuid(classId)
.AddUInt8((byte)className.Length)
.AddString(className)
.AddInt32(version)
.AddUInt16((ushort)members.Count);
}
foreach (var ft in functions)
b.AddUInt8Array(ft.Compose());
@ -553,11 +700,32 @@ public class TypeTemplate
b.AddUInt8Array(pt.Compose());
foreach (var et in events)
b.AddUInt8Array(et.Compose());
foreach (var ct in constants)
b.AddUInt8Array(ct.Compose());
content = b.ToArray();
}
public static bool HasParent (Type type)
{
var parent = type.BaseType;
if (parent == typeof(Resource)
|| parent == typeof(Record))
return false;
while (parent != null)
{
if (parent.GetInterfaces().Contains(typeof(IResource))
|| parent.GetInterfaces().Contains(typeof(IRecord)))
return true;
parent = parent.BaseType;
}
return false;
}
public static TypeTemplate Parse(byte[] data)
{
return Parse(data, 0, (uint)data.Length);
@ -576,17 +744,27 @@ public class TypeTemplate
var od = new TypeTemplate();
od.content = data.Clip(offset, contentLength);
od.templateType = (TemplateType)data[offset++];
var hasParent = (data[offset] & 0x80) > 0;
od.templateType = (TemplateType)(data[offset++] & 0xF);
od.classId = data.GetGuid(offset);
offset += 16;
od.className = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
od.version = data.GetInt32(offset);
if (od.className == "Test.MyChildRecord")
Console.WriteLine();
if (hasParent)
{
od.parentId = data.GetGuid(offset);
offset += 16;
}
od.version = data.GetInt32(offset, Endian.Little);
offset += 4;
ushort methodsCount = data.GetUInt16(offset);
ushort methodsCount = data.GetUInt16(offset, Endian.Little);
offset += 2;
byte functionIndex = 0;
@ -595,7 +773,8 @@ public class TypeTemplate
for (int i = 0; i < methodsCount; i++)
{
var type = data[offset] >> 5;
var inherited = (data[offset] & 0x80) > 0;
var type = (data[offset] >> 5) & 0x3;
if (type == 0) // function
{
@ -606,7 +785,7 @@ public class TypeTemplate
offset += (uint)data[offset] + 1;
// return type
var (rts, returnType) = TemplateDataType.Parse(data, offset);
var (rts, returnType) = RepresentationType.Parse(data, offset);
offset += rts;
// arguments count
@ -615,7 +794,7 @@ public class TypeTemplate
for (var a = 0; a < argsCount; a++)
{
var (cs, argType) = ArgumentTemplate.Parse(data, offset);
var (cs, argType) = ArgumentTemplate.Parse(data, offset, a);
arguments.Add(argType);
offset += cs;
}
@ -623,13 +802,13 @@ public class TypeTemplate
// arguments
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
expansion = data.GetString(offset, cs);
offset += cs;
}
var ft = new FunctionTemplate(od, functionIndex++, name, arguments.ToArray(), returnType, expansion);
var ft = new FunctionTemplate(od, functionIndex++, name, inherited, arguments.ToArray(), returnType, expansion);
od.functions.Add(ft);
}
@ -646,13 +825,13 @@ public class TypeTemplate
offset += (uint)data[offset] + 1;
var (dts, valueType) = TemplateDataType.Parse(data, offset);
var (dts, valueType) = RepresentationType.Parse(data, offset);
offset += dts;
if (hasReadExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
readExpansion = data.GetString(offset, cs);
offset += cs;
@ -660,13 +839,13 @@ public class TypeTemplate
if (hasWriteExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
writeExpansion = data.GetString(offset, cs);
offset += cs;
}
var pt = new PropertyTemplate(od, propertyIndex++, name, valueType, readExpansion, writeExpansion, recordable);
var pt = new PropertyTemplate(od, propertyIndex++, name, inherited, valueType, readExpansion, writeExpansion, recordable);
od.properties.Add(pt);
}
@ -680,23 +859,52 @@ public class TypeTemplate
var name = data.GetString(offset + 1, data[offset]);// Encoding.ASCII.GetString(data, (int)offset + 1, (int)data[offset]);
offset += (uint)data[offset] + 1;
var (dts, argType) = TemplateDataType.Parse(data, offset);
var (dts, argType) = RepresentationType.Parse(data, offset);
offset += dts;
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset);
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
expansion = data.GetString(offset, cs);
offset += cs;
}
var et = new EventTemplate(od, eventIndex++, name, argType, expansion, listenable);
var et = new EventTemplate(od, eventIndex++, name, inherited, argType, expansion, listenable);
od.events.Add(et);
}
// constant
else if (type == 3)
{
string expansion = null;
var hasExpansion = ((data[offset++] & 0x10) == 0x10);
var name = data.GetString(offset + 1, data[offset]);
offset += (uint)data[offset] + 1;
var (dts, valueType) = RepresentationType.Parse(data, offset);
offset += dts;
(dts, var value) = Codec.Parse(data, offset, null);
offset += dts;
if (hasExpansion) // expansion ?
{
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
expansion = data.GetString(offset, cs);
offset += cs;
}
var ct = new ConstantTemplate(od, eventIndex++, name, inherited, valueType, value.Result, expansion);
od.constants.Add(ct);
}
}
// append signals
@ -708,22 +916,9 @@ public class TypeTemplate
// append properties
for (int i = 0; i < od.properties.Count; i++)
od.members.Add(od.properties[i]);
//od.isReady = true;
/*
var oo = owner.Socket.Engine.GetObjectDescription(od.GUID);
if (oo != null)
{
Console.WriteLine("Already there ! description");
return oo;
}
else
{
owner.Socket.Engine.AddObjectDescription(od);
return od;
}
*/
// append constants
for (int i = 0; i < od.constants.Count; i++)
od.members.Add(od.constants[i]);
return od;
}