Update ifdef condition for MCST-LCC compiler (E2K)
[0ad.git] / source / tools / atlas / GameInterface / CommandProc.cpp
blob409956c526678282c5270b4b84c337964488a463
1 /* Copyright (C) 2010 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
20 #include "CommandProc.h"
22 #include <cassert>
23 #include <algorithm>
25 //////////////////////////////////////////////////////////////////////////
27 template<typename T> T next_it(T x) { T t = x; return ++t; }
29 template<typename T> void delete_fn(T* v) { delete v; }
31 //////////////////////////////////////////////////////////////////////////
33 using namespace AtlasMessage;
35 namespace AtlasMessage {
37 CommandProc& GetCommandProc()
39 static CommandProc commandProc;
40 return commandProc;
43 cmdHandlers& GetCmdHandlers()
45 static cmdHandlers h;
46 return h;
51 CommandProc::CommandProc()
53 // Start the list with a NULL, so m_CurrentCommand can point at
54 // something even when the command stack is empty
55 m_Commands.push_back(NULL);
57 m_CurrentCommand = m_Commands.begin();
60 CommandProc::~CommandProc()
62 // Make sure Destroy has been called before now (to avoid
63 // problems from the destruction order of static variables)
64 ENSURE(!m_Commands.size());
67 void CommandProc::Destroy()
69 std::for_each(m_Commands.begin(), m_Commands.end(), delete_fn<Command>);
70 m_Commands.clear();
73 void CommandProc::Submit(Command* cmd)
75 // If some commands have been undone at the time we insert this new one,
76 // delete and remove them all.
77 std::for_each(next_it(m_CurrentCommand), m_Commands.end(), delete_fn<Command>);
78 m_Commands.erase(next_it(m_CurrentCommand), m_Commands.end());
79 assert(next_it(m_CurrentCommand) == m_Commands.end());
81 m_CurrentCommand = m_Commands.insert(next_it(m_CurrentCommand), cmd);
83 (*m_CurrentCommand)->Do();
86 void CommandProc::Undo()
88 if (m_CurrentCommand != m_Commands.begin())
90 (*m_CurrentCommand)->Undo();
91 --m_CurrentCommand;
95 void CommandProc::Redo()
97 if (next_it(m_CurrentCommand) != m_Commands.end())
99 ++m_CurrentCommand;
100 (*m_CurrentCommand)->Redo();
104 void CommandProc::Merge()
106 if (m_CurrentCommand == m_Commands.begin())
108 debug_warn(L"Merge illogic: no commands");
109 return;
112 if (next_it(m_CurrentCommand) != m_Commands.end())
114 debug_warn(L"Merge illogic: not at stack top");
115 return;
118 cmdIt prev = m_CurrentCommand;
119 --prev;
121 if (prev == m_Commands.begin())
123 debug_warn(L"Merge illogic: only 1 command");
124 return;
127 if ((*prev)->GetType() != (*m_CurrentCommand)->GetType())
129 const char* a = (*prev)->GetType();
130 const char* b = (*m_CurrentCommand)->GetType();
131 debug_printf("[incompatible: %s -> %s]\n", a, b);
132 debug_warn(L"Merge illogic: incompatible command");
133 return;
136 (*m_CurrentCommand)->Merge(*prev);
138 delete *m_CurrentCommand;
139 m_Commands.erase(m_CurrentCommand);
141 m_CurrentCommand = prev;