File indexing completed on 2021-12-21 12:50:20

0001 /*
0002  *  ksokoban - a Sokoban game by KDE
0003  *  Copyright (C) 1998  Anders Widell  <awl@hem.passagen.se>
0004  *
0005  *  This program is free software; you can redistribute it and/or modify
0006  *  it under the terms of the GNU General Public License as published by
0007  *  the Free Software Foundation; either version 2 of the License, or
0008  *  (at your option) any later version.
0009  *
0010  *  This program is distributed in the hope that it will be useful,
0011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  *  GNU General Public License for more details.
0014  *
0015  *  You should have received a copy of the GNU General Public License
0016  *  along with this program; if not, write to the Free Software
0017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
0018  */
0019 
0020 #include <QList>
0021 
0022 #include "History.h"
0023 #include "Move.h"
0024 #include "MoveSequence.h"
0025 #include "LevelMap.h"
0026 
0027 History::History() {
0028   //past_.setAutoDelete(true);
0029   //future_.setAutoDelete(true);
0030 }
0031 History::~History() {
0032     for(QList<Move*>::iterator it=past_.begin(); it!=past_.end(); it++)
0033         delete *it;
0034     for(QList<Move*>::iterator it=future_.begin(); it!=future_.end(); it++)
0035         delete *it;
0036 }
0037 
0038 void
0039 History::add(Move *_m) {
0040   future_.clear();
0041   past_.append(_m);
0042 }
0043 
0044 void
0045 History::clear() {
0046   past_.clear();
0047   future_.clear();
0048 }
0049 
0050 void
0051 History::save(QString &_str) {
0052   
0053 
0054   for(QList<Move*>::Iterator iterator = past_.begin(); iterator != past_.end(); ++iterator) {
0055     (*iterator)->save(_str);
0056   }
0057   _str += '-';
0058 
0059   
0060   for(QList<Move*>::Iterator iterator = future_.begin(); iterator != future_.end(); ++iterator) {
0061     (*iterator)->save(_str);
0062   }
0063 }
0064 
0065 const char *
0066 History::load(LevelMap *map, const char *_str) {
0067   Move *m;
0068   int x = map->xpos();
0069   int y = map->ypos();
0070 
0071   clear();
0072   while (*_str != '\0' && *_str != '-') {
0073     m = new Move(x, y);
0074     _str = m->load(_str);
0075     if (_str == nullptr) return nullptr;
0076     x = m->finalX();
0077     y = m->finalY();
0078     past_.append(m);
0079     if (!m->redo(map)) {
0080       //printf("redo failed: %s\n", _str);
0081       //abort();
0082       return nullptr;
0083     }
0084   }
0085   if (*_str != '-') return nullptr;
0086 
0087   _str++;
0088   while (*_str != '\0') {
0089     m = new Move(x, y);
0090     _str = m->load(_str);
0091     if (_str == nullptr) return nullptr;
0092     x = m->finalX();
0093     y = m->finalY();
0094     future_.append(m);
0095   }
0096 
0097   return _str;
0098 }
0099 
0100 bool
0101 History::redo(LevelMap *map) {
0102   if (future_.isEmpty()) return false;
0103 
0104   Move *m=future_.takeAt(0);
0105   past_.append(m);
0106   return m->redo(map);
0107 }
0108 
0109 MoveSequence *
0110 History::deferRedo(LevelMap *map) {
0111   if (future_.isEmpty()) return nullptr;
0112 
0113   Move *m=future_.takeAt(0);
0114   past_.append(m);
0115   return new MoveSequence(m, map);
0116 }
0117 
0118 bool
0119 History::undo(LevelMap *map) {
0120   if (past_.isEmpty()) return false;
0121 
0122   Move *m = past_.takeAt(past_.count ()-1);
0123   future_.insert(0, m);
0124   return m->undo(map);
0125 }
0126 
0127 MoveSequence *
0128 History::deferUndo(LevelMap *map) {
0129   if (past_.isEmpty()) return nullptr;
0130 
0131   Move *m = past_.takeAt(past_.count()-1);
0132   future_.insert(0, m);
0133   return new MoveSequence(m, map, true);
0134 }