JD2022-TU1/main/tools/services/JD.Adobe.Service/Implementation/AdobeService.cs

198 lines
No EOL
6.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JD.Adobe.Service.API;
using JD.Adobe.Service.ExecutableManagement;
using Microsoft.AspNet.SignalR;
using Plume.Core.Events;
using Plume.Core.Logging;
using Plume.Interfaces.Services;
using Shuttle.Api.ClientAPI;
using Shuttle.Servers;
using Shuttle.Servers.Hubs;
using Shuttle.Servers.Managers.AsyncProviders;
using Shuttle.Servers.Managers.Clients;
using Shuttle.Servers.Managers.Events;
using Shuttle.Servers.Managers.Items;
using Shuttle.Servers.Managers.Notifications;
namespace JD.Adobe.Service.Implementation
{
public abstract class AdobeService : IAdobeService
{
private readonly object _lock = new object();
private readonly HashSet<TargetAppInfo> _targets = new HashSet<TargetAppInfo>();
private readonly ISignalrServer _signalrServer;
private readonly EventInvoker _eventInvoker;
private IAdobeEvents _adobeEvents;
protected readonly AdobeExecutableManager _adobeExecutableManager;
protected IAsyncProvider _asyncProvider;
protected IClientManager _clientManager;
protected bool _isInitialized = false;
protected ILogger Logger { get; }
public event Action<TargetAppInfo> OnTargetAdded;
public event Action<TargetAppInfo> OnTargetRemoved;
public event Action<TargetAppInfo, string> OnProjectFileChanged;
public event Action<TargetAppInfo> OnTargetFocused;
protected AdobeService(ILogger logger, string serverUrl)
{
if (serverUrl == null)
{
throw new ArgumentNullException(nameof(serverUrl));
}
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
_signalrServer = new SignalrServer(serverUrl);
_eventInvoker = new EventInvoker(Logger);
_adobeExecutableManager = new AdobeExecutableManager(Logger);
}
protected abstract void InitializeImpl(IServiceContext context);
public void Initialize(IServiceContext context)
{
_asyncProvider = new AsyncProvider();
var aeHubContext = GlobalHost.ConnectionManager.GetHubContext<ClientHub, IAfterEffectsClient>();
var psHubContext = GlobalHost.ConnectionManager.GetHubContext<ClientHub, IPhotoshopClient>();
_clientManager = new ClientManager(Logger, aeHubContext, psHubContext);
_clientManager.OnTargetConnection += AddTarget;
_clientManager.OnTargetDisconnection += RemoveTarget;
var eventManager = new EventManager(Logger, _clientManager);
eventManager.OnAppFocused += OnAppFocused;
eventManager.OnProjectOpened += OnProjectOpened;
eventManager.OnProjectClosed += OnProjectClosedEvent;
_adobeEvents = eventManager;
_signalrServer.Initialize(Logger, _clientManager,
itemDepository: new ItemDepository(Logger, _asyncProvider),
operationNotificationListener: new OperationNotificationListener(Logger, _asyncProvider),
eventNotificationListener: eventManager);
_signalrServer.Start();
_adobeExecutableManager.Initialize();
InitializeImpl(context);
}
public ICollection<TargetAppInfo> GetAvailableTargets()
{
ICollection<TargetAppInfo> results;
lock (_lock)
{
results = new List<TargetAppInfo>(_targets);
}
return results;
}
public abstract Task<TargetAppInfo> StartNewInstance(AdobeApplicationType appType);
public void Dispose()
{
_clientManager.OnTargetConnection -= AddTarget;
_clientManager.OnTargetDisconnection -= RemoveTarget;
_adobeEvents.OnAppFocused -= OnAppFocused;
_adobeEvents.OnProjectOpened -= OnProjectOpened;
_adobeEvents.OnProjectClosed -= OnProjectClosedEvent;
_signalrServer.Dispose();
}
private void AddTarget(TargetAppInfo target)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (TargetAppInfo.IsEmpty(target))
{
throw new ArgumentException($"{nameof(target)} cannot be the empty target.", nameof(target));
}
bool added;
lock (_lock)
{
added = _targets.Add(target);
}
if (!added)
{
throw new ArgumentException($"Target '{target.ShuttleId}' ({target.ConnectionId}) was already known by {this.GetType().Name}.");
}
_eventInvoker.SafeInvokeEventAsync(OnTargetAdded, target);
}
private void RemoveTarget(TargetAppInfo target)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
if (TargetAppInfo.IsEmpty(target))
{
throw new ArgumentException($"{nameof(target)} cannot be the empty target.", nameof(target));
}
bool removed;
lock (_lock)
{
removed = _targets.Remove(target);
}
if (!removed)
{
throw new ArgumentException($"Target '{target.ShuttleId}' ({target.ConnectionId}) was not known by {this.GetType().Name} in the first place.");
}
_eventInvoker.SafeInvokeEventAsync(OnTargetRemoved, target);
}
protected void ThrowIfUnknown(TargetAppInfo target)
{
if (target == null)
{
throw new ArgumentNullException(nameof(target));
}
bool isKnown;
lock (_lock)
{
isKnown = _targets.Contains(target);
}
if (isKnown)
{
return;
}
throw new ArgumentException($"Unknown target '{target.ShuttleId}' ({target.ConnectionId})");
}
private void OnProjectClosedEvent(TargetAppInfo target, string projectFile)
{
_eventInvoker.SafeInvokeEventAsync(OnProjectFileChanged, target, projectFile);
}
private void OnProjectOpened(TargetAppInfo target, string projectFile)
{
_eventInvoker.SafeInvokeEventAsync(OnProjectFileChanged, target, projectFile);
}
private void OnAppFocused(TargetAppInfo target)
{
_eventInvoker.SafeInvokeEventAsync(OnTargetFocused, target);
}
}
}