#include namespace ntx { NtxCmdList::NtxCmdList() : m_executedCount(0) { setDescription("Multi Command"); } NtxCmdList::NtxCmdList(const NtxString& description) : m_executedCount(0) { setDescription(description); } bool NtxCmdList::execute() { m_executedCount = 0; for (size_t i = 0; i < m_commands.size(); ++i) { if (!m_commands[i]->canExecute()) { rollback(i); return false; } if (!m_commands[i]->execute()) { rollback(i); return false; } m_executedCount++; } return true; } bool NtxCmdList::undo() { if (m_executedCount == 0) return false; for (size_t i = m_executedCount; i > 0; --i) { size_t index = i - 1; if (!m_commands[index]->canUndo()) continue; m_commands[index]->undo(); } m_executedCount = 0; return true; } bool NtxCmdList::canExecute() const { if (m_commands.empty()) return false; for (const auto& cmd : m_commands) { if (!cmd->canExecute()) return false; } return true; } bool NtxCmdList::canUndo() const { if (m_executedCount == 0) return false; for (size_t i = 0; i < m_executedCount; ++i) { if (m_commands[i]->canUndo()) return true; } return false; } NtxString NtxCmdList::getDescription() const { NtxString desc = NtxICommand::getDescription(); if (!desc.empty()) return desc; if (m_commands.empty()) return "Empty Multi Command"; return "Multi Command (" + std::to_string(m_commands.size()) + " commands)"; } void NtxCmdList::addCommand(NtxCommandUPtr command) { if (command) { m_commands.push_back(std::move(command)); } } void NtxCmdList::clear() { m_commands.clear(); m_executedCount = 0; } size_t NtxCmdList::count() const { return m_commands.size(); } bool NtxCmdList::isEmpty() const { return m_commands.empty(); } void NtxCmdList::rollback(size_t upToIndex) { for (size_t i = upToIndex; i > 0; --i) { size_t index = i - 1; if (m_commands[index]->canUndo()) { m_commands[index]->undo(); } } m_executedCount = 0; } } // namespace ntx