Advanced Strategic Command
taskcontainer.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.org
3  Copyright (C) 1994-2010 Martin Bickel
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 #include "taskcontainer.h"
22 
23 #include "../gamemap.h"
24 #include "../actions/command.h"
25 #include "../actions/taskinterface.h"
26 
27 
28 static const int yetAnotherTask = 0xbd14cff9;
29 static const int noOtherTasks = 0x339fbb40;
30 
31 
32 
34 {
35  this->gamemap = gamemap;
36 
37  gamemap->sigPlayerTurnHasEnded.connect( sigc::mem_fun( *this, &TaskContainer::endTurn ));
38  gamemap->sigPlayerTurnBegins.connect( sigc::mem_fun( *this, &TaskContainer::startTurn ));
39 }
40 
42 {
43  for ( CommandContainer::iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
44  delete *i;
45 }
46 
47 void TaskContainer::hook( GameMap& gamemap )
48 {
49  gamemap.tasks = new TaskContainer( &gamemap );
50 }
51 
53 {
54  GameMap::sigMapCreation.connect( sigc::ptr_fun( &TaskContainer::hook ));
55  ActionContainer::commitCommand.connect( sigc::ptr_fun( &TaskContainer::getCommand ));
56 
57 }
58 
59 void TaskContainer::endTurn( Player& player )
60 {
61  for ( CommandContainer::iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
62  delete *i;
63  pendingCommands.clear();
64 }
65 
66 
67 void TaskContainer::startTurn( Player& player )
68 {
69 
70  if ( lastPlayer >= 0 ) {
71  /* a player's tasks are submitted at the beginning of the next player's turn,
72  to avoid any timing problems which could cause a task submit happening
73  before the actions are transferred */
74 
75  {
77  memstream.writeInt( noOtherTasks );
78  }
79 
80  delete playerTasks[lastPlayer];
82  newTasks = NULL;
83  lastPlayer = -1;
84  }
85 
86  int p = player.getPosition();
87  if ( playerTasks[p] ) {
88 
89  pendingCommands.clear();
90 
92  int token = stream.readInt();
93  while ( token == yetAnotherTask ) {
94  Command* cmd = dynamic_cast<Command*>( GameAction::readFromStream( stream, gamemap ) );
95  assertOrThrow( cmd != NULL );
96 
97  TaskInterface* ti = dynamic_cast<TaskInterface*>( cmd );
98  if ( !ti )
99  fatalError( "Found a task that does not implement the TaskInterface");
100 
101  ti->rearm();
102 
103  pendingCommands.push_back( cmd );
104  token = stream.readInt();
105  }
106  }
107  delete playerTasks[p];
108  playerTasks[p] = NULL;
109 }
110 
111 
112 
113 void TaskContainer::store( const Command& command )
114 {
115  if ( command.getState() == Command::Run ) {
116  const TaskInterface* ti = dynamic_cast<const TaskInterface*>( &command );
117  if ( ti ) {
118 
119  if ( newTasks == NULL )
121 
123  memstream.writeInt( yetAnotherTask );
124  command.write( memstream, false);
125  lastPlayer = gamemap->actplayer;
126  }
127  }
128 }
129 
131 {
132  CommandContainer::iterator i = find ( pendingCommands.begin(), pendingCommands.end(), cmd );
133  if ( i != pendingCommands.end() )
134  pendingCommands.erase( i );
135 }
136 
137 
138 void TaskContainer::getCommand( GameMap* gamemap, Command& command )
139 {
140  if ( gamemap->tasks ) {
141  TaskContainer* t = dynamic_cast<TaskContainer*>(gamemap->tasks);
142  t->store( command );
143  }
144 }
145 
146 
147 void TaskContainer::write ( tnstream& stream ) const
148 {
149  writeStorage( stream );
150  stream.writeInt( pendingCommands.size() );
151  for ( CommandContainer::const_iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
152  (*i)->write( stream );
153  stream.writeInt( taskMagic );
154 }
155 
156 
158 {
159  readStorage( stream );
160 
161 
162  pendingCommands.clear();
163  int count = stream.readInt();
164  for ( int i = 0; i < count; ++i )
165  pendingCommands.push_back( dynamic_cast<Command*>( GameAction::readFromStream( stream, gamemap )));
166 
167  int magic = stream.readInt();
168  if ( magic != taskMagic )
169  throw new tinvalidversion( stream.getLocation(), taskMagic, magic );
170 
171 }
172 
void readStorage(tnstream &stream)
void read(tnstream &stream)
An in-memory storage of streamed data.
Definition: basestrm.h:172
virtual void writeInt(int i)
Writes a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is p...
Definition: basestrm.cpp:363
static GameAction * readFromStream(tnstream &stream, GameMap *map)
Definition: action.cpp:150
static const int yetAnotherTask
virtual ASCString getLocation()
returns the location of the stream.
Definition: basestrm.cpp:274
virtual int readInt(void)
Reads a 32 bit signed Integer. In the stream little-endian byte order is used and a translation is pe...
Definition: basestrm.cpp:284
int getPosition() const
Definition: player.h:112
#define assertOrThrow(expr)
Definition: errors.h:69
State getState() const
Definition: command.h:125
MemoryStreamStorage * playerTasks[GameMap::maxTotalPlayers]
The interface for all kinds of IO stream.
A Command is an action that the player initiates.
Definition: command.h:114
const int magic
Definition: stack.cpp:36
MemoryStreamStorage * newTasks
void writeStorage(tnstream &stream) const
sigc::signal< void, Player & > sigPlayerTurnHasEnded
Definition: gamemap.h:497
virtual void rearm()=0
Reads data from or writes data to a MemoryStreamStorage This allows a completely volatile storage of ...
Definition: basestrm.h:204
void remove(Command *cmd)
sigc::signal< void, Player & > sigPlayerTurnBegins
Definition: gamemap.h:493
void write(tnstream &stream) const
Definition: action.cpp:145
AbstractTaskContainer * tasks
Definition: gamemap.h:394
signed char actplayer
the player who is currently making his moves (may be human or AI)
Definition: gamemap.h:232
static const int noOtherTasks
static sigc::signal< void, GameMap *, Command & > commitCommand
The command, which has already been executed, is finally commited and will not be undone any more Thi...
the command is completed this turn, but there is still something to do next turn
Definition: command.h:119
CommandContainer pendingCommands
Definition: taskcontainer.h:44
TaskContainer(GameMap *gamemap)
the different players in ASC. There may be 8 players (0..7) and neutral units (8) ...
Definition: player.h:99
void fatalError(const ASCString &string)
static void registerHooks()
void write(tnstream &stream) const
static sigc::signal< void, GameMap & > sigMapCreation
Definition: gamemap.h:500
The map. THE central structure of ASC, which holds everything not globally available together...
Definition: gamemap.h:182