00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "taskcontainer.h"
00022
00023 #include "../gamemap.h"
00024 #include "../actions/command.h"
00025 #include "../actions/taskinterface.h"
00026
00027
00028 static const int yetAnotherTask = 0xbd14cff9;
00029 static const int noOtherTasks = 0x339fbb40;
00030
00031
00032
00033 TaskContainer::TaskContainer( GameMap* gamemap )
00034 {
00035 this->gamemap = gamemap;
00036
00037 gamemap->sigPlayerTurnHasEnded.connect( SigC::slot( *this, &TaskContainer::endTurn ));
00038 gamemap->sigPlayerTurnBegins.connect( SigC::slot( *this, &TaskContainer::startTurn ));
00039 }
00040
00041 TaskContainer::~TaskContainer()
00042 {
00043 for ( CommandContainer::iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
00044 delete *i;
00045 }
00046
00047 void TaskContainer::hook( GameMap& gamemap )
00048 {
00049 gamemap.tasks = new TaskContainer( &gamemap );
00050 }
00051
00052 void TaskContainer::registerHooks()
00053 {
00054 GameMap::sigMapCreation.connect( SigC::slot( &TaskContainer::hook ));
00055 ActionContainer::commitCommand.connect( SigC::slot( &TaskContainer::getCommand ));
00056
00057 }
00058
00059 void TaskContainer::endTurn( Player& player )
00060 {
00061 for ( CommandContainer::iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
00062 delete *i;
00063 pendingCommands.clear();
00064 }
00065
00066
00067 void TaskContainer::startTurn( Player& player )
00068 {
00069
00070 if ( lastPlayer >= 0 ) {
00071
00072
00073
00074
00075 {
00076 MemoryStream memstream( newTasks, tnstream::appending );
00077 memstream.writeInt( noOtherTasks );
00078 }
00079
00080 delete playerTasks[lastPlayer];
00081 playerTasks[lastPlayer] = newTasks;
00082 newTasks = NULL;
00083 lastPlayer = -1;
00084 }
00085
00086 int p = player.getPosition();
00087 if ( playerTasks[p] ) {
00088
00089 pendingCommands.clear();
00090
00091 MemoryStream stream ( playerTasks[p], tnstream::reading );
00092 int token = stream.readInt();
00093 while ( token == yetAnotherTask ) {
00094 Command* cmd = dynamic_cast<Command*>( GameAction::readFromStream( stream, gamemap ) );
00095 assertOrThrow( cmd != NULL );
00096
00097 TaskInterface* ti = dynamic_cast<TaskInterface*>( cmd );
00098 if ( !ti )
00099 fatalError( "Found a task that does not implement the TaskInterface");
00100
00101 ti->rearm();
00102
00103 pendingCommands.push_back( cmd );
00104 token = stream.readInt();
00105 }
00106 }
00107 delete playerTasks[p];
00108 playerTasks[p] = NULL;
00109 }
00110
00111
00112
00113 void TaskContainer::store( const Command& command )
00114 {
00115 if ( command.getState() == Command::Run ) {
00116 const TaskInterface* ti = dynamic_cast<const TaskInterface*>( &command );
00117 if ( ti ) {
00118
00119 if ( newTasks == NULL )
00120 newTasks = new MemoryStreamStorage();
00121
00122 MemoryStream memstream( newTasks, tnstream::appending );
00123 memstream.writeInt( yetAnotherTask );
00124 command.write( memstream, false);
00125 lastPlayer = gamemap->actplayer;
00126 }
00127 }
00128 }
00129
00130 void TaskContainer::remove( Command* cmd )
00131 {
00132 CommandContainer::iterator i = find ( pendingCommands.begin(), pendingCommands.end(), cmd );
00133 if ( i != pendingCommands.end() )
00134 pendingCommands.erase( i );
00135 }
00136
00137
00138 void TaskContainer::getCommand( GameMap* gamemap, Command& command )
00139 {
00140 if ( gamemap->tasks ) {
00141 TaskContainer* t = dynamic_cast<TaskContainer*>(gamemap->tasks);
00142 t->store( command );
00143 }
00144 }
00145
00146
00147 void TaskContainer::write ( tnstream& stream ) const
00148 {
00149 writeStorage( stream );
00150 stream.writeInt( pendingCommands.size() );
00151 for ( CommandContainer::const_iterator i = pendingCommands.begin(); i != pendingCommands.end(); ++i )
00152 (*i)->write( stream );
00153 stream.writeInt( taskMagic );
00154 }
00155
00156
00157 void TaskContainer::read ( tnstream& stream )
00158 {
00159 readStorage( stream );
00160
00161
00162 pendingCommands.clear();
00163 int count = stream.readInt();
00164 for ( int i = 0; i < count; ++i )
00165 pendingCommands.push_back( dynamic_cast<Command*>( GameAction::readFromStream( stream, gamemap )));
00166
00167 int magic = stream.readInt();
00168 if ( magic != taskMagic )
00169 throw new tinvalidversion( stream.getLocation(), taskMagic, magic );
00170
00171 }
00172