File indexing completed on 2024-05-12 04:39:43
0001 /* 0002 SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "micommandqueue.h" 0008 0009 #include "mi.h" 0010 #include "micommand.h" 0011 #include "debuglog.h" 0012 0013 using namespace KDevMI::MI; 0014 0015 CommandQueue::CommandQueue() = default; 0016 CommandQueue::~CommandQueue() = default; 0017 0018 void CommandQueue::enqueue(std::unique_ptr<MICommand> command) 0019 { 0020 ++m_tokenCounter; 0021 if (m_tokenCounter == 0) 0022 m_tokenCounter = 1; 0023 command->setToken(m_tokenCounter); 0024 0025 // take the time when this command was added to the command queue 0026 command->markAsEnqueued(); 0027 0028 if (command->flags() & (CmdImmediately | CmdInterrupt)) 0029 ++m_immediatelyCounter; 0030 0031 m_commandList.push_back(std::move(command)); 0032 0033 rationalizeQueue(m_commandList.back().get()); 0034 dumpQueue(); 0035 } 0036 0037 void CommandQueue::dumpQueue() const 0038 { 0039 qCDebug(DEBUGGERCOMMON) << "Pending commands" << m_commandList.size(); 0040 unsigned commandNum = 0; 0041 for (const auto& command : m_commandList) { 0042 qCDebug(DEBUGGERCOMMON) << "Command" << commandNum << command->initialString(); 0043 ++commandNum; 0044 } 0045 } 0046 0047 void CommandQueue::rationalizeQueue(MICommand* command) 0048 { 0049 if ((command->type() >= ExecAbort && command->type() <= ExecUntil) && 0050 command->type() != ExecArguments ) { 0051 // Changing execution location, abort any variable updates and stack list updates 0052 0053 auto predicate = [this](const auto& command) { 0054 const auto type = command->type(); 0055 const auto isVariableUpdate 0056 = (type >= VarEvaluateExpression && type <= VarListChildren) || type == VarUpdate; 0057 const auto isStackListUpdate = type >= StackListArguments && type <= StackListLocals; 0058 if (isVariableUpdate || isStackListUpdate) { 0059 if (command->flags() & (CmdImmediately | CmdInterrupt)) 0060 --m_immediatelyCounter; 0061 return true; 0062 } 0063 return false; 0064 }; 0065 m_commandList.erase(std::remove_if(m_commandList.begin(), m_commandList.end(), predicate), m_commandList.end()); 0066 } 0067 } 0068 0069 void CommandQueue::clear() 0070 { 0071 m_commandList.clear(); 0072 m_immediatelyCounter = 0; 0073 } 0074 0075 int CommandQueue::count() const 0076 { 0077 return m_commandList.size(); 0078 } 0079 0080 bool CommandQueue::isEmpty() const 0081 { 0082 return m_commandList.empty(); 0083 } 0084 0085 bool CommandQueue::haveImmediateCommand() const 0086 { 0087 return m_immediatelyCounter > 0; 0088 } 0089 0090 std::unique_ptr<MICommand> CommandQueue::nextCommand() 0091 { 0092 if (m_commandList.empty()) 0093 return {}; 0094 0095 auto command = std::exchange(m_commandList.front(), {}); 0096 m_commandList.pop_front(); 0097 0098 if (command->flags() & (CmdImmediately | CmdInterrupt)) 0099 --m_immediatelyCounter; 0100 0101 return command; 0102 } 0103