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

@ -0,0 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource;
public delegate void CustomEventOccurredEvent(CustomEventOccurredInfo info);

View File

@ -0,0 +1,27 @@
using Esiur.Resource.Template;
using Esiur.Security.Authority;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource;
public class CustomEventOccurredInfo
{
public readonly EventTemplate EventTemplate;
public readonly IResource Resource;
public readonly object Value;
public readonly object Issuer;
public readonly Func<Session, bool> Receivers;
public string Name => EventTemplate.Name;
public CustomEventOccurredInfo(IResource resource, EventTemplate eventTemplate, Func<Session, bool> receivers, object issuer, object value)
{
Resource = resource;
EventTemplate = eventTemplate;
Receivers = receivers;
Issuer = issuer;
Value = value;
}
}

View File

@ -0,0 +1,8 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
public delegate void EventOccurredEvent(EventOccurredInfo info);
}

View File

@ -0,0 +1,26 @@
using Esiur.Resource.Template;
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
public class EventOccurredInfo
{
public readonly EventTemplate EventTemplate;
public string Name => EventTemplate.Name;
public readonly IResource Resource;
public readonly object Value;
public EventOccurredInfo(IResource resource, EventTemplate eventTemplate, object value)
{
Resource = resource;
Value = value;
EventTemplate = eventTemplate;
}
}
}

View File

@ -40,7 +40,6 @@ public delegate bool QueryFilter<T>(T value);
public interface IResource : IDestructible///, INotifyPropertyChanged
{
AsyncReply<bool> Trigger(ResourceTrigger trigger);
[NotMapped]
@ -50,5 +49,5 @@ public interface IResource : IDestructible///, INotifyPropertyChanged
set;
}
}

View File

@ -40,8 +40,8 @@ public interface IStore : IResource
//AsyncReply<IResource> Retrieve(uint iid);
AsyncReply<bool> Put(IResource resource);
string Link(IResource resource);
bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
bool Remove(IResource resource);
//bool RemoveAttributes(IResource resource, string[] attributes = null);

View File

@ -7,7 +7,7 @@ namespace Esiur.Resource;
[AttributeUsage(AttributeTargets.Class)]
public class ImportAttribute : Attribute
{
public ImportAttribute(string url)
public ImportAttribute(params string[] urls)
{
}

View File

@ -32,24 +32,20 @@ public class Instance
AutoList<IPermissionsManager, Instance> managers;
public delegate void ResourceModifiedEvent(IResource resource, string propertyName, object newValue);
public delegate void ResourceEventOccurredEvent(IResource resource, string eventName, object args);
public event PropertyModifiedEvent PropertyModified;
public delegate void CustomResourceEventOccurredEvent(IResource resource, object issuer, Func<Session, bool> receivers, string eventName, object args);
public delegate void ResourceDestroyedEvent(IResource resource);
public event ResourceModifiedEvent ResourceModified;
public event ResourceEventOccurredEvent ResourceEventOccurred;
public event CustomResourceEventOccurredEvent CustomResourceEventOccurred;
public event ResourceDestroyedEvent ResourceDestroyed;
public event EventOccurredEvent EventOccurred;
public event CustomEventOccurredEvent CustomEventOccurred;
public event ResourceDestroyedEvent Destroyed;
bool loading = false;
//KeyList<string, object> attributes;
List<ulong> ages = new List<ulong>();
List<DateTime> modificationDates = new List<DateTime>();
List<ulong?> ages = new();
List<DateTime?> modificationDates = new ();
private ulong instanceAge;
private DateTime instanceModificationDate;
@ -100,10 +96,10 @@ public class Instance
*/
}
public Structure GetAttributes(string[] attributes = null)
public Map<string,object> GetAttributes(string[] attributes = null)
{
// @TODO
Structure rt = new Structure();
var rt = new Map<string,object>();
if (attributes != null)
{
@ -172,7 +168,7 @@ public class Instance
*/
}
public bool SetAttributes(Structure attributes, bool clearAttributes = false)
public bool SetAttributes(Map<string,object> attributes, bool clearAttributes = false)
{
// @ TODO
@ -274,7 +270,7 @@ public class Instance
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <returns>Age.</returns>
public ulong GetAge(byte index)
public ulong? GetAge(byte index)
{
if (index < ages.Count)
return ages[index];
@ -287,13 +283,13 @@ public class Instance
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Age.</param>
public void SetAge(byte index, ulong value)
public void SetAge(byte index, ulong? value)
{
if (index < ages.Count)
{
ages[index] = value;
if (value > instanceAge)
instanceAge = value;
instanceAge = (ulong)value;
}
}
@ -302,13 +298,13 @@ public class Instance
/// </summary>
/// <param name="index">Zero-based property index.</param>
/// <param name="value">Modification date.</param>
public void SetModificationDate(byte index, DateTime value)
public void SetModificationDate(byte index, DateTime? value)
{
if (index < modificationDates.Count)
{
modificationDates[index] = value;
if (value > instanceModificationDate)
instanceModificationDate = value;
instanceModificationDate = (DateTime) value;
}
}
@ -317,7 +313,7 @@ public class Instance
/// </summary>
/// <param name="index">Zero-based property index</param>
/// <returns>Modification date.</returns>
public DateTime GetModificationDate(byte index)
public DateTime? GetModificationDate(byte index)
{
if (index < modificationDates.Count)
return modificationDates[index];
@ -333,7 +329,7 @@ public class Instance
/// <param name="age">Property age</param>
/// <param name="value">Property value</param>
/// <returns></returns>
public bool LoadProperty(string name, ulong age, DateTime modificationDate, object value)
public bool LoadProperty(string name, ulong? age, DateTime? modificationDate, object value)
{
IResource res;
@ -354,7 +350,8 @@ public class Instance
#endif
*/
if (pt.PropertyInfo.PropertyType == typeof(DistributedPropertyContext))
if (pt.PropertyInfo.PropertyType.IsGenericType
&& pt.PropertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(DistributedPropertyContext<>))
return false;
@ -394,7 +391,7 @@ public class Instance
/// <summary>
/// Last modification date.
/// </summary>
public DateTime ModificationDate
public DateTime? ModificationDate
{
get
{
@ -559,14 +556,15 @@ public class Instance
if (pt.Recordable)
{
store.Record(res, pt.Name, value, ages[pt.Index], now);
}
else //if (pt.Storage == StorageMode.Recordable)
{
store.Modify(res, pt.Name, value, ages[pt.Index], now);
}
ResourceModified?.Invoke(res, pt.Name, value);
//ResourceModified?.Invoke(res, pt.Name, value);
PropertyModified?.Invoke(new PropertyModificationInfo(res, pt, value, instanceAge));
}
}
@ -591,21 +589,21 @@ public class Instance
// internal void EmitResourceEvent(string name, string[] users, DistributedConnection[] connections, object[] args)
internal void EmitCustomResourceEvent(object issuer, Func<Session, bool> receivers, string name, object args)
internal void EmitCustomResourceEvent(object issuer, Func<Session, bool> receivers, EventTemplate eventTemplate, object value)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
CustomResourceEventOccurred?.Invoke(res, issuer, receivers, name, args);
CustomEventOccurred?.Invoke(new CustomEventOccurredInfo(res, eventTemplate, receivers, issuer, value));
}
}
internal void EmitResourceEvent(string name, object args)
internal void EmitResourceEvent(EventTemplate eventTemplate, object value)
{
IResource res;
if (this.resource.TryGetTarget(out res))
{
ResourceEventOccurred?.Invoke(res, name, args);
EventOccurred?.Invoke(new EventOccurredInfo(res, eventTemplate, value));
}
}
@ -912,7 +910,7 @@ public class Instance
// if (ca.Length == 0)
// continue;
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt.Name, args);
ResourceEventHandler<object> proxyDelegate = (args) => EmitResourceEvent(evt, args);
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
}
@ -922,7 +920,7 @@ public class Instance
//if (ca.Length == 0)
// continue;
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt.Name, args);
CustomResourceEventHandler<object> proxyDelegate = (issuer, receivers, args) => EmitCustomResourceEvent(issuer, receivers, evt, args);
evt.EventInfo.AddEventHandler(resource, proxyDelegate);
}
@ -991,6 +989,6 @@ public class Instance
private void Resource_OnDestroy(object sender)
{
ResourceDestroyed?.Invoke((IResource)sender);
Destroyed?.Invoke((IResource)sender);
}
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Text;
using Esiur.Resource;
using Esiur.Resource.Template;
namespace Esiur.Resource;
public struct PropertyModificationInfo
{
public readonly IResource Resource;
public readonly PropertyTemplate PropertyTemplate;
public string Name => PropertyTemplate.Name;
public readonly ulong Age;
public object Value;
public PropertyModificationInfo(IResource resource, PropertyTemplate propertyTemplate, object value, ulong age)
{
Resource = resource;
PropertyTemplate = propertyTemplate;
Age = age;
Value = value;
}
}

View File

@ -0,0 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource;
public delegate void PropertyModifiedEvent(PropertyModificationInfo data);

View File

@ -4,7 +4,7 @@ using System.Text;
namespace Esiur.Resource;
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class)]
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Event | AttributeTargets.Class | AttributeTargets.Enum)]
public class PublicAttribute : Attribute
{

View File

@ -32,7 +32,7 @@ public class Resource : IResource
public Instance Instance { get; set; }
public event DestroyedEvent OnDestroy;
public virtual void Destroy()
{
OnDestroy?.Invoke(this);
@ -52,6 +52,7 @@ public class Resource : IResource
return true;
}
~Resource()
{
Destroy();

View File

@ -0,0 +1,8 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Esiur.Resource
{
public delegate void ResourceDestroyedEvent(IResource resource);
}

View File

@ -34,42 +34,21 @@ namespace Esiur.Resource;
[AttributeUsage(AttributeTargets.Property)]
public class ResourceProperty : System.Attribute
{
bool serialize;
string readExpansion;
string writeExpansion;
// bool recordable;
//bool storable;
//public bool Recordable => recordable;
//public bool Storable => storable;
StorageMode storage;
public readonly bool Nullable;
public readonly StorageMode Storage;
public readonly bool Serialize;
public readonly string ReadExpansion;
public readonly string WriteExpansion;
public StorageMode Storage => storage;
public bool Serialize => serialize;
public string ReadExpansion
public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true,
string readExpansion = null, string writeExpansion = null)
{
get
{
return readExpansion;
}
}
public string WriteExpansion
{
get
{
return writeExpansion;
}
}
public ResourceProperty(StorageMode storage = StorageMode.NonVolatile, bool serialize = true, string readExpansion = null, string writeExpansion = null)
{
this.readExpansion = readExpansion;
this.writeExpansion = writeExpansion;
this.storage = storage;
this.serialize = serialize;
this.ReadExpansion = readExpansion;
this.WriteExpansion = writeExpansion;
this.Storage = storage;
this.Serialize = serialize;
}
}

View File

@ -40,11 +40,11 @@ public class Storable : global::System.Attribute
SerializerFunction serializer;
DeserializerFunction deserializer;
DataType type;
RepresentationType dataType;
public Storable()
{
type = DataType.Void;
//dataType = = DataType.Void;
}
public DeserializerFunction Deserializer
@ -57,14 +57,14 @@ public class Storable : global::System.Attribute
get { return serializer; }
}
public Storable(DataType type)
public Storable(RepresentationType type)
{
this.type = type;
this.dataType = type;
}
public Storable(DataType type, SerializerFunction serializer, DeserializerFunction deserializer)
public Storable(RepresentationType type, SerializerFunction serializer, DeserializerFunction deserializer)
{
this.type = type;
this.dataType = type;
this.serializer = serializer;
this.deserializer = deserializer;
}

View File

@ -11,6 +11,7 @@ public abstract class Store<T> : IStore where T : IResource
public Instance Instance { get; set; }
public event DestroyedEvent OnDestroy;
public abstract AsyncReply<bool> AddChild(IResource parent, IResource child);
@ -30,13 +31,13 @@ public abstract class Store<T> : IStore where T : IResource
public abstract string Link(IResource resource);
public abstract bool Modify(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
public abstract bool Modify(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
public abstract AsyncBag<T1> Parents<T1>(IResource resource, string name) where T1 : IResource;
public abstract AsyncReply<bool> Put(IResource resource);
public abstract bool Record(IResource resource, string propertyName, object value, ulong age, DateTime dateTime);
public abstract bool Record(IResource resource, string propertyName, object value, ulong? age, DateTime? dateTime);
public abstract bool Remove(IResource resource);

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;
}

View File

@ -53,9 +53,7 @@ public static class Warehouse
static uint resourceCounter = 0;
//static KeyList<Guid, TypeTemplate> templates = new KeyList<Guid, TypeTemplate>();
//static KeyList<Guid, TypeTemplate> wrapperTemplates = new KeyList<Guid, TypeTemplate>();
static KeyList<TemplateType, KeyList<Guid, TypeTemplate>> templates
= new KeyList<TemplateType, KeyList<Guid, TypeTemplate>>()
{
@ -63,6 +61,7 @@ public static class Warehouse
[TemplateType.Resource] = new KeyList<Guid, TypeTemplate>(),
[TemplateType.Record] = new KeyList<Guid, TypeTemplate>(),
[TemplateType.Wrapper] = new KeyList<Guid, TypeTemplate>(),
[TemplateType.Enum] = new KeyList<Guid, TypeTemplate>(),
};
static bool warehouseIsOpen = false;
@ -141,6 +140,12 @@ public static class Warehouse
{
PutTemplate(new TypeTemplate(t));
}
var enumsTypes = (Type[])generatedType.GetProperty("Enums").GetValue(null);
foreach (var t in recordTypes)
{
PutTemplate(new TypeTemplate(t));
}
}
}
}
@ -590,7 +595,7 @@ public static class Warehouse
resource.Instance = new Instance(resourceCounter++, instanceName, resource, store, customTemplate, age);
if (attributes != null)
resource.Instance.SetAttributes(Structure.FromObject(attributes));
resource.Instance.SetAttributes(Map<string,object>.FromObject(attributes));
if (manager != null)
resource.Instance.Managers.Add(manager);
@ -686,7 +691,7 @@ public static class Warehouse
if (properties != null)
{
var ps = Structure.FromObject(properties);
var ps = Map<string,object>.FromObject(properties);
foreach (var p in ps)
{
@ -768,6 +773,8 @@ public static class Warehouse
templateType = TemplateType.Resource;
else if (Codec.ImplementsInterface(type, typeof(IRecord)))
templateType = TemplateType.Record;
else if (type.IsEnum)
templateType = TemplateType.Enum;
else
return null;
@ -781,7 +788,10 @@ public static class Warehouse
// loaded ?
if (template == null)
{
template = new TypeTemplate(baseType, true);
TypeTemplate.GetDependencies(template);
}
return template;
}
@ -805,6 +815,12 @@ public static class Warehouse
if (template != null)
return template;
// look in enums
template = templates[TemplateType.Enum][classId];
if (template != null)
return template;
// look in wrappers
template = templates[TemplateType.Wrapper][classId];
return template;