mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2025-05-06 19:42:58 +00:00
MAUI Support
This commit is contained in:
parent
3b39c9bd28
commit
4cc0657869
@ -6,6 +6,7 @@ namespace Esiur.Core;
|
|||||||
|
|
||||||
public enum ExceptionCode : ushort
|
public enum ExceptionCode : ushort
|
||||||
{
|
{
|
||||||
|
RuntimeException,
|
||||||
HostNotReachable,
|
HostNotReachable,
|
||||||
AccessDenied,
|
AccessDenied,
|
||||||
UserOrTokenNotFound,
|
UserOrTokenNotFound,
|
||||||
|
@ -154,7 +154,7 @@ public static class Codec
|
|||||||
public static bool IsLocalResource(IResource resource, DistributedConnection connection)
|
public static bool IsLocalResource(IResource resource, DistributedConnection connection)
|
||||||
{
|
{
|
||||||
if (resource is DistributedResource)
|
if (resource is DistributedResource)
|
||||||
if ((resource as DistributedResource).Connection == connection)
|
if ((resource as DistributedResource).DistributedResourceConnection == connection)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -321,7 +321,7 @@ public static class DataSerializer
|
|||||||
{
|
{
|
||||||
|
|
||||||
fixed (byte* ptr = rt)
|
fixed (byte* ptr = rt)
|
||||||
*((uint*)ptr) = (resource as DistributedResource).Id;
|
*((uint*)ptr) = (resource as DistributedResource).DistributedResourceInstanceId;
|
||||||
|
|
||||||
return (TransmissionTypeIdentifier.ResourceLocal, rt);
|
return (TransmissionTypeIdentifier.ResourceLocal, rt);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<Copyright>Ahmed Kh. Zamil</Copyright>
|
<Copyright>Ahmed Kh. Zamil</Copyright>
|
||||||
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
<PackageProjectUrl>http://www.esiur.com</PackageProjectUrl>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Version>2.3.1</Version>
|
<Version>2.3.4</Version>
|
||||||
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
<RepositoryUrl>https://github.com/esiur/esiur-dotnet</RepositoryUrl>
|
||||||
<Authors>Ahmed Kh. Zamil</Authors>
|
<Authors>Ahmed Kh. Zamil</Authors>
|
||||||
<AssemblyVersion></AssemblyVersion>
|
<AssemblyVersion></AssemblyVersion>
|
||||||
|
@ -46,12 +46,10 @@ namespace Esiur.Misc;
|
|||||||
public static class Global
|
public static class Global
|
||||||
{
|
{
|
||||||
private static KeyList<string, object> variables = new KeyList<string, object>();
|
private static KeyList<string, object> variables = new KeyList<string, object>();
|
||||||
// private static Hashtable m_Cached = new Hashtable();
|
|
||||||
//internal static bool SystemIsWorking = false;
|
|
||||||
|
|
||||||
private static Random rand = new Random(System.Environment.TickCount);
|
private static Random rand = new Random();// System.Environment.TickCount);
|
||||||
|
|
||||||
|
|
||||||
//public static Encoding DefaultEncoding = Encoding.GetEncoding(1252);// .GetEncoding("windows-1252");
|
|
||||||
|
|
||||||
public static KeyList<string, long> Counters = new KeyList<string, long>();
|
public static KeyList<string, long> Counters = new KeyList<string, long>();
|
||||||
|
|
||||||
@ -68,7 +66,7 @@ public static class Global
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine(ex.ToString());
|
Log(ex);
|
||||||
return "{}";
|
return "{}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -86,18 +84,8 @@ public static class Global
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static string Version { get; } = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
|
public static string Version { get; } = typeof(Global).Assembly.GetName().Version.ToString(); //FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion;
|
||||||
|
|
||||||
//FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
|
|
||||||
// string version = fvi.FileVersion;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
public static char GetDirectorySeparator()
|
|
||||||
{
|
|
||||||
return System.IO.Path.DirectorySeparatorChar;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static void Log(Exception ex, params object[] arguments)
|
public static void Log(Exception ex, params object[] arguments)
|
||||||
{
|
{
|
||||||
@ -147,12 +135,7 @@ public static class Global
|
|||||||
SystemLog?.Invoke(service, type, message);
|
SystemLog?.Invoke(service, type, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
public static string GetTempPath()
|
|
||||||
{
|
|
||||||
return System.IO.Path.GetTempPath();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static string RemoveControlCharacters(string inString)
|
public static string RemoveControlCharacters(string inString)
|
||||||
{
|
{
|
||||||
@ -184,49 +167,9 @@ public static class Global
|
|||||||
Console.WriteLine(k + ":" + Counters[k]);
|
Console.WriteLine(k + ":" + Counters[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Encoding ANSI = Encoding.GetEncoding(1252);
|
|
||||||
|
|
||||||
/*
|
|
||||||
public static Hashtable Cached
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return m_Cached;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
public static string ByteArrayToMAC(byte[] array)
|
|
||||||
{
|
|
||||||
string rt="";
|
|
||||||
|
|
||||||
if (array == null)
|
|
||||||
return "00:00:00:00:00:00";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//for (int i = 0; i < array.Length - 1; i++)
|
|
||||||
// rt += Convert.ToString(array[i], 16) + ":";
|
|
||||||
|
|
||||||
//rt += Convert.ToString(array[array.Length - 1], 16);
|
|
||||||
|
|
||||||
rt = BitConverter.ToString(array);
|
|
||||||
rt = rt.Replace('-', ':');
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
public static string IPAddressFromInt32(UInt32 IP)
|
|
||||||
{
|
|
||||||
//var dIP = DC.ToBytes(IP);
|
|
||||||
|
|
||||||
return (IP >> 24) + "." + ((IP >> 16) & 0xFF) + "." + ((IP >> 8) & 0xFF) + "." + (IP & 0xFF);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
public static KeyList<string, object> Variables
|
public static KeyList<string, object> Variables
|
||||||
{
|
{
|
||||||
@ -356,66 +299,9 @@ public static Hashtable Cached
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetUserPart(string strAddress)
|
|
||||||
{
|
|
||||||
return strAddress.Substring(0, strAddress.IndexOf("@", 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[][] GetBytesFromChunk(byte[] Data, int ChunkSize)
|
|
||||||
{
|
|
||||||
if (ChunkSize == 1)
|
|
||||||
{
|
|
||||||
byte[][] ar = new byte[0][];
|
|
||||||
int ptr = 0;
|
|
||||||
while (ptr < Data.Length)
|
|
||||||
{
|
|
||||||
Array.Resize<byte[]>(ref ar, ar.Length + 1);
|
|
||||||
ar[ar.Length - 1] = new byte[Data[ptr]];
|
|
||||||
Buffer.BlockCopy(Data, ++ptr, ar[ar.Length - 1], 0, Data[ptr]);
|
|
||||||
ptr += Data[ptr] + 1;
|
|
||||||
}
|
|
||||||
return ar;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static string GetFileTitle(string Filename)
|
|
||||||
{
|
|
||||||
string[] s = Filename.Split(Path.DirectorySeparatorChar);
|
|
||||||
return s[s.Length - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetNewFileName(string FileDir)
|
|
||||||
{
|
|
||||||
string tempGetNewFileName = null;
|
|
||||||
short i = 0;
|
|
||||||
string NewFile = null;
|
|
||||||
NewFile = FileDir;
|
|
||||||
Begin:
|
|
||||||
FileInfo FF = new FileInfo(NewFile);
|
|
||||||
if (FF.Exists)
|
|
||||||
{
|
|
||||||
//If FSO.FileExists(NewFile) Then
|
|
||||||
i++; //= i + 1;
|
|
||||||
NewFile = FileDir.Substring(0, FileDir.Length - 4) + "_" + i + "." + FileDir.Substring(FileDir.Length - 3);
|
|
||||||
goto Begin;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tempGetNewFileName = NewFile;
|
|
||||||
}
|
|
||||||
return tempGetNewFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
public static string TrimEx(string strIn)
|
|
||||||
{
|
|
||||||
return strIn.Replace("\r", "").Replace("\n", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public static bool IsUnix()
|
public static bool IsUnix()
|
||||||
@ -442,47 +328,17 @@ public static Hashtable Cached
|
|||||||
|
|
||||||
public static string GenerateCode(int length)
|
public static string GenerateCode(int length)
|
||||||
{
|
{
|
||||||
return GenerateCode(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");// ~!@#$%^&*()_-+=\\?/");
|
return GenerateCode(length, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GenerateCode(int length, string chars)
|
public static string GenerateCode(int length, string chars)
|
||||||
//public static string GenerateCode(int Length)
|
|
||||||
{
|
{
|
||||||
//var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~!@#$%^&*()_-+=\\?/";
|
|
||||||
var result = new string(
|
var result = new string(
|
||||||
Enumerable.Repeat(chars, length)
|
Enumerable.Repeat(chars, length)
|
||||||
.Select(s => s[rand.Next(s.Length)])
|
.Select(s => s[rand.Next(s.Length)])
|
||||||
.ToArray());
|
.ToArray());
|
||||||
//if (result.Length < length)
|
return result;
|
||||||
// Console.WriteLine();
|
}
|
||||||
return result;
|
|
||||||
/*
|
|
||||||
int len = 0;
|
|
||||||
string code = "";
|
|
||||||
|
|
||||||
while(len < Length)
|
|
||||||
{
|
|
||||||
var c = Convert.ToChar((byte)(rand.NextDouble() * 255));
|
|
||||||
if (Char.IsLetterOrDigit(c))
|
|
||||||
{
|
|
||||||
code += c;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string ReplaceOnce(string Expression, string Find, string Replacement)
|
|
||||||
{
|
|
||||||
int pos = Expression.IndexOf(Find);
|
|
||||||
if (pos != -1)
|
|
||||||
return Expression.Substring(0, pos) + Replacement + Expression.Substring(pos + Find.Length);
|
|
||||||
else
|
|
||||||
return Expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static Regex GetRouteRegex(string url)
|
public static Regex GetRouteRegex(string url)
|
||||||
@ -512,8 +368,4 @@ public static Hashtable Cached
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//public void Replace(string Expression, string Find, string Replacement, int Start, int Count)
|
|
||||||
//{
|
|
||||||
// Expression.IndexOf(
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
var r = resource as DistributedResource;
|
var r = resource as DistributedResource;
|
||||||
if (r.Instance.Store == this)
|
if (r.Instance.Store == this)
|
||||||
return this.Instance.Name + "/" + r.Id;
|
return this.Instance.Name + "/" + r.DistributedResourceInstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@ -1362,9 +1362,9 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
foreach (var r in toBeRestored)
|
foreach (var r in toBeRestored)
|
||||||
{
|
{
|
||||||
|
|
||||||
var link = DC.ToBytes(r.Link);
|
var link = DC.ToBytes(r.DistributedResourceLink);
|
||||||
|
|
||||||
Console.WriteLine("Restoreing " + r.Link);
|
Console.WriteLine("Restoreing " + r.DistributedResourceLink);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -1380,8 +1380,8 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
{
|
{
|
||||||
// parse them as int
|
// parse them as int
|
||||||
var id = data.GetUInt32(8, Endian.Little);
|
var id = data.GetUInt32(8, Endian.Little);
|
||||||
if (id != r.Id)
|
if (id != r.DistributedResourceInstanceId)
|
||||||
r.Id = id;
|
r.DistributedResourceInstanceId = id;
|
||||||
|
|
||||||
neededResources[id] = r;
|
neededResources[id] = r;
|
||||||
suspendedResources.Remove(id);
|
suspendedResources.Remove(id);
|
||||||
@ -1426,7 +1426,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
public AsyncReply<bool> Put(IResource resource)
|
public AsyncReply<bool> Put(IResource resource)
|
||||||
{
|
{
|
||||||
if (Codec.IsLocalResource(resource, this))
|
if (Codec.IsLocalResource(resource, this))
|
||||||
neededResources.Add((resource as DistributedResource).Id, (DistributedResource)resource);
|
neededResources.Add((resource as DistributedResource).DistributedResourceInstanceId, (DistributedResource)resource);
|
||||||
// else ... send it to the peer
|
// else ... send it to the peer
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
@ -1550,7 +1550,7 @@ public partial class DistributedConnection : NetworkConnection, IStore
|
|||||||
if (x.TryGetTarget(out r))
|
if (x.TryGetTarget(out r))
|
||||||
{
|
{
|
||||||
r.Suspend();
|
r.Suspend();
|
||||||
suspendedResources[r.Id] = x;
|
suspendedResources[r.DistributedResourceInstanceId] = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -638,8 +638,8 @@ partial class DistributedConnection
|
|||||||
public bool RemoveChild(IResource parent, IResource child)
|
public bool RemoveChild(IResource parent, IResource child)
|
||||||
{
|
{
|
||||||
SendEvent(IIPPacket.IIPPacketEvent.ChildRemoved)
|
SendEvent(IIPPacket.IIPPacketEvent.ChildRemoved)
|
||||||
.AddUInt32((parent as DistributedResource).Id)
|
.AddUInt32((parent as DistributedResource).DistributedResourceInstanceId)
|
||||||
.AddUInt32((child as DistributedResource).Id)
|
.AddUInt32((child as DistributedResource).DistributedResourceInstanceId)
|
||||||
.Done();
|
.Done();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -648,8 +648,8 @@ partial class DistributedConnection
|
|||||||
public bool AddChild(IResource parent, IResource child)
|
public bool AddChild(IResource parent, IResource child)
|
||||||
{
|
{
|
||||||
SendEvent(IIPPacket.IIPPacketEvent.ChildAdded)
|
SendEvent(IIPPacket.IIPPacketEvent.ChildAdded)
|
||||||
.AddUInt32((parent as DistributedResource).Id)
|
.AddUInt32((parent as DistributedResource).DistributedResourceInstanceId)
|
||||||
.AddUInt32((child as DistributedResource).Id)
|
.AddUInt32((child as DistributedResource).DistributedResourceInstanceId)
|
||||||
.Done();
|
.Done();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -2228,7 +2228,7 @@ partial class DistributedConnection
|
|||||||
else
|
else
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
else if (resource != null && !resource.Suspended)
|
else if (resource != null && !resource.DistributedResourceSuspended)
|
||||||
{
|
{
|
||||||
// @REVIEW: this should never happen
|
// @REVIEW: this should never happen
|
||||||
Global.Log("DCON", LogType.Error, "Resource not moved to attached.");
|
Global.Log("DCON", LogType.Error, "Resource not moved to attached.");
|
||||||
@ -2496,13 +2496,13 @@ partial class DistributedConnection
|
|||||||
{
|
{
|
||||||
var dr = resource as DistributedResource;
|
var dr = resource as DistributedResource;
|
||||||
|
|
||||||
if (dr.Connection != this)
|
if (dr.DistributedResourceConnection != this)
|
||||||
return new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>(null);
|
return new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>(null);
|
||||||
|
|
||||||
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
|
var reply = new AsyncReply<KeyList<PropertyTemplate, PropertyValue[]>>();
|
||||||
|
|
||||||
SendRequest(IIPPacket.IIPPacketAction.ResourceHistory)
|
SendRequest(IIPPacket.IIPPacketAction.ResourceHistory)
|
||||||
.AddUInt32(dr.Id)
|
.AddUInt32(dr.DistributedResourceInstanceId)
|
||||||
.AddDateTime(fromDate)
|
.AddDateTime(fromDate)
|
||||||
.AddDateTime(toDate)
|
.AddDateTime(toDate)
|
||||||
.Done()
|
.Done()
|
||||||
|
@ -45,14 +45,15 @@ using Esiur.Resource.Template;
|
|||||||
namespace Esiur.Net.IIP;
|
namespace Esiur.Net.IIP;
|
||||||
|
|
||||||
//[System.Runtime.InteropServices.ComVisible(true)]
|
//[System.Runtime.InteropServices.ComVisible(true)]
|
||||||
public class DistributedResource : DynamicObject, IResource
|
public class DistributedResource : DynamicObject, IResource, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Raised when the distributed resource is destroyed.
|
/// Raised when the distributed resource is destroyed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event DestroyedEvent OnDestroy;
|
public event DestroyedEvent OnDestroy;
|
||||||
public event PropertyModifiedEvent PropertyModified;
|
//public event PropertyModifiedEvent PropertyModified;
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
uint instanceId;
|
uint instanceId;
|
||||||
DistributedConnection connection;
|
DistributedConnection connection;
|
||||||
@ -89,7 +90,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Connection responsible for the distributed resource.
|
/// Connection responsible for the distributed resource.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DistributedConnection Connection
|
public DistributedConnection DistributedResourceConnection
|
||||||
{
|
{
|
||||||
get { return connection; }
|
get { return connection; }
|
||||||
}
|
}
|
||||||
@ -97,7 +98,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resource link
|
/// Resource link
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Link
|
public string DistributedResourceLink
|
||||||
{
|
{
|
||||||
get { return link; }
|
get { return link; }
|
||||||
}
|
}
|
||||||
@ -105,7 +106,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instance Id given by the other end.
|
/// Instance Id given by the other end.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Id
|
public uint DistributedResourceInstanceId
|
||||||
{
|
{
|
||||||
get { return instanceId; }
|
get { return instanceId; }
|
||||||
internal set { instanceId = value; }
|
internal set { instanceId = value; }
|
||||||
@ -136,9 +137,9 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resource is attached when all its properties are received.
|
/// Resource is attached when all its properties are received.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal bool Attached => attached;
|
public bool DistributedResourceAttached => attached;
|
||||||
|
|
||||||
internal bool Suspended => suspended;
|
public bool DistributedResourceSuspended => suspended;
|
||||||
|
|
||||||
|
|
||||||
// public DistributedResourceStack Stack
|
// public DistributedResourceStack Stack
|
||||||
@ -315,7 +316,7 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
indexedArgs.Add(i, pi.GetValue(args[0]));
|
indexedArgs.Add(i, pi.GetValue(args[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
result =_Invoke(ft.Index, indexedArgs);
|
result = _Invoke(ft.Index, indexedArgs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -403,6 +404,33 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
Instance.EmitModification(pt, value);
|
Instance.EmitModification(pt, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <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 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;
|
||||||
|
|
||||||
|
return _Set(index, value).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set property value.
|
/// Set property value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -411,6 +439,15 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
/// <returns>Indicator when the property is set.</returns>
|
/// <returns>Indicator when the property is set.</returns>
|
||||||
protected internal AsyncReply<object> _Set(byte index, object value)
|
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)
|
if (index >= properties.Length)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -424,16 +461,15 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
.Done()
|
.Done()
|
||||||
.Then((res) =>
|
.Then((res) =>
|
||||||
{
|
{
|
||||||
// not really needed, server will always send property modified,
|
// not really needed, server will always send property modified,
|
||||||
// this only happens if the programmer forgot to emit in property setter
|
// this only happens if the programmer forgot to emit in property setter
|
||||||
properties[index] = value;
|
properties[index] = value;
|
||||||
reply.Trigger(null);
|
reply.Trigger(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override bool TrySetMember(SetMemberBinder binder, object value)
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
||||||
{
|
{
|
||||||
if (destroyed)
|
if (destroyed)
|
||||||
@ -521,12 +557,19 @@ public class DistributedResource : DynamicObject, IResource
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (trigger == ResourceTrigger.Initialize)
|
if (trigger == ResourceTrigger.Initialize)
|
||||||
this.Instance.PropertyModified += this.PropertyModified;
|
{
|
||||||
|
this.Instance.PropertyModified += (x) =>
|
||||||
|
this.PropertyChanged?.Invoke(this, new ResourcePropertyChangedEventArgs(x.Name));
|
||||||
|
}
|
||||||
// do nothing.
|
// do nothing.
|
||||||
return new AsyncReply<bool>(true);
|
return new AsyncReply<bool>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void EmitPropertyChanged(string name)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||||
|
}
|
||||||
|
|
||||||
~DistributedResource()
|
~DistributedResource()
|
||||||
{
|
{
|
||||||
Destroy();
|
Destroy();
|
||||||
|
23
Esiur/Net/IIP/ResourcePropertyChangedEventArgs.cs
Normal file
23
Esiur/Net/IIP/ResourcePropertyChangedEventArgs.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using Esiur.Resource;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Esiur.Net.IIP
|
||||||
|
{
|
||||||
|
public class ResourcePropertyChangedEventArgs : PropertyChangedEventArgs
|
||||||
|
{
|
||||||
|
public ResourcePropertyChangedEventArgs(string propertyName) : base(propertyName)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourcePropertyChangedEventArgs(PropertyModificationInfo info) : base(info.Name)
|
||||||
|
{
|
||||||
|
Info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly PropertyModificationInfo Info;
|
||||||
|
}
|
||||||
|
}
|
@ -154,21 +154,21 @@ using Esiur.Core;
|
|||||||
namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{
|
namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{
|
||||||
";
|
";
|
||||||
|
|
||||||
if (ci.HasInterface)
|
if (ci.IsInterfaceImplemented(receiver.Classes))
|
||||||
code += $"public partial class {ci.Name} {{\r\n";
|
code += $"public partial class {ci.Name} {{\r\n";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
code +=
|
code +=
|
||||||
@$" public partial class {ci.Name} : IResource {{
|
@$" public partial class {ci.Name} : IResource {{
|
||||||
public Instance Instance {{ get; set; }}
|
public virtual Instance Instance {{ get; set; }}
|
||||||
public event DestroyedEvent OnDestroy;
|
public virtual event DestroyedEvent OnDestroy;
|
||||||
|
|
||||||
public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
|
public virtual void Destroy() {{ OnDestroy?.Invoke(this); }}
|
||||||
";
|
";
|
||||||
|
|
||||||
if (!ci.HasTrigger)
|
if (!ci.HasTrigger)
|
||||||
code +=
|
code +=
|
||||||
" public AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);\r\n";
|
"\tpublic virtual AsyncReply<bool> Trigger(ResourceTrigger trigger) => new AsyncReply<bool>(true);\r\n\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
//Debugger.Launch();
|
//Debugger.Launch();
|
||||||
@ -183,8 +183,8 @@ namespace { ci.ClassSymbol.ContainingNamespace.ToDisplayString() } {{
|
|||||||
//System.IO.File.AppendAllText("c:\\gen\\fields.txt", fn + " -> " + pn + "\r\n");
|
//System.IO.File.AppendAllText("c:\\gen\\fields.txt", fn + " -> " + pn + "\r\n");
|
||||||
|
|
||||||
// copy attributes
|
// copy attributes
|
||||||
var attrs = string.Join(" ", f.GetAttributes().Select(x => $"[{x.ToString()}]"));
|
var attrs = string.Join("\r\n\t", f.GetAttributes().Select(x => $"[{x.ToString()}]"));
|
||||||
code += $"{attrs} public {f.Type} {pn} {{ get => {fn}; set {{ {fn} = value; Instance?.Modified(); }} }}\r\n";
|
code += $"\t{attrs}\r\n\t public {f.Type} {pn} {{ \r\n\t\t get => {fn}; \r\n\t\t set {{ \r\n\t\t {fn} = value; \r\n\t\t Instance?.Modified(); \r\n\t\t}}\r\n\t}}\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
code += "}}\r\n";
|
code += "}}\r\n";
|
||||||
|
@ -16,4 +16,13 @@ public struct ResourceGeneratorClassInfo
|
|||||||
|
|
||||||
public ClassDeclarationSyntax ClassDeclaration { get; set; }
|
public ClassDeclarationSyntax ClassDeclaration { get; set; }
|
||||||
|
|
||||||
|
public bool IsInterfaceImplemented(Dictionary<string, ResourceGeneratorClassInfo> classes)
|
||||||
|
{
|
||||||
|
if (HasInterface)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Are we going to generate the interface for the parent ?
|
||||||
|
var fullName = ClassSymbol.BaseType.ContainingAssembly + "." + ClassSymbol.BaseType.Name;
|
||||||
|
return classes.ContainsKey(fullName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
|||||||
|
|
||||||
//if (!Debugger.IsAttached)
|
//if (!Debugger.IsAttached)
|
||||||
//{
|
//{
|
||||||
// if (cls.Name == "User")
|
// if (cls.Name == "MyChildResource")
|
||||||
// Debugger.Launch();
|
// Debugger.Launch();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
@ -68,11 +68,12 @@ public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
|||||||
// Partial class check
|
// Partial class check
|
||||||
if (Classes.ContainsKey(fullName))
|
if (Classes.ContainsKey(fullName))
|
||||||
{
|
{
|
||||||
|
|
||||||
// append fields
|
// append fields
|
||||||
var c = Classes[fullName];
|
var c = Classes[fullName];
|
||||||
c.Fields.AddRange(fields);
|
c.Fields.AddRange(fields);
|
||||||
if (!c.HasInterface)
|
if (!c.HasInterface)
|
||||||
c.HasInterface = cls.Interfaces.Any(x => x.ToDisplayString() == "Esiur.Resource.IResource");
|
c.HasInterface = cls.AllInterfaces.Any(x => x.ToDisplayString() == "Esiur.Resource.IResource");
|
||||||
if (!c.HasTrigger)
|
if (!c.HasTrigger)
|
||||||
c.HasTrigger = hasTrigger;
|
c.HasTrigger = hasTrigger;
|
||||||
}
|
}
|
||||||
@ -84,9 +85,13 @@ public class ResourceGeneratorReceiver : ISyntaxContextReceiver
|
|||||||
ClassDeclaration = cds,
|
ClassDeclaration = cds,
|
||||||
ClassSymbol = cls,
|
ClassSymbol = cls,
|
||||||
Fields = fields.ToList(),
|
Fields = fields.ToList(),
|
||||||
HasInterface = cls.Interfaces.Any(x => x.ToDisplayString() == "Esiur.Resource.IResource"),
|
HasInterface = cls.AllInterfaces.Any(x => x.ToDisplayString() == "Esiur.Resource.IResource"),
|
||||||
HasTrigger = hasTrigger
|
HasTrigger = hasTrigger
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -344,6 +344,7 @@ public static class TemplateGenerator
|
|||||||
rt.AppendLine("return rt; }");
|
rt.AppendLine("return rt; }");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach (var p in template.Properties)
|
foreach (var p in template.Properties)
|
||||||
{
|
{
|
||||||
if (p.Inherited)
|
if (p.Inherited)
|
||||||
@ -352,7 +353,7 @@ public static class TemplateGenerator
|
|||||||
var ptTypeName = GetTypeName(p.ValueType, templates);
|
var ptTypeName = GetTypeName(p.ValueType, templates);
|
||||||
rt.AppendLine($"[Public] public {ptTypeName} {p.Name} {{");
|
rt.AppendLine($"[Public] public {ptTypeName} {p.Name} {{");
|
||||||
rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];");
|
rt.AppendLine($"get => ({ptTypeName})properties[{p.Index}];");
|
||||||
rt.AppendLine($"set => _Set({p.Index}, value);");
|
rt.AppendLine($"set => _SetSync({p.Index}, value);");
|
||||||
rt.AppendLine("}");
|
rt.AppendLine("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,11 +43,8 @@ public interface IResource : IDestructible///, INotifyPropertyChanged
|
|||||||
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
AsyncReply<bool> Trigger(ResourceTrigger trigger);
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
Instance Instance
|
[JsonIgnore]
|
||||||
{
|
Instance Instance { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Esiur.Resource;
|
using Esiur.Core;
|
||||||
|
using Esiur.Resource;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -14,7 +15,6 @@ namespace Test
|
|||||||
[Public][Annotation("Comment")] string description;
|
[Public][Annotation("Comment")] string description;
|
||||||
[Public] int categoryId;
|
[Public] int categoryId;
|
||||||
|
|
||||||
|
|
||||||
[Public] public string Hello() => "Hi";
|
[Public] public string Hello() => "Hi";
|
||||||
|
|
||||||
[Public] public string HelloParent() => "Hi from Parent";
|
[Public] public string HelloParent() => "Hi from Parent";
|
||||||
|
@ -152,7 +152,8 @@ public partial class MyService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Public] public AsyncReply<List<Map<int, string?>?>> AsyncHello()
|
[Public]
|
||||||
|
public AsyncReply<List<Map<int, string?>?>> AsyncHello()
|
||||||
{
|
{
|
||||||
var rt = new List<Map<int, string?>?>();
|
var rt = new List<Map<int, string?>?>();
|
||||||
rt.Add(new Map<int, string?>() { [1] = "SSSSS", [2] = null });
|
rt.Add(new Map<int, string?>() { [1] = "SSSSS", [2] = null });
|
||||||
|
@ -96,7 +96,6 @@ namespace Test
|
|||||||
|
|
||||||
// Start testing
|
// Start testing
|
||||||
TestClient(service);
|
TestClient(service);
|
||||||
// TestClient(service);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user