mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-01-27 01:20:39 +00:00
IDynamicResource Added
This commit is contained in:
@@ -68,7 +68,7 @@ partial class DistributedConnection
|
||||
|
||||
object subscriptionsLock = new object();
|
||||
|
||||
AsyncQueue<DistributedResourceQueueItem> queue = new ();
|
||||
AsyncQueue<DistributedResourceQueueItem> queue = new();
|
||||
|
||||
|
||||
|
||||
@@ -450,7 +450,7 @@ partial class DistributedConnection
|
||||
var (valueOffset, valueSize, args) =
|
||||
DataDeserializer.LimitedCountListParser(dataType.Data, dataType.Offset, dataType.ContentLength, Instance.Warehouse, 2);
|
||||
|
||||
var rid =Convert.ToUInt32(args[0]);
|
||||
var rid = Convert.ToUInt32(args[0]);
|
||||
var index = (byte)args[1];
|
||||
|
||||
Fetch(rid, null).Then(r =>
|
||||
@@ -559,26 +559,13 @@ partial class DistributedConnection
|
||||
// unsubscribe
|
||||
Unsubscribe(r);
|
||||
|
||||
if (r is DistributedResource dr)
|
||||
{
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
dr._Serialize());
|
||||
}
|
||||
else
|
||||
{
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
r.Instance.Serialize());
|
||||
}
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
r.Instance.Serialize());
|
||||
|
||||
// subscribe
|
||||
Subscribe(r);
|
||||
@@ -618,26 +605,15 @@ partial class DistributedConnection
|
||||
// unsubscribe
|
||||
Unsubscribe(r);
|
||||
|
||||
if (r is DistributedResource dr)
|
||||
{
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
dr._SerializeAfter(age));
|
||||
}
|
||||
else
|
||||
{
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
r.Instance.SerializeAfter(age));
|
||||
}
|
||||
|
||||
// reply ok
|
||||
SendReply(IIPPacketReply.Completed, callback,
|
||||
r.Instance.Template.ClassId,
|
||||
r.Instance.Age,
|
||||
r.Instance.Link,
|
||||
r.Instance.Hops,
|
||||
r.Instance.SerializeAfter(age));
|
||||
|
||||
|
||||
// subscribe
|
||||
Subscribe(r);
|
||||
@@ -1612,7 +1588,7 @@ partial class DistributedConnection
|
||||
}
|
||||
|
||||
|
||||
if (r is DistributedResource)
|
||||
if (r is IDynamicResource)
|
||||
{
|
||||
var (_, parsed) = Codec.ParseAsync(data, offset, this, null);
|
||||
if (parsed is AsyncReply)
|
||||
@@ -1620,7 +1596,7 @@ partial class DistributedConnection
|
||||
(parsed as AsyncReply).Then((value) =>
|
||||
{
|
||||
// propagation
|
||||
(r as DistributedResource)._Set(index, value).Then((x) =>
|
||||
(r as IDynamicResource).SetResourcePropertyAsync(index, value).Then((x) =>
|
||||
{
|
||||
SendReply(IIPPacketReply.Completed, callback);
|
||||
}).Error(x =>
|
||||
@@ -1912,7 +1888,7 @@ partial class DistributedConnection
|
||||
{
|
||||
template = Instance.Warehouse.GetTemplateByClassId(classId, TemplateType.Resource);
|
||||
if (template?.DefinedType != null && template.IsWrapper)
|
||||
dr = Activator.CreateInstance(template.DefinedType, this, id,Convert.ToUInt64( args[1]), (string)args[2]) as DistributedResource;
|
||||
dr = Activator.CreateInstance(template.DefinedType, this, id, Convert.ToUInt64(args[1]), (string)args[2]) as DistributedResource;
|
||||
else
|
||||
dr = new DistributedResource(this, id, Convert.ToUInt64(args[1]), (string)args[2]);
|
||||
}
|
||||
@@ -1955,7 +1931,9 @@ partial class DistributedConnection
|
||||
// ClassId, ResourceAge, ResourceLink, Content
|
||||
if (resource == null)
|
||||
{
|
||||
Instance.Warehouse.Put(this.Instance.Link + "/" + id.ToString(), dr, tmp)
|
||||
dr.ResourceTemplate = tmp;
|
||||
|
||||
Instance.Warehouse.Put(this.Instance.Link + "/" + id.ToString(), dr)
|
||||
.Then(initResource)
|
||||
.Error(ex => reply.TriggerError(ex));
|
||||
}
|
||||
@@ -1973,7 +1951,7 @@ partial class DistributedConnection
|
||||
{
|
||||
if (resource == null)
|
||||
{
|
||||
Instance.Warehouse.Put(this.Instance.Link + "/" + id.ToString(), dr, template)
|
||||
Instance.Warehouse.Put(this.Instance.Link + "/" + id.ToString(), dr)
|
||||
.Then(initResource).Error((ex) => reply.TriggerError(ex));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -46,7 +46,7 @@ using Esiur.Net.Packets;
|
||||
namespace Esiur.Net.IIP;
|
||||
|
||||
//[System.Runtime.InteropServices.ComVisible(true)]
|
||||
public class DistributedResource : DynamicObject, IResource, INotifyPropertyChanged
|
||||
public class DistributedResource : DynamicObject, IResource, INotifyPropertyChanged, IDynamicResource
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
@@ -57,6 +57,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
uint instanceId;
|
||||
TypeTemplate template;
|
||||
DistributedConnection connection;
|
||||
|
||||
|
||||
@@ -67,7 +68,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
//Structure properties = new Structure();
|
||||
|
||||
string link;
|
||||
//ulong age;
|
||||
ulong age;
|
||||
|
||||
protected object[] properties;
|
||||
internal List<DistributedResource> parents = new List<DistributedResource>();
|
||||
@@ -77,17 +78,6 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resource template for the remotely located resource.
|
||||
/// </summary>
|
||||
//public ResourceTemplate Template
|
||||
//{
|
||||
// get { return template; }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Connection responsible for the distributed resource.
|
||||
/// </summary>
|
||||
@@ -160,45 +150,9 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
this.link = link;
|
||||
this.connection = connection;
|
||||
this.instanceId = instanceId;
|
||||
|
||||
//this.Instance.Template = template;
|
||||
//this.Instance.Age = age;
|
||||
//this.template = template;
|
||||
//this.age = age;
|
||||
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Export properties as byte array.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal PropertyValue[] _Serialize()
|
||||
{
|
||||
var props = new PropertyValue[properties.Length];
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
props[i] = new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
internal Map<byte, PropertyValue> _SerializeAfter(ulong age = 0)
|
||||
{
|
||||
var rt = new Map<byte, PropertyValue>();
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
if (Instance.GetAge(i) > age)
|
||||
rt.Add(i, new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i)));
|
||||
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
internal bool _Attach(PropertyValue[] properties)
|
||||
{
|
||||
if (attached)
|
||||
@@ -357,17 +311,14 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a property value.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <returns>Value</returns>
|
||||
protected internal object _Get(byte index)
|
||||
{
|
||||
if (index >= properties.Length)
|
||||
return null;
|
||||
return properties[index];
|
||||
}
|
||||
///// <summary>
|
||||
///// Get a property value.
|
||||
///// </summary>
|
||||
///// <param name="index">Zero-based property index.</param>
|
||||
///// <returns>Value</returns>
|
||||
//protected internal object _Get(byte index)
|
||||
//{
|
||||
//}
|
||||
|
||||
public bool TryGetPropertyValue(byte index, out object value)
|
||||
{
|
||||
@@ -427,65 +378,19 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Value</param>
|
||||
/// <returns>Indicator when the property is set.</returns>
|
||||
protected object _SetSync(byte index, object value)
|
||||
{
|
||||
//Console.WriteLine("Setting..." + index + " " + value);
|
||||
//protected object _SetSync(byte index, object value)
|
||||
//{
|
||||
//}
|
||||
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (!attached)
|
||||
return null;
|
||||
|
||||
if (index >= properties.Length)
|
||||
return null;
|
||||
|
||||
// Don't set the same current value
|
||||
if (properties[index] == value)
|
||||
return value;
|
||||
|
||||
var rt = _Set(index, value).Wait();
|
||||
|
||||
//Console.WriteLine("Done Setting");
|
||||
return rt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set property value.
|
||||
/// </summary>
|
||||
/// <param name="index">Zero-based property index.</param>
|
||||
/// <param name="value">Value</param>
|
||||
/// <returns>Indicator when the property is set.</returns>
|
||||
protected internal AsyncReply<object> _Set(byte index, object value)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (!attached)
|
||||
return null;
|
||||
|
||||
if (index >= properties.Length)
|
||||
return null;
|
||||
|
||||
var reply = new AsyncReply<object>();
|
||||
|
||||
connection.SendSetProperty(instanceId, index, value)
|
||||
.Then((res) =>
|
||||
{
|
||||
// not really needed, server will always send property modified,
|
||||
// this only happens if the programmer forgot to emit in property setter
|
||||
properties[index] = value;
|
||||
reply.Trigger(null);
|
||||
});
|
||||
|
||||
return reply;
|
||||
}
|
||||
///// <summary>
|
||||
///// Set property value.
|
||||
///// </summary>
|
||||
///// <param name="index">Zero-based property index.</param>
|
||||
///// <param name="value">Value</param>
|
||||
///// <returns>Indicator when the property is set.</returns>
|
||||
//protected internal AsyncReply<object> _Set(byte index, object value)
|
||||
//{
|
||||
//}
|
||||
|
||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||
{
|
||||
@@ -502,7 +407,7 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
|
||||
if (pt != null)
|
||||
{
|
||||
_Set(pt.Index, value);
|
||||
SetResourceProperty(pt.Index, value);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -518,33 +423,6 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
public async void InvokeMethod(byte index, object[] arguments, DistributedConnection sender)
|
||||
{
|
||||
// get function parameters
|
||||
Type t = this.GetType();
|
||||
|
||||
MethodInfo mi = t.GetMethod(GetFunctionName(index), BindingFlags.DeclaredOnly |
|
||||
BindingFlags.Public |
|
||||
BindingFlags.Instance | BindingFlags.InvokeMethod);
|
||||
if (mi != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = await invokeMethod(mi, arguments, sender);
|
||||
object rt = Codec.Compose(res);
|
||||
sender.SendParams((byte)0x80, instanceId, index, rt);
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
var msg = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
|
||||
sender.SendParams((byte)0x8E, instanceId, index, Codec.Compose(msg));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Resource interface.
|
||||
@@ -555,6 +433,18 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
set;
|
||||
}
|
||||
|
||||
public TypeTemplate ResourceTemplate
|
||||
{
|
||||
get
|
||||
{
|
||||
return template;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
template = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance of distributed resource.
|
||||
/// </summary>
|
||||
@@ -587,6 +477,82 @@ public class DistributedResource : DynamicObject, IResource, INotifyPropertyChan
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
|
||||
public PropertyValue[] SerializeResource()
|
||||
{
|
||||
var props = new PropertyValue[properties.Length];
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
props[i] = new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
public Map<byte, PropertyValue> SerializeResourceAfter(ulong age = 0)
|
||||
{
|
||||
var rt = new Map<byte, PropertyValue>();
|
||||
|
||||
for (byte i = 0; i < properties.Length; i++)
|
||||
if (Instance.GetAge(i) > age)
|
||||
rt.Add(i, new PropertyValue(properties[i],
|
||||
Instance.GetAge(i),
|
||||
Instance.GetModificationDate(i)));
|
||||
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public object GetResourceProperty(byte index)
|
||||
{
|
||||
if (index >= properties.Length)
|
||||
return null;
|
||||
return properties[index];
|
||||
}
|
||||
|
||||
public AsyncReply SetResourcePropertyAsync(byte index, object value)
|
||||
{
|
||||
if (destroyed)
|
||||
throw new Exception("Trying to access a destroyed object.");
|
||||
|
||||
if (suspended)
|
||||
throw new Exception("Trying to access a suspended object.");
|
||||
|
||||
if (!attached)
|
||||
throw new Exception("Resource is not attached.");
|
||||
|
||||
if (index >= properties.Length)
|
||||
throw new Exception("Property index not found."); ;
|
||||
|
||||
var reply = new AsyncReply<object>();
|
||||
|
||||
connection.SendSetProperty(instanceId, index, value)
|
||||
.Then((res) =>
|
||||
{
|
||||
// not really needed, server will always send property modified,
|
||||
// this only happens if the programmer forgot to emit in property setter
|
||||
properties[index] = value;
|
||||
reply.Trigger(null);
|
||||
});
|
||||
|
||||
return reply;
|
||||
|
||||
}
|
||||
|
||||
public void SetResourceProperty(byte index, object value)
|
||||
{
|
||||
// Don't set the same current value
|
||||
if (properties[index] == value)
|
||||
return;
|
||||
|
||||
SetResourcePropertyAsync(index, value).Wait();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
~DistributedResource()
|
||||
{
|
||||
Destroy();
|
||||
|
||||
Reference in New Issue
Block a user