2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2026-03-31 10:28:21 +00:00

No templates anymore

This commit is contained in:
2026-03-18 18:47:18 +03:00
parent 05d2c04857
commit ee3fbd116d
23 changed files with 208 additions and 956 deletions

View File

@@ -1,562 +0,0 @@
using Esiur.Core;
using Esiur.Net.EP;
using Esiur.Resource;
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Data;
using Esiur.Resource.Template;
using System.Linq;
using Esiur.Misc;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Esiur.Data;
public static class DataDeserializer
{
public static AsyncReply NullParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply(null);
}
public static AsyncReply BooleanTrueParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<bool>(true);
}
public static AsyncReply BooleanFalseParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<bool>(false);
}
public static AsyncReply NotModifiedParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<NotModified>(new NotModified());
}
public static AsyncReply ByteParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<byte>(data[offset]);
}
public static AsyncReply SByteParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<sbyte>((sbyte)data[offset]);
}
public static unsafe AsyncReply Char16Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<char>(*(char*)ptr);
}
public static AsyncReply Char8Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<char>((char)data[offset]);
}
public static unsafe AsyncReply Int16Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<short>(*(short*)ptr);
}
public static unsafe AsyncReply UInt16Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<ushort>(*(ushort*)ptr);
}
public static unsafe AsyncReply Int32Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<int>(*(int*)ptr);
}
public static unsafe AsyncReply UInt32Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<uint>(*(uint*)ptr);
}
public static unsafe AsyncReply Float32Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<float>(*(float*)ptr);
}
public static unsafe AsyncReply Float64Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<double>(*(double*)ptr);
}
public static unsafe AsyncReply Float128Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<decimal>(*(decimal*)ptr);
}
public static unsafe AsyncReply Int128Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<decimal>(*(decimal*)ptr);
}
public static unsafe AsyncReply UInt128Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<decimal>(*(decimal*)ptr);
}
public static unsafe AsyncReply Int64Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<long>(*(long*)ptr);
}
public static unsafe AsyncReply UInt64Parser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<ulong>(*(ulong*)ptr);
}
public static unsafe AsyncReply DateTimeParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return new AsyncReply<DateTime>(new DateTime(*(long*)ptr, DateTimeKind.Utc));
}
public static unsafe AsyncReply ResourceParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return connection.Fetch(*(uint*)ptr, requestSequence);
}
public static unsafe AsyncReply LocalResourceParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
fixed (byte* ptr = &data[offset])
return Warehouse.GetById(*(uint*)ptr);
}
public static unsafe AsyncReply RawDataParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<byte[]>(data.Clip(offset, length));
}
public static unsafe AsyncReply StringParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
return new AsyncReply<string>(data.GetString(offset, length));
}
public static unsafe AsyncReply RecordParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var reply = new AsyncReply<IRecord>();
var classId = data.GetUUID(offset);
offset += 16;
length -= 16;
var template = Warehouse.GetTemplateByClassId(classId, TemplateType.Record);
var initRecord = (TypeSchema template) =>
{
ListParser(data, offset, length, connection, requestSequence).Then(r =>
{
var ar = (object[])r;
if (template == null)
{
// @TODO: add parse if no template settings
reply.TriggerError(new AsyncException(ErrorType.Management, (ushort)ExceptionCode.TemplateNotFound,
"Template not found for record."));
}
else if (template.DefinedType != null)
{
var record = Activator.CreateInstance(template.DefinedType) as IRecord;
for (var i = 0; i < template.Properties.Length; i++)
{
try
{
//var v = Convert.ChangeType(ar[i], template.Properties[i].PropertyInfo.PropertyType);
var v = DC.CastConvert(ar[i], template.Properties[i].PropertyInfo.PropertyType);
template.Properties[i].PropertyInfo.SetValue(record, v);
}
catch (Exception ex)
{
Global.Log(ex);
}
}
reply.Trigger(record);
}
else
{
var record = new Record();
for (var i = 0; i < template.Properties.Length; i++)
record.Add(template.Properties[i].Name, ar[i]);
reply.Trigger(record);
}
});
};
if (template != null)
{
initRecord(template);
}
else if (connection != null)
{
// try to get the template from the other end
connection.GetTemplate(classId).Then(tmp =>
{
initRecord(tmp);
}).Error(x => reply.TriggerError(x));
}
else
{
initRecord(null);
}
return reply;
}
public static unsafe AsyncReply ConstantParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
throw new NotImplementedException();
}
public static unsafe AsyncReply EnumParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var classId = data.GetUUID(offset);
offset += 16;
var index = data[offset++];
var template = Warehouse.GetTemplateByClassId(classId, TemplateType.Enum);
if (template != null)
{
return new AsyncReply(template.Constants[index].Value);
}
else
{
var reply = new AsyncReply();
connection.GetTemplate(classId).Then(tmp =>
{
reply.Trigger(tmp.Constants[index].Value);
}).Error(x => reply.TriggerError(x));
return reply;
}
}
public static AsyncReply RecordListParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<IRecord>();
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
rt.Seal();
return rt;
}
public static AsyncReply ResourceListParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<IResource>();
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
rt.Seal();
return rt;
}
public static AsyncBag<object> ListParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<object>();
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
rt.Seal();
return rt;
}
public static AsyncReply TypedMapParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
// get key type
var (keyCs, keyRepType) = RepresentationType.Parse(data, offset);
offset += keyCs;
length -= keyCs;
var (valueCs, valueRepType) = RepresentationType.Parse(data, offset);
offset += valueCs;
length -= valueCs;
var map = (IMap)Activator.CreateInstance(typeof(Map<,>).MakeGenericType(keyRepType.GetRuntimeType(), valueRepType.GetRuntimeType()));
var rt = new AsyncReply();
var results = new AsyncBag<object>();
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
results.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
results.Seal();
results.Then(ar =>
{
for (var i = 0; i < ar.Length; i += 2)
map.Add(ar[i], ar[i + 1]);
rt.Trigger(map);
});
return rt;
}
public static AsyncReply TupleParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var results = new AsyncBag<object>();
var rt = new AsyncReply();
var tupleSize = data[offset++];
length--;
var types = new List<Type>();
for (var i = 0; i < tupleSize; i++)
{
var (cs, rep) = RepresentationType.Parse(data, offset);
types.Add(rep.GetRuntimeType());
offset += cs;
length -= cs;
}
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
results.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
results.Seal();
results.Then(ar =>
{
if (ar.Length == 2)
{
var type = typeof(ValueTuple<,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1]));
}
else if (ar.Length == 3)
{
var type = typeof(ValueTuple<,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2]));
}
else if (ar.Length == 4)
{
var type = typeof(ValueTuple<,,,>).MakeGenericType(types.ToArray());
rt.Trigger(Activator.CreateInstance(type, ar[0], ar[1], ar[2], ar[3]));
}
});
return rt;
}
public static AsyncReply TypedListParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)
{
var rt = new AsyncBag<object>();
// get the type
var (hdrCs, rep) = RepresentationType.Parse(data, offset);
offset += hdrCs;
length -= hdrCs;
var runtimeType = rep.GetRuntimeType();
rt.ArrayType = runtimeType;
while (length > 0)
{
var (cs, reply) = Codec.Parse(data, offset, connection, requestSequence);
rt.Add(reply);
if (cs > 0)
{
offset += (uint)cs;
length -= (uint)cs;
}
else
throw new Exception("Error while parsing structured data");
}
rt.Seal();
return rt;
}
public static AsyncBag<PropertyValue> PropertyValueArrayParser(byte[] data, uint offset, uint length, EpConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
{
var rt = new AsyncBag<PropertyValue>();
ListParser(data, offset, length, connection, requestSequence).Then(x =>
{
var ar = (object[])x;
var pvs = new List<PropertyValue>();
for (var i = 0; i < ar.Length; i += 3)
pvs.Add(new PropertyValue(ar[2], (ulong?)ar[0], (DateTime?)ar[1]));
rt.Trigger(pvs.ToArray());
});
return rt;
}
public static (uint, AsyncReply<PropertyValue>) PropertyValueParser(byte[] data, uint offset, EpConnection connection, uint[] requestSequence)//, bool ageIncluded = true)
{
var reply = new AsyncReply<PropertyValue>();
var age = data.GetUInt64(offset, Endian.Little);
offset += 8;
DateTime date = data.GetDateTime(offset, Endian.Little);
offset += 8;
var (valueSize, results) = Codec.Parse(data, offset, connection, requestSequence);
results.Then(value =>
{
reply.Trigger(new PropertyValue(value, age, date));
});
return (16 + valueSize, reply);
}
public static AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> HistoryParser(byte[] data, uint offset, uint length, IResource resource, EpConnection connection, uint[] requestSequence)
{
//var count = (int)toAge - (int)fromAge;
var list = new KeyList<PropertyTemplate, PropertyValue[]>();
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
var bagOfBags = new AsyncBag<PropertyValue[]>();
var ends = offset + length;
while (offset < ends)
{
var index = data[offset++];
var pt = resource.Instance.Template.GetPropertyTemplateByIndex(index);
list.Add(pt, null);
var cs = data.GetUInt32(offset, Endian.Little);
offset += 4;
var (len, pv) = PropertyValueParser(data, offset, connection, requestSequence);
bagOfBags.Add(pv);// ParsePropertyValueArray(data, offset, cs, connection));
offset += len;
}
bagOfBags.Seal();
bagOfBags.Then(x =>
{
for (var i = 0; i < list.Count; i++)
list[list.Keys.ElementAt(i)] = x[i];
reply.Trigger(list);
});
return reply;
}
}

View File

@@ -517,8 +517,8 @@ public static class DataDeserializer
public static unsafe object RecordParser(ParsedTDU tdu, Warehouse warehouse) public static unsafe object RecordParser(ParsedTDU tdu, Warehouse warehouse)
{ {
var classId = tdu.Metadata.GetUUID(0); var typeId = tdu.Metadata.GetUUID(0);
var typeDef = warehouse.GetTypeDefById(classId, TypeDefKind.Record); var typeDef = warehouse.GetTypeDefById(typeId, TypeDefKind.Record);
if (typeDef == null) if (typeDef == null)
{ {

View File

@@ -1,131 +1 @@
//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);
// 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)
// {
// bool isList = typeof(ICollection).IsAssignableFrom(type);
// var t = type switch
// {
// { IsArray: true } => type.GetElementType(),
// { IsEnum: true } => type.GetEnumUnderlyingType(),
// _ when isList => Codec.GetGenericListType(type),
// (_) => 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
// };
// 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

@@ -103,13 +103,6 @@ public class EventDef : MemberDef
.ToArray(); .ToArray();
} }
//public EventTemplate(TypeSchema template, byte index, string name, bool inherited, TRU argumentType, Map<string, string> annotations = null, bool subscribable = false)
// : base(template, index, name, inherited)
//{
// this.Annotations = annotations;
// this.Subscribable = subscribable;
// this.ArgumentType = argumentType;
//}
public static EventDef MakeEventDef(Type type, EventInfo ei, byte index, string name, TypeDef schema) public static EventDef MakeEventDef(Type type, EventInfo ei, byte index, string name, TypeDef schema)
{ {

View File

@@ -118,16 +118,6 @@ public class FunctionDef : MemberDef
return bl.ToArray(); return bl.ToArray();
} }
//public FunctionTemplate(TypeSchema template, byte index, string name, bool inherited, bool isStatic, ArgumentTemplate[] arguments, TRU returnType, Map<string, string> annotations = null)
// : base(template, index, name, inherited)
//{
// this.Arguments = arguments;
// this.ReturnType = returnType;
// this.Annotations = annotations;
// this.IsStatic = isStatic;
//}
public static FunctionDef MakeFunctionDef(Type type, MethodInfo mi, byte index, string name, TypeDef schema) public static FunctionDef MakeFunctionDef(Type type, MethodInfo mi, byte index, string name, TypeDef schema)
{ {

View File

@@ -13,20 +13,9 @@ public class MemberDef
public string Name { get; set; } public string Name { get; set; }
public bool Inherited { get; set; } public bool Inherited { get; set; }
public TypeDef Definition { get; set; } public TypeDef Definition { get; set; }
//public MemberTemplate()
//{
// Template = template;
// Index = index;
// Name = name;
// Inherited = inherited;
//}
public string Fullname => Definition.Name + "." + Name; public string Fullname => Definition.Name + "." + Name;
//public virtual byte[] Compose()
//{
// return DC.ToBytes(Name);
//}
} }

View File

@@ -14,11 +14,6 @@ using Esiur.Protocol;
namespace Esiur.Data.Types; namespace Esiur.Data.Types;
//public enum TemplateType
//{
// Resource,
// Record
//}
public class TypeDef public class TypeDef
{ {
@@ -43,8 +38,6 @@ public class TypeDef
return typeName; return typeName;
} }
// protected TemplateType
//bool isReady;
protected byte[] content; protected byte[] content;
@@ -61,17 +54,6 @@ public class TypeDef
public Type DefinedType { get; set; } public Type DefinedType { get; set; }
public Type ParentDefinedType { get; set; } public Type ParentDefinedType { get; set; }
//public MemberTemplate GetMemberTemplate(MemberInfo member)
//{
// if (member is MethodInfo)
// return GetFunctionTemplateByName(member.Name);
// else if (member is EventInfo)
// return GetEventTemplateByName(member.Name);
// else if (member is PropertyInfo)
// return GetPropertyTemplateByName(member.Name);
// else
// return null;
//}
public EventDef GetEventDefByName(string eventName) public EventDef GetEventDefByName(string eventName)
{ {
@@ -137,10 +119,6 @@ public class TypeDef
get { return typeName; } get { return typeName; }
} }
//public MemberTemplate[] Methods
//{
// get { return members.ToArray(); }
//}
public FunctionDef[] Functions public FunctionDef[] Functions
{ {
@@ -166,9 +144,9 @@ public class TypeDef
public static UUID GetTypeUUID(Type type) public static UUID GetTypeUUID(Type type)
{ {
var attr = type.GetCustomAttribute<ClassIdAttribute>(); var attr = type.GetCustomAttribute<TypeIdAttribute>();
if (attr != null) if (attr != null)
return attr.ClassId; return attr.Id;
var tn = Encoding.UTF8.GetBytes(GetTypeName(type)); var tn = Encoding.UTF8.GetBytes(GetTypeName(type));
var hash = SHA256.Create().ComputeHash(tn).Clip(0, 16); var hash = SHA256.Create().ComputeHash(tn).Clip(0, 16);
@@ -245,11 +223,11 @@ public class TypeDef
// Get parents // Get parents
while (parentType != null) while (parentType != null)
{ {
var parentTemplate = warehouse.GetTypeDefByType(parentType); var parentTypeDef = warehouse.GetTypeDefByType(parentType);
if (parentTemplate != null) if (parentTypeDef != null)
{ {
list.Add(parentTemplate); list.Add(parentTypeDef);
parentType = parentTemplate.ParentDefinedType; parentType = parentTypeDef.ParentDefinedType;
} }
} }
@@ -257,18 +235,16 @@ public class TypeDef
foreach (var f in sch.functions) foreach (var f in sch.functions)
{ {
var functionReturnTypes = GetDistributedTypes(f.MethodInfo.ReturnType); var functionReturnTypes = GetDistributedTypes(f.MethodInfo.ReturnType);
//.Select(x => Warehouse.GetTemplateByType(x))
//.Where(x => x != null && !bag.Contains(x))
foreach (var functionReturnType in functionReturnTypes) foreach (var functionReturnType in functionReturnTypes)
{ {
var functionReturnTemplate = warehouse.GetTypeDefByType(functionReturnType); var functionReturnTypeDef = warehouse.GetTypeDefByType(functionReturnType);
if (functionReturnTemplate != null) if (functionReturnTypeDef != null)
{ {
if (!bag.Contains(functionReturnTemplate)) if (!bag.Contains(functionReturnTypeDef))
{ {
list.Add(functionReturnTemplate); list.Add(functionReturnTypeDef);
getDependenciesFunc(functionReturnTemplate, bag); getDependenciesFunc(functionReturnTypeDef, bag);
} }
} }
} }
@@ -326,13 +302,13 @@ public class TypeDef
foreach (var propertyType in propertyTypes) foreach (var propertyType in propertyTypes)
{ {
var propertyTemplate = warehouse.GetTypeDefByType(propertyType); var propertyTypeDef = warehouse.GetTypeDefByType(propertyType);
if (propertyTemplate != null) if (propertyTypeDef != null)
{ {
if (!bag.Contains(propertyTemplate)) if (!bag.Contains(propertyTypeDef))
{ {
bag.Add(propertyTemplate); bag.Add(propertyTypeDef);
getDependenciesFunc(propertyTemplate, bag); getDependenciesFunc(propertyTypeDef, bag);
} }
} }
} }
@@ -345,14 +321,14 @@ public class TypeDef
foreach (var eventType in eventTypes) foreach (var eventType in eventTypes)
{ {
var eventTemplate = warehouse.GetTypeDefByType(eventType); var eventTypeDef = warehouse.GetTypeDefByType(eventType);
if (eventTemplate != null) if (eventTypeDef != null)
{ {
if (!bag.Contains(eventTemplate)) if (!bag.Contains(eventTypeDef))
{ {
bag.Add(eventTemplate); bag.Add(eventTypeDef);
getDependenciesFunc(eventTemplate, bag); getDependenciesFunc(eventTypeDef, bag);
} }
} }
} }

View File

@@ -58,14 +58,12 @@
<ItemGroup> <ItemGroup>
<Compile Remove="Data\DataDeserializer - Copy.cs" />
<Compile Remove="Data\NullabilityInfo.cs" /> <Compile Remove="Data\NullabilityInfo.cs" />
<Compile Remove="Data\NullabilityInfoContext.cs" /> <Compile Remove="Data\NullabilityInfoContext.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="Data\DataDeserializer - Copy.cs" />
<None Include="Data\NullabilityInfo.cs" /> <None Include="Data\NullabilityInfo.cs" />
<None Include="Data\NullabilityInfoContext.cs" /> <None Include="Data\NullabilityInfoContext.cs" />
<None Include="Data\Types\ArgumentDef.cs" /> <None Include="Data\Types\ArgumentDef.cs" />

View File

@@ -186,9 +186,9 @@ partial class EpConnection
} }
public AsyncReply StaticCall(UUID classId, byte index, object parameters) public AsyncReply StaticCall(UUID typeId, byte index, object parameters)
{ {
return SendRequest(EpPacketRequest.StaticCall, classId, index, parameters); return SendRequest(EpPacketRequest.StaticCall, typeId, index, parameters);
} }
public AsyncReply Call(string procedureCall, params object[] parameters) public AsyncReply Call(string procedureCall, params object[] parameters)
@@ -808,16 +808,16 @@ partial class EpConnection
return; return;
} }
if (r.Instance.Applicable(session, ActionType.ViewTemplate, null) == Ruling.Denied) if (r.Instance.Applicable(session, ActionType.ViewTypeDef, null) == Ruling.Denied)
{ {
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.NotAllowed); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.NotAllowed);
return; return;
} }
var templates = TypeDef.GetDependencies(r.Instance.Definition, Instance.Warehouse); var typeDefs = TypeDef.GetDependencies(r.Instance.Definition, Instance.Warehouse);
// Send // Send
SendReply(EpPacketReply.Completed, callback, templates.Select(x => x.Content).ToArray()); SendReply(EpPacketReply.Completed, callback, typeDefs.Select(x => x.Content).ToArray());
}; };
@@ -851,9 +851,9 @@ partial class EpConnection
var (_, value) = Codec.ParseSync(dataType, Instance.Warehouse); var (_, value) = Codec.ParseSync(dataType, Instance.Warehouse);
var classId = (UUID)value; var typeId = (UUID)value;
var t = Instance.Warehouse.GetTypeDefById(classId); var t = Instance.Warehouse.GetTypeDefById(typeId);
if (t != null) if (t != null)
{ {
@@ -1018,7 +1018,7 @@ partial class EpConnection
// return; // return;
//} //}
InvokeFunction(call.Value.Template, callback, results, EpPacketRequest.ProcedureCall, call.Value.Delegate.Target); InvokeFunction(call.Value.Definition, callback, results, EpPacketRequest.ProcedureCall, call.Value.Delegate.Target);
}).Error(x => }).Error(x =>
{ {
@@ -1033,7 +1033,7 @@ partial class EpConnection
this.Socket.Unhold(); this.Socket.Unhold();
// @TODO: Make managers for procedure calls // @TODO: Make managers for procedure calls
InvokeFunction(call.Value.Template, callback, parsed, EpPacketRequest.ProcedureCall, call.Value.Delegate.Target); InvokeFunction(call.Value.Definition, callback, parsed, EpPacketRequest.ProcedureCall, call.Value.Delegate.Target);
} }
} }
@@ -1042,29 +1042,29 @@ partial class EpConnection
var (offset, length, args) = DataDeserializer.LimitedCountListParser(data, dataType.Offset, var (offset, length, args) = DataDeserializer.LimitedCountListParser(data, dataType.Offset,
dataType.ContentLength, Instance.Warehouse, 2); dataType.ContentLength, Instance.Warehouse, 2);
var classId = new UUID((byte[])args[0]); var typeId = new UUID((byte[])args[0]);
var index = (byte)args[1]; var index = (byte)args[1];
var template = Instance.Warehouse.GetTypeDefById(classId); var typeDef = Instance.Warehouse.GetTypeDefById(typeId);
if (template == null) if (typeDef == null)
{ {
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TypeDefNotFound); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.TypeDefNotFound);
return; return;
} }
var ft = template.GetFunctionDefByIndex(index); var fd = typeDef.GetFunctionDefByIndex(index);
if (ft == null) if (fd == null)
{ {
// no function at this index // no function at this index
SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound); SendError(ErrorType.Management, callback, (ushort)ExceptionCode.MethodNotFound);
return; return;
} }
var fi = ft.MethodInfo; var fi = fd.MethodInfo;
if (fi == null) if (fi == null)
{ {
@@ -1093,7 +1093,7 @@ partial class EpConnection
// return; // return;
//} //}
InvokeFunction(ft, callback, results, EpPacketRequest.StaticCall, null); InvokeFunction(fd, callback, results, EpPacketRequest.StaticCall, null);
}).Error(x => }).Error(x =>
{ {
@@ -1110,7 +1110,7 @@ partial class EpConnection
// @TODO: Make managers for static calls // @TODO: Make managers for static calls
InvokeFunction(ft, callback, parsed, EpPacketRequest.StaticCall, null); InvokeFunction(fd, callback, parsed, EpPacketRequest.StaticCall, null);
} }
} }
@@ -1715,9 +1715,9 @@ partial class EpConnection
/// <summary> /// <summary>
/// Get the TypeSchema for a given class Id. /// Get the TypeSchema for a given type Id.
/// </summary> /// </summary>
/// <param name="classId">Class GUID.</param> /// <param name="typeId">Type UUID.</param>
/// <returns>TypeSchema.</returns> /// <returns>TypeSchema.</returns>
public AsyncReply<TypeDef> GetTypeDefById(UUID typeId) public AsyncReply<TypeDef> GetTypeDefById(UUID typeId)
{ {
@@ -1749,9 +1749,9 @@ partial class EpConnection
public AsyncReply<TypeDef> GetTypeDefByName(string typeName) public AsyncReply<TypeDef> GetTypeDefByName(string typeName)
{ {
var template = typeDefs.Values.FirstOrDefault(x => x.Name == typeName); var typeDef = typeDefs.Values.FirstOrDefault(x => x.Name == typeName);
if (template != null) if (typeDef != null)
return new AsyncReply<TypeDef>(template); return new AsyncReply<TypeDef>(typeDef);
if (typeDefsByNameRequests.ContainsKey(typeName)) if (typeDefsByNameRequests.ContainsKey(typeName))
return typeDefsByNameRequests[typeName]; return typeDefsByNameRequests[typeName];
@@ -1844,8 +1844,7 @@ partial class EpConnection
/// <summary> /// <summary>
/// Fetch a resource from the other end /// Fetch a resource from the other end
/// </summary> /// </summary>
/// <param name="classId">Class GUID</param> /// <param name="id">Resource Id</param>
/// <param name="id">Resource Id</param>Guid classId
/// <returns>DistributedResource</returns> /// <returns>DistributedResource</returns>
public AsyncReply<EpResource> Fetch(uint id, uint[] requestSequence) public AsyncReply<EpResource> Fetch(uint id, uint[] requestSequence)
{ {
@@ -1901,7 +1900,7 @@ partial class EpConnection
return; return;
} }
// ClassId, Age, Link, Hops, PropertyValue[] // TypeId, Age, Link, Hops, PropertyValue[]
var args = (object[])result; var args = (object[])result;
var typeId = (UUID)args[0]; var typeId = (UUID)args[0];
var age = Convert.ToUInt64(args[1]); var age = Convert.ToUInt64(args[1]);
@@ -1957,7 +1956,7 @@ partial class EpConnection
{ {
GetTypeDefById(typeId).Then((tmp) => GetTypeDefById(typeId).Then((tmp) =>
{ {
// ClassId, ResourceAge, ResourceLink, Content // typeId, ResourceAge, ResourceLink, Content
if (resource == null) if (resource == null)
{ {
dr.ResourceDefinition = tmp; dr.ResourceDefinition = tmp;
@@ -2024,7 +2023,7 @@ partial class EpConnection
/// Create a new resource. /// Create a new resource.
/// </summary> /// </summary>
/// <param name="path">Resource path.</param> /// <param name="path">Resource path.</param>
/// <param name="type">Type template.</param> /// <param name="type">Type definition.</param>
/// <param name="properties">Values for the resource properties.</param> /// <param name="properties">Values for the resource properties.</param>
/// <param name="attributes">Resource attributes.</param> /// <param name="attributes">Resource attributes.</param>
/// <returns>New resource instance</returns> /// <returns>New resource instance</returns>
@@ -2097,13 +2096,13 @@ partial class EpConnection
{ {
SendNotification(EpPacketNotification.PropertyModified, SendNotification(EpPacketNotification.PropertyModified,
info.Resource.Instance.Id, info.Resource.Instance.Id,
info.PropertyTemplate.Index, info.PropertyDef.Index,
info.Value); info.Value);
} }
private void Instance_CustomEventOccurred(CustomEventOccurredInfo info) private void Instance_CustomEventOccurred(CustomEventOccurredInfo info)
{ {
if (info.EventTemplate.Subscribable) if (info.EventDef.Subscribable)
{ {
lock (subscriptionsLock) lock (subscriptionsLock)
{ {
@@ -2111,7 +2110,7 @@ partial class EpConnection
if (!subscriptions.ContainsKey(info.Resource)) if (!subscriptions.ContainsKey(info.Resource))
return; return;
if (!subscriptions[info.Resource].Contains(info.EventTemplate.Index)) if (!subscriptions[info.Resource].Contains(info.EventDef.Index))
return; return;
} }
} }
@@ -2119,14 +2118,14 @@ partial class EpConnection
if (!info.Receivers(this.session)) if (!info.Receivers(this.session))
return; return;
if (info.Resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, info.EventTemplate, info.Issuer) == Ruling.Denied) if (info.Resource.Instance.Applicable(this.session, ActionType.ReceiveEvent, info.EventDef, info.Issuer) == Ruling.Denied)
return; return;
// compose the packet // compose the packet
SendNotification(EpPacketNotification.EventOccurred, SendNotification(EpPacketNotification.EventOccurred,
info.Resource.Instance.Id, info.Resource.Instance.Id,
info.EventTemplate.Index, info.EventDef.Index,
info.Value); info.Value);
} }

View File

@@ -142,7 +142,6 @@ public class EpResource : DynamicObject, IResource, INotifyPropertyChanged, IDyn
/// Create a new distributed resource. /// Create a new distributed resource.
/// </summary> /// </summary>
/// <param name="connection">Connection responsible for the distributed resource.</param> /// <param name="connection">Connection responsible for the distributed resource.</param>
/// <param name="template">Resource template.</param>
/// <param name="instanceId">Instance Id given by the other end.</param> /// <param name="instanceId">Instance Id given by the other end.</param>
/// <param name="age">Resource age.</param> /// <param name="age">Resource age.</param>
public EpResource(EpConnection connection, uint instanceId, ulong age, string link) public EpResource(EpConnection connection, uint instanceId, ulong age, string link)
@@ -206,7 +205,7 @@ public class EpResource : DynamicObject, IResource, INotifyPropertyChanged, IDyn
var ft = Instance.Definition.GetFunctionDefByIndex(index); var ft = Instance.Definition.GetFunctionDefByIndex(index);
if (ft == null) if (ft == null)
throw new Exception("Function template not found."); throw new Exception("Function definition not found.");
if (ft.IsStatic) if (ft.IsStatic)
return connection.StaticCall(Instance.Definition.Id, index, args); return connection.StaticCall(Instance.Definition.Id, index, args);

View File

@@ -170,14 +170,14 @@ public class EpServer : NetworkServer<EpConnection>, IResource
public struct CallInfo public struct CallInfo
{ {
public FunctionDef Template; public FunctionDef Definition;
public Delegate Delegate; public Delegate Delegate;
} }
public EpServer MapCall(string call, Delegate handler) public EpServer MapCall(string call, Delegate handler)
{ {
var ft = FunctionDef.MakeFunctionDef(null, handler.Method, 0, call, null); var fd = FunctionDef.MakeFunctionDef(null, handler.Method, 0, call, null);
Calls.Add(call, new CallInfo() { Delegate = handler, Template = ft }); Calls.Add(call, new CallInfo() { Delegate = handler, Definition = fd });
return this; return this;
} }

View File

@@ -44,7 +44,7 @@ namespace Esiur.Proxy
.Collect() .Collect()
.Select( (list, y) => MergePartials(list)); .Select( (list, y) => MergePartials(list));
// 4) Generate: A) remote templates (from ImportAttribute URLs) // 4) Generate: A) remote TypeDefs (from ImportAttribute URLs)
context.RegisterSourceOutput(importUrls, (spc, urls) => context.RegisterSourceOutput(importUrls, (spc, urls) =>
{ {
if (urls.Length == 0) return; if (urls.Length == 0) return;
@@ -57,9 +57,9 @@ namespace Esiur.Proxy
var parts = TypeDefGenerator.urlRegex.Split(path); var parts = TypeDefGenerator.urlRegex.Split(path);
var con = Warehouse.Default.Get<EpConnection>($"{parts[1]}://{parts[2]}").Wait(20000); var con = Warehouse.Default.Get<EpConnection>($"{parts[1]}://{parts[2]}").Wait(20000);
var templates = con.GetLinkDefinitions(parts[3]).Wait(60000); var typeDefs = con.GetLinkDefinitions(parts[3]).Wait(60000);
EmitTemplates(spc, templates); EmitTypeDefs(spc, typeDefs);
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -222,26 +222,26 @@ $@" public partial class {ci.Name} : IResource {{
} }
// === Emission helpers (ported from your original generator) === // === Emission helpers (ported from your original generator) ===
private static void EmitTemplates(SourceProductionContext spc, TypeDef[] templates) private static void EmitTypeDefs(SourceProductionContext spc, TypeDef[] typeDefs)
{ {
foreach (var tmp in templates) foreach (var typeDef in typeDefs)
{ {
if (tmp.Kind == TypeDefKind.Resource) if (typeDef.Kind == TypeDefKind.Resource)
{ {
var source = TypeDefGenerator.GenerateClass(tmp, templates, false); var source = TypeDefGenerator.GenerateClass(typeDef, typeDefs, false);
spc.AddSource(tmp.Name + ".g.cs", source); spc.AddSource(typeDef.Name + ".g.cs", source);
} }
else if (tmp.Kind == TypeDefKind.Record) else if (typeDef.Kind == TypeDefKind.Record)
{ {
var source = TypeDefGenerator.GenerateRecord(tmp, templates); var source = TypeDefGenerator.GenerateRecord(typeDef, typeDefs);
spc.AddSource(tmp.Name + ".g.cs", source); spc.AddSource(typeDef.Name + ".g.cs", source);
} }
} }
var typesFile = "using System; \r\n namespace Esiur { public static class Generated { public static Type[] Resources {get;} = new Type[] { " + var typesFile = "using System; \r\n namespace Esiur { public static class Generated { public static Type[] Resources {get;} = new Type[] { " +
string.Join(",", templates.Where(x => x.Kind == TypeDefKind.Resource).Select(x => $"typeof({x.Name})")) string.Join(",", typeDefs.Where(x => x.Kind == TypeDefKind.Resource).Select(x => $"typeof({x.Name})"))
+ " }; \r\n public static Type[] Records { get; } = new Type[] { " + + " }; \r\n public static Type[] Records { get; } = new Type[] { " +
string.Join(",", templates.Where(x => x.Kind == TypeDefKind.Record).Select(x => $"typeof({x.Name})")) string.Join(",", typeDefs.Where(x => x.Kind == TypeDefKind.Record).Select(x => $"typeof({x.Name})"))
+ " }; " + + " }; " +
"\r\n } \r\n}"; "\r\n } \r\n}";

View File

@@ -61,7 +61,7 @@ public static class TypeDefGenerator
} }
internal static string GenerateRecord(TypeDef typeDef, TypeDef[] templates) internal static string GenerateRecord(TypeDef typeDef, TypeDef[] typeDefs)
{ {
var cls = typeDef.Name.Split('.'); var cls = typeDef.Name.Split('.');
@@ -82,13 +82,13 @@ public static class TypeDefGenerator
} }
} }
rt.AppendLine($"[ClassId(\"{typeDef.Id.Data.ToHex(0, 16, null)}\")]"); rt.AppendLine($"[TypeId(\"{typeDef.Id.Data.ToHex(0, 16, null)}\")]");
rt.AppendLine($"[Export] public class {className} : IRecord {{"); rt.AppendLine($"[Export] public class {className} : IRecord {{");
foreach (var p in typeDef.Properties) foreach (var p in typeDef.Properties)
{ {
var ptTypeName = GetTypeName(p.ValueType, templates); var pdTypeName = GetTypeName(p.ValueType, typeDefs);
if (p.Annotations != null) if (p.Annotations != null)
@@ -100,7 +100,7 @@ public static class TypeDefGenerator
} }
rt.AppendLine($"public {ptTypeName} {p.Name} {{ get; set; }}"); rt.AppendLine($"public {pdTypeName} {p.Name} {{ get; set; }}");
rt.AppendLine(); rt.AppendLine();
} }
@@ -109,9 +109,9 @@ public static class TypeDefGenerator
return rt.ToString(); return rt.ToString();
} }
internal static string GenerateEnum(TypeDef template, TypeDef[] templates) internal static string GenerateEnum(TypeDef typeDef, TypeDef[] typeDefs)
{ {
var cls = template.Name.Split('.'); var cls = typeDef.Name.Split('.');
var nameSpace = string.Join(".", cls.Take(cls.Length - 1)); var nameSpace = string.Join(".", cls.Take(cls.Length - 1));
var className = cls.Last(); var className = cls.Last();
@@ -121,18 +121,18 @@ public static class TypeDefGenerator
rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Protocol;"); rt.AppendLine("using System;\r\nusing Esiur.Resource;\r\nusing Esiur.Core;\r\nusing Esiur.Data;\r\nusing Esiur.Protocol;");
rt.AppendLine($"namespace {nameSpace} {{"); rt.AppendLine($"namespace {nameSpace} {{");
if (template.Annotations != null) if (typeDef.Annotations != null)
{ {
foreach (var ann in template.Annotations) foreach (var ann in typeDef.Annotations)
{ {
rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]"); rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]");
} }
} }
rt.AppendLine($"[ClassId(\"{template.Id.Data.ToHex(0, 16, null)}\")]"); rt.AppendLine($"[TypeId(\"{typeDef.Id.Data.ToHex(0, 16, null)}\")]");
rt.AppendLine($"[Export] public enum {className} {{"); rt.AppendLine($"[Export] public enum {className} {{");
rt.AppendLine(String.Join(",\r\n", template.Constants.Select(x => $"{x.Name}={x.Value}"))); rt.AppendLine(String.Join(",\r\n", typeDef.Constants.Select(x => $"{x.Name}={x.Value}")));
rt.AppendLine("\r\n}\r\n}"); rt.AppendLine("\r\n}\r\n}");
@@ -140,34 +140,34 @@ public static class TypeDefGenerator
} }
static string GetTypeName(TRU representationType, TypeDef[] templates) static string GetTypeName(TRU tru, TypeDef[] typeDefs)
{ {
string name; string name;
if (representationType.Identifier == TRUIdentifier.TypedResource)// == DataType.Resource) if (tru.Identifier == TRUIdentifier.TypedResource)// == DataType.Resource)
name = templates.First(x => x.Id == representationType.UUID && (x.Kind == TypeDefKind.Resource)).Name; name = typeDefs.First(x => x.Id == tru.UUID && (x.Kind == TypeDefKind.Resource)).Name;
else if (representationType.Identifier == TRUIdentifier.TypedRecord) else if (tru.Identifier == TRUIdentifier.TypedRecord)
name = templates.First(x => x.Id == representationType.UUID && x.Kind == TypeDefKind.Record).Name; name = typeDefs.First(x => x.Id == tru.UUID && x.Kind == TypeDefKind.Record).Name;
else if (representationType.Identifier == TRUIdentifier.Enum) else if (tru.Identifier == TRUIdentifier.Enum)
name = templates.First(x => x.Id == representationType.UUID && x.Kind == TypeDefKind.Enum).Name; name = typeDefs.First(x => x.Id == tru.UUID && x.Kind == TypeDefKind.Enum).Name;
else if (representationType.Identifier == TRUIdentifier.TypedList) else if (tru.Identifier == TRUIdentifier.TypedList)
name = GetTypeName(representationType.SubTypes[0], templates) + "[]"; name = GetTypeName(tru.SubTypes[0], typeDefs) + "[]";
else if (representationType.Identifier == TRUIdentifier.TypedMap) else if (tru.Identifier == TRUIdentifier.TypedMap)
name = "Map<" + GetTypeName(representationType.SubTypes[0], templates) name = "Map<" + GetTypeName(tru.SubTypes[0], typeDefs)
+ "," + GetTypeName(representationType.SubTypes[1], templates) + "," + GetTypeName(tru.SubTypes[1], typeDefs)
+ ">"; + ">";
else if (representationType.Identifier == TRUIdentifier.Tuple2 || else if (tru.Identifier == TRUIdentifier.Tuple2 ||
representationType.Identifier == TRUIdentifier.Tuple3 || tru.Identifier == TRUIdentifier.Tuple3 ||
representationType.Identifier == TRUIdentifier.Tuple4 || tru.Identifier == TRUIdentifier.Tuple4 ||
representationType.Identifier == TRUIdentifier.Tuple5 || tru.Identifier == TRUIdentifier.Tuple5 ||
representationType.Identifier == TRUIdentifier.Tuple6 || tru.Identifier == TRUIdentifier.Tuple6 ||
representationType.Identifier == TRUIdentifier.Tuple7) tru.Identifier == TRUIdentifier.Tuple7)
name = "(" + String.Join(",", representationType.SubTypes.Select(x => GetTypeName(x, templates))) name = "(" + String.Join(",", tru.SubTypes.Select(x => GetTypeName(x, typeDefs)))
+ ")"; + ")";
else else
{ {
name = representationType.Identifier switch name = tru.Identifier switch
{ {
TRUIdentifier.Dynamic => "object", TRUIdentifier.Dynamic => "object",
TRUIdentifier.Bool => "bool", TRUIdentifier.Bool => "bool",
@@ -193,10 +193,10 @@ public static class TypeDefGenerator
}; };
} }
return (representationType.Nullable) ? name + "?" : name; return (tru.Nullable) ? name + "?" : name;
} }
public static string GetTemplate(string url, string dir = null, bool tempDir = false, string username = null, string password = null, bool asyncSetters = false) public static string GetTypes(string url, string dir = null, bool tempDir = false, string username = null, string password = null, bool asyncSetters = false)
{ {
try try
{ {
@@ -215,7 +215,7 @@ public static class TypeDefGenerator
if (string.IsNullOrEmpty(dir)) if (string.IsNullOrEmpty(dir))
dir = path[2].Replace(":", "_"); dir = path[2].Replace(":", "_");
var templates = con.GetLinkDefinitions(path[3]).Wait(60000); var typeDefs = con.GetLinkDefinitions(path[3]).Wait(60000);
// no longer needed // no longer needed
Warehouse.Default.Remove(con); Warehouse.Default.Remove(con);
@@ -231,22 +231,22 @@ public static class TypeDefGenerator
} }
// make sources // make sources
foreach (var tmp in templates) foreach (var td in typeDefs)
{ {
if (tmp.Kind == TypeDefKind.Resource) if (td.Kind == TypeDefKind.Resource)
{ {
var source = GenerateClass(tmp, templates, asyncSetters); var source = GenerateClass(td, typeDefs, asyncSetters);
File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + tmp.Name + ".g.cs", source); File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + td.Name + ".g.cs", source);
} }
else if (tmp.Kind == TypeDefKind.Record) else if (td.Kind == TypeDefKind.Record)
{ {
var source = GenerateRecord(tmp, templates); var source = GenerateRecord(td, typeDefs);
File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + tmp.Name + ".g.cs", source); File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + td.Name + ".g.cs", source);
} }
else if (tmp.Kind == TypeDefKind.Enum) else if (td.Kind == TypeDefKind.Enum)
{ {
var source = GenerateEnum(tmp, templates); var source = GenerateEnum(td, typeDefs);
File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + tmp.Name + ".g.cs", source); File.WriteAllText(dstDir.FullName + Path.DirectorySeparatorChar + td.Name + ".g.cs", source);
} }
} }
@@ -256,13 +256,13 @@ public static class TypeDefGenerator
namespace Esiur { namespace Esiur {
public static class Generated { public static class Generated {
public static Type[] Resources {get;} = new Type[] { " + public static Type[] Resources {get;} = new Type[] { " +
string.Join(",", templates.Where(x => x.Kind == TypeDefKind.Resource).Select(x => $"typeof({x.Name})")) string.Join(",", typeDefs.Where(x => x.Kind == TypeDefKind.Resource).Select(x => $"typeof({x.Name})"))
+ @" }; + @" };
public static Type[] Records { get; } = new Type[] { " + public static Type[] Records { get; } = new Type[] { " +
string.Join(",", templates.Where(x => x.Kind == TypeDefKind.Record).Select(x => $"typeof({x.Name})")) string.Join(",", typeDefs.Where(x => x.Kind == TypeDefKind.Record).Select(x => $"typeof({x.Name})"))
+ @" }; + @" };
public static Type[] Enums { get; } = new Type[] { " + public static Type[] Enums { get; } = new Type[] { " +
string.Join(",", templates.Where(x => x.Kind == TypeDefKind.Enum).Select(x => $"typeof({x.Name})")) string.Join(",", typeDefs.Where(x => x.Kind == TypeDefKind.Enum).Select(x => $"typeof({x.Name})"))
+ @" };" + + @" };" +
"\r\n } \r\n}"; "\r\n } \r\n}";
@@ -279,9 +279,9 @@ public static class TypeDefGenerator
} }
} }
internal static string GenerateClass(TypeDef template, TypeDef[] templates, bool asyncSetters) internal static string GenerateClass(TypeDef typeDef, TypeDef[] typeDefs, bool asyncSetters)
{ {
var cls = template.Name.Split('.'); var cls = typeDef.Name.Split('.');
var nameSpace = string.Join(".", cls.Take(cls.Length - 1)); var nameSpace = string.Join(".", cls.Take(cls.Length - 1));
var className = cls.Last(); var className = cls.Last();
@@ -293,33 +293,33 @@ public static class TypeDefGenerator
rt.AppendLine($"namespace {nameSpace} {{"); rt.AppendLine($"namespace {nameSpace} {{");
if (template.Annotations != null) if (typeDef.Annotations != null)
{ {
foreach (var ann in template.Annotations) foreach (var ann in typeDef.Annotations)
{ {
rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]"); rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]");
} }
} }
rt.AppendLine($"[ClassId(\"{template.Id.Data.ToHex(0, 16, null)}\")]"); rt.AppendLine($"[TypeId(\"{typeDef.Id.Data.ToHex(0, 16, null)}\")]");
// extends // extends
if (template.ParentId == null) if (typeDef.ParentId == null)
rt.AppendLine($"public class {className} : EpResource {{"); rt.AppendLine($"public class {className} : EpResource {{");
else else
rt.AppendLine($"public class {className} : {templates.First(x => x.Id == template.ParentId && x.Kind == TypeDefKind.Resource).Name} {{"); rt.AppendLine($"public class {className} : {typeDefs.First(x => x.Id == typeDef.ParentId && x.Kind == TypeDefKind.Resource).Name} {{");
rt.AppendLine($"public {className}(EpConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {{}}"); rt.AppendLine($"public {className}(EpConnection connection, uint instanceId, ulong age, string link) : base(connection, instanceId, age, link) {{}}");
rt.AppendLine($"public {className}() {{}}"); rt.AppendLine($"public {className}() {{}}");
foreach (var f in template.Functions) foreach (var f in typeDef.Functions)
{ {
if (f.Inherited) if (f.Inherited)
continue; continue;
var rtTypeName = GetTypeName(f.ReturnType, templates); var rtTypeName = GetTypeName(f.ReturnType, typeDefs);
var positionalArgs = f.Arguments.Where((x) => !x.Optional).ToArray(); var positionalArgs = f.Arguments.Where((x) => !x.Optional).ToArray();
var optionalArgs = f.Arguments.Where((x) => x.Optional).ToArray(); var optionalArgs = f.Arguments.Where((x) => x.Optional).ToArray();
@@ -339,11 +339,11 @@ public static class TypeDefGenerator
if (positionalArgs.Length > 0) if (positionalArgs.Length > 0)
rt.Append(", " + rt.Append(", " +
String.Join(", ", positionalArgs.Select((a) => GetTypeName(a.Type, templates) + " " + a.Name))); String.Join(", ", positionalArgs.Select((a) => GetTypeName(a.Type, typeDefs) + " " + a.Name)));
if (optionalArgs.Length > 0) if (optionalArgs.Length > 0)
rt.Append(", " + rt.Append(", " +
String.Join(", ", optionalArgs.Select((a) => GetTypeName(a.Type.ToNullable(), templates) + " " + a.Name + " = null"))); String.Join(", ", optionalArgs.Select((a) => GetTypeName(a.Type.ToNullable(), typeDefs) + " " + a.Name + " = null")));
} }
else else
@@ -352,14 +352,14 @@ public static class TypeDefGenerator
if (positionalArgs.Length > 0) if (positionalArgs.Length > 0)
rt.Append( rt.Append(
String.Join(", ", positionalArgs.Select((a) => GetTypeName(a.Type, templates) + " " + a.Name))); String.Join(", ", positionalArgs.Select((a) => GetTypeName(a.Type, typeDefs) + " " + a.Name)));
if (optionalArgs.Length > 0) if (optionalArgs.Length > 0)
{ {
if (positionalArgs.Length > 0) rt.Append(","); if (positionalArgs.Length > 0) rt.Append(",");
rt.Append( rt.Append(
String.Join(", ", optionalArgs.Select((a) => GetTypeName(a.Type.ToNullable(), templates) + " " + a.Name + " = null"))); String.Join(", ", optionalArgs.Select((a) => GetTypeName(a.Type.ToNullable(), typeDefs) + " " + a.Name + " = null")));
} }
} }
@@ -378,7 +378,7 @@ public static class TypeDefGenerator
rt.AppendLine($"var rt = new AsyncReply<{rtTypeName}>();"); rt.AppendLine($"var rt = new AsyncReply<{rtTypeName}>();");
if (f.IsStatic) if (f.IsStatic)
rt.AppendLine($"connection.StaticCall(Guid.Parse(\"{template.Id.ToString()}\"), {f.Index}, args)"); rt.AppendLine($"connection.StaticCall(Guid.Parse(\"{typeDef.Id.ToString()}\"), {f.Index}, args)");
else else
rt.AppendLine($"_Invoke({f.Index}, args)"); rt.AppendLine($"_Invoke({f.Index}, args)");
@@ -389,7 +389,7 @@ public static class TypeDefGenerator
} }
foreach (var p in template.Properties) foreach (var p in typeDef.Properties)
{ {
if (p.Inherited) if (p.Inherited)
continue; continue;
@@ -402,7 +402,7 @@ public static class TypeDefGenerator
} }
} }
var ptTypeName = GetTypeName(p.ValueType, templates); var ptTypeName = GetTypeName(p.ValueType, typeDefs);
rt.AppendLine($"[Export] public {ptTypeName} {p.Name} {{"); rt.AppendLine($"[Export] public {ptTypeName} {p.Name} {{");
rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];"); rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];");
if (asyncSetters) if (asyncSetters)
@@ -412,7 +412,7 @@ public static class TypeDefGenerator
rt.AppendLine("}"); rt.AppendLine("}");
} }
foreach (var c in template.Constants) foreach (var c in typeDef.Constants)
{ {
if (c.Inherited) if (c.Inherited)
continue; continue;
@@ -423,12 +423,12 @@ public static class TypeDefGenerator
rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]"); rt.AppendLine($"[Annotation({ToLiteral(ann.Key)}, {ToLiteral(ann.Value)})]");
} }
var ctTypeName = GetTypeName(c.ValueType, templates); var ctTypeName = GetTypeName(c.ValueType, typeDefs);
rt.AppendLine($"[Export] public const {ctTypeName} {c.Name} = {c.Value};"); rt.AppendLine($"[Export] public const {ctTypeName} {c.Name} = {c.Value};");
} }
if (template.Events.Length > 0) if (typeDef.Events.Length > 0)
{ {
rt.AppendLine("protected override void _EmitEventByIndex(byte index, object args) {"); rt.AppendLine("protected override void _EmitEventByIndex(byte index, object args) {");
@@ -436,9 +436,9 @@ public static class TypeDefGenerator
var eventsList = new StringBuilder(); var eventsList = new StringBuilder();
foreach (var e in template.Events) foreach (var e in typeDef.Events)
{ {
var etTypeName = GetTypeName(e.ArgumentType, templates); var etTypeName = GetTypeName(e.ArgumentType, typeDefs);
rt.AppendLine($"case {e.Index}: {e.Name}?.Invoke(({etTypeName})args); break;"); rt.AppendLine($"case {e.Index}: {e.Name}?.Invoke(({etTypeName})args); break;");

View File

@@ -143,10 +143,10 @@ In the above client example, we relied on Esiur support for dynamic objects, but
Esiur has a self describing feature which comes with every language it supports, allowing the developer to fetch and generate classes that match the ones on the other side (i.e. server). Esiur has a self describing feature which comes with every language it supports, allowing the developer to fetch and generate classes that match the ones on the other side (i.e. server).
After installing the Esiur nuget package a new command is added to Visual Studio Package Console Manager that is called ***Get-Template***, which generates client side classes for robust static typing. After installing the Esiur nuget package a new command is added to Visual Studio Package Console Manager that is called ***Get-Types***, which generates client side classes for robust static typing.
```ps ```ps
Get-Template EP://localhost/sys/hello Get-Types ep://localhost/sys/hello
``` ```
This will generate and add wrappers for all types needed by our resource. This will generate and add wrappers for all types needed by our resource.

View File

@@ -1,19 +0,0 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum)]
public class ClassIdAttribute : Attribute
{
public UUID ClassId { get; private set; }
public ClassIdAttribute(string classId)
{
var data = DC.FromHex(classId, null);
ClassId = new UUID(data);
}
}
}

View File

@@ -8,18 +8,18 @@ namespace Esiur.Resource;
public class CustomEventOccurredInfo public class CustomEventOccurredInfo
{ {
public readonly EventDef EventTemplate; public readonly EventDef EventDef;
public readonly IResource Resource; public readonly IResource Resource;
public readonly object Value; public readonly object Value;
public readonly object Issuer; public readonly object Issuer;
public readonly Func<Session, bool> Receivers; public readonly Func<Session, bool> Receivers;
public string Name => EventTemplate.Name; public string Name => EventDef.Name;
public CustomEventOccurredInfo(IResource resource, EventDef eventTemplate, Func<Session, bool> receivers, object issuer, object value) public CustomEventOccurredInfo(IResource resource, EventDef eventDef, Func<Session, bool> receivers, object issuer, object value)
{ {
Resource = resource; Resource = resource;
EventTemplate = eventTemplate; EventDef = eventDef;
Receivers = receivers; Receivers = receivers;
Issuer = issuer; Issuer = issuer;
Value = value; Value = value;

View File

@@ -70,8 +70,8 @@ public interface IStore : IResource
//AsyncReply<PropertyValue[]> GetPropertyRecord(IResource resource, string propertyName, ulong fromAge, ulong toAge); //AsyncReply<PropertyValue[]> GetPropertyRecord(IResource resource, string propertyName, ulong fromAge, ulong toAge);
//AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate); //AsyncReply<PropertyValue[]> GetPropertyRecordByDate(IResource resource, string propertyName, DateTime fromDate, DateTime toDate);
//AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecord(IResource resource, ulong fromAge, ulong toAge); //AsyncReply<KeyList<PropertyDef, PropertyValue[]>> GetRecord(IResource resource, ulong fromAge, ulong toAge);
// AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>> GetRecordByDate(IResource resource, DateTime fromDate, DateTime toDate); // AsyncReply<KeyList<PropertyDef, PropertyValue[]>> GetRecordByDate(IResource resource, DateTime fromDate, DateTime toDate);
//AsyncReply<KeyList<PropertyDef, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate); //AsyncReply<KeyList<PropertyDef, PropertyValue[]>> GetRecord(IResource resource, DateTime fromDate, DateTime toDate);
} }

View File

@@ -9,15 +9,15 @@ namespace Esiur.Resource;
public struct PropertyModificationInfo public struct PropertyModificationInfo
{ {
public readonly IResource Resource; public readonly IResource Resource;
public readonly PropertyDef PropertyTemplate; public readonly PropertyDef PropertyDef;
public string Name => PropertyTemplate.Name; public string Name => PropertyDef.Name;
public readonly ulong Age; public readonly ulong Age;
public object Value; public object Value;
public PropertyModificationInfo(IResource resource, PropertyDef propertyTemplate, object value, ulong age) public PropertyModificationInfo(IResource resource, PropertyDef propertyDef, object value, ulong age)
{ {
Resource = resource; Resource = resource;
PropertyTemplate = propertyTemplate; PropertyDef = propertyDef;
Age = age; Age = age;
Value = value; Value = value;
} }

View File

@@ -0,0 +1,19 @@
using Esiur.Data;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum)]
public class TypeIdAttribute : Attribute
{
public UUID Id { get; private set; }
public TypeIdAttribute(string id)
{
var data = DC.FromHex(id, null);
Id = new UUID(data);
}
}
}

View File

@@ -515,12 +515,12 @@ public class Warehouse
} }
/// <summary> /// <summary>
/// Get a TypeDef by type from the typeDefs warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse. /// Get a TypeDef by type from the warehouse. If not in the warehouse, a new TypeDef is created and added to the warehouse.
/// </summary> /// </summary>
/// <param name="type">.Net type.</param> /// <param name="type">.Net type.</param>
/// <returns>Resource template.</returns> /// <returns>Resource TypeDef.</returns>
public TypeDef GetTypeDefByType(Type type) public TypeDef GetTypeDefByType(Type type)
{ {
if (!(type.IsClass || type.IsEnum)) if (!(type.IsClass || type.IsEnum))
return null; return null;
@@ -531,61 +531,61 @@ public class Warehouse
|| baseType == typeof(IRecord)) || baseType == typeof(IRecord))
return null; return null;
TypeDefKind schemaKind; TypeDefKind typeDefKind;
if (Codec.ImplementsInterface(type, typeof(IResource))) if (Codec.ImplementsInterface(type, typeof(IResource)))
schemaKind = TypeDefKind.Resource; typeDefKind = TypeDefKind.Resource;
else if (Codec.ImplementsInterface(type, typeof(IRecord))) else if (Codec.ImplementsInterface(type, typeof(IRecord)))
schemaKind = TypeDefKind.Record; typeDefKind = TypeDefKind.Record;
else if (type.IsEnum) else if (type.IsEnum)
schemaKind = TypeDefKind.Enum; typeDefKind = TypeDefKind.Enum;
else else
return null; return null;
var schema = typeDefs[schemaKind].Values.FirstOrDefault(x => x.DefinedType == baseType); var typeDef = typeDefs[typeDefKind].Values.FirstOrDefault(x => x.DefinedType == baseType);
if (schema != null) if (typeDef != null)
return schema; return typeDef;
// create new template for type // create new TypeDef for type
schema = new TypeDef(baseType, this); typeDef = new TypeDef(baseType, this);
TypeDef.GetDependencies(schema, this); TypeDef.GetDependencies(typeDef, this);
return schema; return typeDef;
} }
/// <summary> /// <summary>
/// Get a schema by class Id from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse. /// Get a TypeDef by TypeId from the warehouse. If not in the warehouse, a new TypeDef is created and added to the warehouse.
/// </summary> /// </summary>
/// <param name="classId">Class Id.</param> /// <param name="typeId">typeId.</param>
/// <returns>Resource template.</returns> /// <returns>TypeDef.</returns>
public TypeDef GetTypeDefById(UUID typeId, TypeDefKind? templateType = null) public TypeDef GetTypeDefById(UUID typeId, TypeDefKind? typeDefKind = null)
{ {
if (templateType == null) if (typeDefKind == null)
{ {
// look into resources // look into resources
var template = typeDefs[TypeDefKind.Resource][typeId]; var typeDef = typeDefs[TypeDefKind.Resource][typeId];
if (template != null) if (typeDef != null)
return template; return typeDef;
// look into records // look into records
template = typeDefs[TypeDefKind.Record][typeId]; typeDef = typeDefs[TypeDefKind.Record][typeId];
if (template != null) if (typeDef != null)
return template; return typeDef;
// look into enums // look into enums
template = typeDefs[TypeDefKind.Enum][typeId]; typeDef = typeDefs[TypeDefKind.Enum][typeId];
return template; return typeDef;
} }
else else
return typeDefs[templateType.Value][typeId]; return typeDefs[typeDefKind.Value][typeId];
} }
/// <summary> /// <summary>
/// Get a template by class name from the templates warehouse. If not in the warehouse, a new ResourceTemplate is created and added to the warehouse. /// Get a TypeDef by type name . If not in the warehouse, a new TypeDef is created and added to the warehouse.
/// </summary> /// </summary>
/// <param name="className">Class name.</param> /// <param name="typeName">Class full name.</param>
/// <returns>Resource template.</returns> /// <returns>TypeDef.</returns>
public TypeDef GetTypeDefByName(string typeName, TypeDefKind? typeDefKind = null) public TypeDef GetTypeDefByName(string typeName, TypeDefKind? typeDefKind = null)
{ {
if (typeDefKind == null) if (typeDefKind == null)

View File

@@ -46,5 +46,5 @@ public enum ActionType
RemoveChild, RemoveChild,
Rename, Rename,
ReceiveEvent, ReceiveEvent,
ViewTemplate ViewTypeDef
} }

Binary file not shown.

View File

@@ -1,11 +1,11 @@
function Get-Template($url, $dir, $username, $password, $asyncSetters) function Get-Types($url, $dir, $username, $password, $asyncSetters)
{ {
$lib = Resolve-Path -Path "$($PSScriptRoot)\..\lib\netstandard2.0\Esiur.dll" $lib = Resolve-Path -Path "$($PSScriptRoot)\..\lib\netstandard2.0\Esiur.dll"
#write-host "Lib is at $($lib)" #write-host "Lib is at $($lib)"
$assembly = [Reflection.Assembly]::LoadFile($lib) $assembly = [Reflection.Assembly]::LoadFile($lib)
$tempPath = [Esiur.Proxy.TemplateGenerator]::GetTemplate($url, $dir, $true, $username,$password, $asyncSetters); $tempPath = [Esiur.Proxy.TypeDefGenerator]::GetTypes($url, $dir, $true, $username,$password, $asyncSetters);
$startupProject = GetStartupProject $startupProject = GetStartupProject