| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 | using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq;using System.Threading;using System.Threading.Tasks;using Comal.Classes;using H.Formatters;using H.Pipes;using InABox.Clients;using InABox.Core;using InABox.IPC;using InABox.Logikal;using java.lang;using Exception = System.Exception;using Process = System.Diagnostics.Process;namespace PRSDesktop;public class LogikalClient : IDisposable{    private readonly PipeClient<LogikalMessage> _client;        private ConcurrentDictionary<Guid, ManualResetEventSlim> Events = new();    private ConcurrentDictionary<Guid, LogikalMessage> Responses = new();    private const int DefaultRequestTimeout = 5 * 60 * 1000; // 5 minutes        private LogikalSettings _settings;        public LogikalClient()    {                _settings = Client            .Query(                new Filter<LogikalSettings>().All(),                Columns.All<LogikalSettings>(),                null,                CoreRange.Database(1)            )            .ToObjects<LogikalSettings>()            .FirstOrDefault()        ?? new LogikalSettings();                var _basedirectory = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? "";        var _logikalapp = System.IO.Path.Combine(_basedirectory, "PRSLogikal", "PRSLogikal.exe");        Process.Start(_logikalapp);                _client = new PipeClient<LogikalMessage>("$logikal", formatter: new NewtonsoftJsonFormatter());                _client.Connected += Client_Connected;        _client.Disconnected += Client_Disconnected;        _client.MessageReceived += Client_MessageReceived;        _client.ExceptionOccurred += Client_ExceptionOccurred;        _client.ConnectAsync();    }        public void Dispose()    {        _client.DisposeAsync().AsTask().Wait();    }        private void Client_Connected(object? sender, H.Pipes.Args.ConnectionEventArgs<LogikalMessage> e)    {        Logger.Send(LogType.Information, "", $"Connected to Pipe: {e.Connection.PipeName}");        //Disconnected = false;        // Here we will register a Licence "Hit" for the Logikal interface    }    private void Client_Disconnected(object? sender, H.Pipes.Args.ConnectionEventArgs<LogikalMessage> e)    {        Logger.Send(LogType.Information, "", $"Disconnected from Pipe: {e.Connection.PipeName}");        foreach (var ev in Events)        {            Responses.TryAdd(ev.Key, LogikalMessage.Error("Disconnected"));            ev.Value.Set();        }        //Disconnected = true;    }        private void Client_ExceptionOccurred(object? sender, H.Pipes.Args.ExceptionEventArgs e)    {        Logger.Send(LogType.Error, "", $"Exception occured: {e.Exception.Message}");    }        public LogikalResponse Send(LogikalRequest request, int timeout = DefaultRequestTimeout)    {        var message = new LogikalMessage()        {            ID = Guid.NewGuid(),            Method = request.Method(),            Payload = Serialization.Serialize(request),        };        var ev = Queue(message.ID);        _client.WriteAsync(message);        var result = GetResult(message.ID, ev, timeout);        return LogikalResponse.FromMessage(result);    }    public ManualResetEventSlim Queue(Guid id)    {        var ev = new ManualResetEventSlim();        Events[id] = ev;        return ev;    }    public LogikalMessage GetResult(Guid id, ManualResetEventSlim ev, int timeout)    {        if (Responses.TryRemove(id, out var result))        {            Events.TryRemove(id, out ev);            return result;        }        try        {            if (!ev.Wait(timeout))            {                return LogikalMessage.Error("Timeout");            }        }        catch (Exception e)        {            Console.WriteLine(e);            throw;        }                    Responses.TryRemove(id, out result);        Events.TryRemove(id, out ev);        return result ?? LogikalMessage.Error("Unknown");    }    private void Client_MessageReceived(object? sender, H.Pipes.Args.ConnectionMessageEventArgs<LogikalMessage?> e)    {        if (Events.TryGetValue(e.Message.ID, out var ev))        {            Responses[e.Message.ID] = e.Message;            ev.Set();        }    }        ~LogikalClient()    {        Dispose();    }    public LogikalStatus Connect()    {        var _request = new LogikalConnectRequest()        {            Path = _settings.Path        };        var _result = Send(_request);        return _result.Status;    }    public LogikalStatus Disconnect()    {        var _request = new LogikalDisconnectRequest();        var _result = Send(_request);        return _result.Status;    }    public LogikalStatus Login()    {        var _request = new LogikalLoginRequest() { UserID = _settings.UserID, Password = _settings.Password };        var _result = Send(_request);        return _result.Status;    }    public LogikalStatus Logout()    {        var _request = new LogikalLogoutRequest();        var _result = Send(_request);        return _result.Status;    }        public IEnumerable<ILogikalProject>? ProjectList()    {        var _request = new LogikalProjectsRequest();        var _result = Send(_request) as LogikalProjectsResponse;        return _result?.Projects;    }            public ILogikalProject? GetProject()    {        var _request = new LogikalProjectsRequest();        var _result = Send(_request) as LogikalProjectResponse;        return _result?.Project;    }        public ILogikalElevation? GetElevation()    {        var _request = new LogikalElevationRequest();        var _result = Send(_request) as LogikalElevationResponse;        return _result?.Elevation;    }        }
 |