taskcontainer.cpp

Go to the documentation of this file.
00001 /*
00002      This file is part of Advanced Strategic Command; http://www.asc-hq.org
00003      Copyright (C) 1994-2010  Martin Bickel
00004  
00005      This program is free software; you can redistribute it and/or modify
00006      it under the terms of the GNU General Public License as published by
00007      the Free Software Foundation; either version 2 of the License, or
00008      (at your option) any later version.
00009  
00010      This program is distributed in the hope that it will be useful,
00011      but WITHOUT ANY WARRANTY; without even the implied warranty of
00012      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013      GNU General Public License for more details.
00014  
00015      You should have received a copy of the GNU General Public License
00016      along with this program; see the file COPYING. If not, write to the 
00017      Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018      Boston, MA  02111-1307  USA
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       /* a player's tasks are submitted at the beginning of the next player's turn, 
00072          to avoid any timing problems which could cause a task submit happening
00073          before the actions are transferred */
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 

Generated on Mon May 21 01:26:38 2012 for Advanced Strategic Command by  doxygen 1.5.1