예제 #1
0
 /// <summary>
 /// Check if Marlin is being emulated
 /// </summary>
 /// <returns>True if Marlin is being emulated</returns>
 public async Task <bool> EmulatingMarlin()
 {
     using (await Provider.AccessReadOnlyAsync())
     {
         Compatibility compatibility = Provider.Get.Inputs[Channel].Compatibility;
         return(compatibility == Compatibility.Marlin || compatibility == Compatibility.NanoDLP);
     }
 }
예제 #2
0
        /// <summary>
        /// Task that keeps pushing model updates to the client
        /// </summary>
        /// <returns>Task that represents the lifecycle of a connection</returns>
        public override async Task Process()
        {
            try
            {
                // Subscribe to changes in Patch mode
                if (_mode == SubscriptionMode.Patch)
                {
                    Observer.OnPropertyPathChanged += MachineModelPropertyChanged;
                }

                // Get the requested machine model
                byte[] jsonData;
                using (await Provider.AccessReadOnlyAsync())
                {
                    if (_mode == SubscriptionMode.Full || _filters.Length == 0)
                    {
                        jsonData = JsonSerializer.SerializeToUtf8Bytes(Provider.Get, JsonHelper.DefaultJsonOptions);
                    }
                    else
                    {
                        Dictionary <string, object> patchModel = new Dictionary <string, object>();
                        foreach (object[] filter in _filters)
                        {
                            Dictionary <string, object> partialModel = Filter.GetFiltered(filter);
                            Filter.MergeFiltered(patchModel, partialModel);
                        }
                        jsonData = JsonSerializer.SerializeToUtf8Bytes(patchModel, JsonHelper.DefaultJsonOptions);
                    }
                }

                BaseCommand command;
                Type        commandType;
                do
                {
                    // Send new JSON data
                    if (jsonData != null)
                    {
                        await Connection.Send(jsonData);

                        jsonData = null;

                        // Wait for an acknowledgement from the client
                        command = await Connection.ReceiveCommand();

                        commandType = command.GetType();

                        // Make sure the command is supported and permitted
                        if (!SupportedCommands.Contains(commandType))
                        {
                            throw new ArgumentException($"Invalid command {command.Command} (wrong mode?)");
                        }
                        Connection.CheckPermissions(commandType);
                    }

                    // Wait for an object model update to complete
                    using CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(Program.CancellationToken);
                    cts.CancelAfter(Settings.SocketPollInterval);
                    try
                    {
                        await Provider.WaitForUpdate(cts.Token);
                    }
                    catch (OperationCanceledException)
                    {
                        if (!Program.CancellationToken.IsCancellationRequested)
                        {
                            Connection.Poll();
                            continue;
                        }
                        Connection.Logger.Debug("Subscriber connection requested to terminate");
                        throw;
                    }

                    // Get the (diff) JSON
                    if (_mode == SubscriptionMode.Patch)
                    {
                        lock (_patch)
                        {
                            if (_patch.Count > 0)
                            {
                                jsonData = JsonSerializer.SerializeToUtf8Bytes(_patch, JsonHelper.DefaultJsonOptions);
                                _patch.Clear();
                            }
                        }
                    }
                    else
                    {
                        using (await Provider.AccessReadOnlyAsync())
                        {
                            jsonData = JsonSerializer.SerializeToUtf8Bytes(Provider.Get, JsonHelper.DefaultJsonOptions);
                        }
                    }
                }while (!Program.CancellationToken.IsCancellationRequested);
            }
            catch (Exception e)
            {
                // Don't throw this exception if the connection has been termianted
                if (!(e is SocketException))
                {
                    throw;
                }
            }
            finally
            {
                lock (_subscriptions)
                {
                    _subscriptions.Remove(this);
                }

                if (_mode == SubscriptionMode.Patch)
                {
                    Observer.OnPropertyPathChanged -= MachineModelPropertyChanged;
                }
                Connection.Logger.Debug("Subscription processor unregistered");
            }
        }