/// <summary> /// Push a new state on the stack /// </summary> /// <returns>New state</returns> public State Push() { State state = new State(); // Dequeue already suspended codes first so the correct order is maintained Queue <Code> alreadySuspendedCodes = new Queue <Code>(CurrentState.SuspendedCodes.Count); while (CurrentState.SuspendedCodes.TryDequeue(out Code suspendedCode)) { alreadySuspendedCodes.Enqueue(suspendedCode); } // Suspend the already buffered codes foreach (Code bufferedCode in BufferedCodes) { _logger.Debug("Suspending code {0}", bufferedCode); CurrentState.SuspendedCodes.Enqueue(bufferedCode); } BytesBuffered = 0; BufferedCodes.Clear(); // Add back any codes that were previously suspended while (alreadySuspendedCodes.TryDequeue(out Code suspendedCode)) { CurrentState.SuspendedCodes.Enqueue(suspendedCode); } // Done Stack.Push(state); CurrentState = state; return(state); }
/// <summary> /// Store an enqueued code for transmission to RepRapFirmware /// </summary> /// <param name="queuedCode">Code to transfer</param> /// <returns>True if the code could be buffered</returns> private bool BufferCode(QueuedCode queuedCode) { try { if (Interface.BufferCode(queuedCode, out int codeLength)) { BytesBuffered += codeLength; BufferedCodes.Add(queuedCode); _logger.Debug("Sent {0}, remaining space {1}, needed {2}", queuedCode.Code, Settings.MaxBufferSpacePerChannel - BytesBuffered, codeLength); return(true); } return(false); } catch (Exception e) { _logger.Debug(e, "Failed to buffer code {0}", queuedCode.Code); queuedCode.SetException(e); return(true); } }
/// <summary> /// Push a new state on the stack /// </summary> /// <returns>New state</returns> public State Push() { State state = new State(); // Suspend the remaining buffered codes foreach (Code bufferedCode in BufferedCodes) { _logger.Debug("Suspending code {0}", bufferedCode); CurrentState.SuspendedCodes.Enqueue(bufferedCode); } BytesBuffered = 0; BufferedCodes.Clear(); // Do not send codes to RRF until it has cleared its internal buffer IsBlocked = true; // Done Stack.Push(state); CurrentState = state; return(state); }
/// <summary> /// Handle a G-code reply /// </summary> /// <param name="flags">Message flags</param> /// <param name="reply">Code reply</param> /// <returns>Whether the reply could be processed</returns> public bool HandleReply(MessageTypeFlags flags, string reply) { if (flags.HasFlag(MessageTypeFlags.LogMessage)) { _partialLogMessage += reply; if (!flags.HasFlag(MessageTypeFlags.PushFlag)) { if (!string.IsNullOrWhiteSpace(_partialLogMessage)) { MessageType type = flags.HasFlag(MessageTypeFlags.ErrorMessageFlag) ? MessageType.Error : flags.HasFlag(MessageTypeFlags.WarningMessageFlag) ? MessageType.Warning : MessageType.Success; Utility.Logger.Log(type, _partialLogMessage); } _partialLogMessage = null; } } if (SystemMacroHadError) { SystemMacroHadError = false; return(true); } if (NestedMacros.TryPeek(out MacroFile macroFile)) { if ((macroFile.StartCode != null && !macroFile.StartCode.DoingNestedMacro) || (macroFile.StartCode == null && SystemMacroHasFinished)) { if (macroFile.StartCode != null) { macroFile.StartCode.HandleReply(flags, reply); if (macroFile.IsFinished) { NestedMacros.Pop().Dispose(); _logger.Info("Finished macro file {0}", Path.GetFileName(macroFile.FileName)); if (macroFile.StartCode != null) { _logger.Debug("==> Starting code: {0}", macroFile.StartCode); } } } else if (!flags.HasFlag(MessageTypeFlags.PushFlag)) { NestedMacros.Pop().Dispose(); SystemMacroHasFinished = false; _logger.Info("Finished system macro file {0}", Path.GetFileName(macroFile.FileName)); } return(true); } if (macroFile.StartCode != null) { macroFile.StartCode.HandleReply(flags, reply); } } if (BufferedCodes.Count > 0) { BufferedCodes[0].HandleReply(flags, reply); if (BufferedCodes[0].IsFinished) { BytesBuffered -= BufferedCodes[0].BinarySize; BufferedCodes.RemoveAt(0); } return(true); } // Replies from the code queue or a final empty response from the file are expected if (Channel != CodeChannel.CodeQueue && Channel != CodeChannel.File) { _logger.Warn("Out-of-order reply: '{0}'", reply); } return(false); }