/// <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); } }
/// <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"); } }