Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 54 additions & 54 deletions src/ElectronNET.API/API/ApiBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ protected enum SocketEventNameTypes
CamelCase,
}

private const int PropertyTimeout = 1000;
private const int InvocationTimeout = 1000;

private readonly string objectName;
private readonly ConcurrentDictionary<string, PropertyGetter> propertyGetters;
private readonly ConcurrentDictionary<string, string> propertyEventNames = new();
private readonly ConcurrentDictionary<string, string> propertyMessageNames = new();
private readonly ConcurrentDictionary<string, Invocator> invocators;
private readonly ConcurrentDictionary<string, string> invocationEventNames = new();
private readonly ConcurrentDictionary<string, string> invocationMessageNames = new();
private readonly ConcurrentDictionary<string, string> methodMessageNames = new();
private static readonly ConcurrentDictionary<string, EventContainer> eventContainers = new();
private static readonly ConcurrentDictionary<string, ConcurrentDictionary<string, PropertyGetter>> AllPropertyGetters = new();
private static readonly ConcurrentDictionary<string, ConcurrentDictionary<string, Invocator>> AllInvocators = new();

private readonly object objLock = new object();

Expand All @@ -58,7 +58,7 @@ protected set
protected ApiBase()
{
this.objectName = this.GetType().Name.LowerFirst();
propertyGetters = AllPropertyGetters.GetOrAdd(objectName, _ => new ConcurrentDictionary<string, PropertyGetter>());
this.invocators = AllInvocators.GetOrAdd(this.objectName, _ => new ConcurrentDictionary<string, Invocator>());
}

protected void CallMethod0([CallerMemberName] string callerName = null)
Expand Down Expand Up @@ -113,37 +113,37 @@ protected void CallMethod3(object val1, object val2, object val3, [CallerMemberN
}
}

protected Task<T> GetPropertyAsync<T>(object arg = null, [CallerMemberName] string callerName = null)
protected Task<T> InvokeAsync<T>(object arg = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");

lock (this.objLock)
{
return this.propertyGetters.GetOrAdd(callerName, _ =>
return this.invocators.GetOrAdd(callerName, _ =>
{
var getter = new PropertyGetter<T>(this, callerName, PropertyTimeout, arg);
var getter = new Invocator<T>(this, callerName, InvocationTimeout, arg);

getter.Task<T>().ContinueWith(_ =>
{
lock (this.objLock)
{
return this.propertyGetters.TryRemove(callerName, out var _);
return this.invocators.TryRemove(callerName, out var _);
}
});

return getter;
}).Task<T>();
}
}

protected void AddEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");
var eventName = EventName(callerName);
var eventKey = EventKey(eventName, id);
var eventName = this.EventName(callerName);

var eventKey = this.EventKey(eventName, id);

lock (objLock)
lock (this.objLock)
{
var container = eventContainers.GetOrAdd(eventKey, _ =>
{
Expand All @@ -156,14 +156,14 @@ protected void AddEvent(Action value, int? id = null, [CallerMemberName] string
container.Register(value);
}
}

protected void RemoveEvent(Action value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");
var eventName = EventName(callerName);
var eventKey = EventKey(eventName, id);
var eventName = this.EventName(callerName);
var eventKey = this.EventKey(eventName, id);

lock (objLock)
lock (this.objLock)
{
if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value))
{
Expand All @@ -172,15 +172,15 @@ protected void RemoveEvent(Action value, int? id = null, [CallerMemberName] stri
}
}
}

protected void AddEvent<T>(Action<T> value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");

var eventName = EventName(callerName);
var eventKey = EventKey(eventName, id);

lock (objLock)
var eventName = this.EventName(callerName);
var eventKey = this.EventKey(eventName, id);

lock (this.objLock)
{
var container = eventContainers.GetOrAdd(eventKey, _ =>
{
Expand All @@ -197,10 +197,10 @@ protected void AddEvent<T>(Action<T> value, int? id = null, [CallerMemberName] s
protected void RemoveEvent<T>(Action<T> value, int? id = null, [CallerMemberName] string callerName = null)
{
Debug.Assert(callerName != null, nameof(callerName) + " != null");
var eventName = EventName(callerName);
var eventKey = EventKey(eventName, id);
var eventName = this.EventName(callerName);
var eventKey = this.EventKey(eventName, id);

lock (objLock)
lock (this.objLock)
{
if (eventContainers.TryGetValue(eventKey, out var container) && !container.Unregister(value))
{
Expand All @@ -212,33 +212,33 @@ protected void RemoveEvent<T>(Action<T> value, int? id = null, [CallerMemberName

private string EventName(string callerName)
{
switch (SocketEventNameType)
switch (this.SocketEventNameType)
{
case SocketEventNameTypes.DashedLower:
return $"{objectName}-{callerName.ToDashedEventName()}";
return $"{this.objectName}-{callerName.ToDashedEventName()}";
case SocketEventNameTypes.CamelCase:
return $"{objectName}-{callerName.ToCamelCaseEventName()}";
return $"{this.objectName}-{callerName.ToCamelCaseEventName()}";
default:
throw new ArgumentOutOfRangeException();
}
}

private string EventKey(string eventName, int? id)
{
return string.Format(CultureInfo.InvariantCulture, "{0}{1:D}", eventName, id);
}

internal abstract class PropertyGetter
internal abstract class Invocator
{
public abstract Task<T> Task<T>();
}

internal class PropertyGetter<T> : PropertyGetter
internal class Invocator<T> : Invocator
{
private readonly Task<T> tcsTask;
private TaskCompletionSource<T> tcs;

public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object arg = null)
public Invocator(ApiBase apiBase, string callerName, int timeoutMs, object arg = null)
{
this.tcs = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
this.tcsTask = this.tcs.Task;
Expand All @@ -249,22 +249,22 @@ public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object
switch (apiBase.SocketTaskEventNameType)
{
case SocketTaskEventNameTypes.DashesLowerFirst:
eventName = apiBase.propertyEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}-completed");
eventName = apiBase.invocationEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}-completed");
break;
case SocketTaskEventNameTypes.NoDashUpperFirst:
eventName = apiBase.propertyEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}{s.StripAsync()}Completed");
eventName = apiBase.invocationEventNames.GetOrAdd(callerName, s => $"{apiBase.objectName}{s.StripAsync()}Completed");
break;
default:
throw new ArgumentOutOfRangeException();
}

switch (apiBase.SocketTaskMessageNameType)
{
case SocketTaskMessageNameTypes.DashesLowerFirst:
messageName = apiBase.propertyMessageNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}");
messageName = apiBase.invocationMessageNames.GetOrAdd(callerName, s => $"{apiBase.objectName}-{s.StripAsync().LowerFirst()}");
break;
case SocketTaskMessageNameTypes.NoDashUpperFirst:
messageName = apiBase.propertyMessageNames.GetOrAdd(callerName, s => apiBase.objectName + s.StripAsync());
messageName = apiBase.invocationMessageNames.GetOrAdd(callerName, s => apiBase.objectName + s.StripAsync());
break;
default:
throw new ArgumentOutOfRangeException();
Expand All @@ -289,17 +289,17 @@ public PropertyGetter(ApiBase apiBase, string callerName, int timeoutMs, object
}
}
});

if (arg != null)
{
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg);
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id, arg) : BridgeConnector.Socket.Emit(messageName, arg);
}
else
{
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName);
_ = apiBase.Id >= 0 ? BridgeConnector.Socket.Emit(messageName, apiBase.Id) : BridgeConnector.Socket.Emit(messageName);
}

System.Threading.Tasks.Task.Delay(PropertyTimeout).ContinueWith(_ =>
System.Threading.Tasks.Task.Delay(InvocationTimeout).ContinueWith(_ =>
{
if (this.tcs != null)
{
Expand All @@ -321,7 +321,7 @@ public override Task<T1> Task<T1>()
return this.tcsTask as Task<T1>;
}
}

[SuppressMessage("ReSharper", "InconsistentlySynchronizedField")]
private class EventContainer
{
Expand All @@ -330,41 +330,41 @@ private class EventContainer

private Action<T> GetEventActionT<T>()
{
return (Action<T>)eventActionT;
return (Action<T>)this.eventActionT;
}

private void SetEventActionT<T>(Action<T> actionT)
{
eventActionT = actionT;
this.eventActionT = actionT;
}

public void OnEventAction() => eventAction?.Invoke();
public void OnEventAction() => this.eventAction?.Invoke();

public void OnEventActionT<T>(T p) => GetEventActionT<T>()?.Invoke(p);
public void OnEventActionT<T>(T p) => this.GetEventActionT<T>()?.Invoke(p);

public void Register(Action receiver)
{
eventAction += receiver;
this.eventAction += receiver;
}

public void Register<T>(Action<T> receiver)
{
var actionT = GetEventActionT<T>();
var actionT = this.GetEventActionT<T>();
actionT += receiver;
SetEventActionT(actionT);
this.SetEventActionT(actionT);
}

public bool Unregister(Action receiver)
{
eventAction -= receiver;
this.eventAction -= receiver;
return this.eventAction != null;
}

public bool Unregister<T>(Action<T> receiver)
{
var actionT = GetEventActionT<T>();
var actionT = this.GetEventActionT<T>();
actionT -= receiver;
SetEventActionT(actionT);
this.SetEventActionT(actionT);

return actionT != null;
}
Expand Down
24 changes: 12 additions & 12 deletions src/ElectronNET.API/API/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ public Task<string> NameAsync
{
get
{
return this.GetPropertyAsync<string>();
return this.InvokeAsync<string>();
}
}

Expand Down Expand Up @@ -501,7 +501,7 @@ public void Show()
public async Task<string> GetAppPathAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<string>().ConfigureAwait(false);
return await this.InvokeAsync<string>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -565,7 +565,7 @@ public void SetPath(PathName name, string path)
public async Task<string> GetVersionAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<string>().ConfigureAwait(false);
return await this.InvokeAsync<string>().ConfigureAwait(false);
}

/// <summary>
Expand All @@ -579,7 +579,7 @@ public async Task<string> GetVersionAsync(CancellationToken cancellationToken =
public async Task<string> GetLocaleAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<string>().ConfigureAwait(false);
return await this.InvokeAsync<string>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -850,7 +850,7 @@ public async Task<bool> SetUserTasksAsync(UserTask[] userTasks, CancellationToke
public async Task<JumpListSettings> GetJumpListSettingsAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<JumpListSettings>().ConfigureAwait(false);
return await this.InvokeAsync<JumpListSettings>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -941,7 +941,7 @@ public void ReleaseSingleInstanceLock()
public async Task<bool> HasSingleInstanceLockAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<bool>().ConfigureAwait(false);
return await this.InvokeAsync<bool>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -980,7 +980,7 @@ public void SetUserActivity(string type, object userInfo, string webpageUrl)
public async Task<string> GetCurrentActivityTypeAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<string>().ConfigureAwait(false);
return await this.InvokeAsync<string>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -1043,7 +1043,7 @@ public async Task<int> ImportCertificateAsync(ImportCertificateOptions options,
public async Task<ProcessMetric[]> GetAppMetricsAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<ProcessMetric[]>().ConfigureAwait(false);
return await this.InvokeAsync<ProcessMetric[]>().ConfigureAwait(false);
}

/// <summary>
Expand All @@ -1055,7 +1055,7 @@ public async Task<ProcessMetric[]> GetAppMetricsAsync(CancellationToken cancella
public async Task<GPUFeatureStatus> GetGpuFeatureStatusAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<GPUFeatureStatus>().ConfigureAwait(false);
return await this.InvokeAsync<GPUFeatureStatus>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -1090,7 +1090,7 @@ public async Task<bool> SetBadgeCountAsync(int count, CancellationToken cancella
public async Task<int> GetBadgeCountAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<int>().ConfigureAwait(false);
return await this.InvokeAsync<int>().ConfigureAwait(false);
}

/// <summary>
Expand All @@ -1105,7 +1105,7 @@ public async Task<int> GetBadgeCountAsync(CancellationToken cancellationToken =
public async Task<bool> IsUnityRunningAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<bool>().ConfigureAwait(false);
return await this.InvokeAsync<bool>().ConfigureAwait(false);
}

/// <summary>
Expand Down Expand Up @@ -1166,7 +1166,7 @@ public void SetLoginItemSettings(LoginSettings loginSettings)
public async Task<bool> IsAccessibilitySupportEnabledAsync(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return await this.GetPropertyAsync<bool>().ConfigureAwait(false);
return await this.InvokeAsync<bool>().ConfigureAwait(false);
}

/// <summary>
Expand Down
Loading