Undo/Snapshots, fixes #118

This commit is contained in:
Simon Robertshaw 2012-08-16 22:03:40 +01:00
parent f19c7f62c7
commit edad8f46af
8 changed files with 166 additions and 6 deletions

View File

@ -23,6 +23,7 @@
#include "save/LocalSaveActivity.h"
#include "save/ServerSaveActivity.h"
#include "interface/Keys.h"
#include "simulation/Snapshot.h"
using namespace std;
@ -187,6 +188,40 @@ GameController::~GameController()
delete gameView;
}
void GameController::HistoryRestore()
{
std::deque<Snapshot*> history = gameModel->GetHistory();
if(history.size())
{
Snapshot * snap = history.back();
gameModel->GetSimulation()->Restore(*snap);
if(history.size()>1)
{
history.pop_back();
delete snap;
gameModel->SetHistory(history);
}
}
}
void GameController::HistorySnapshot()
{
std::deque<Snapshot*> history = gameModel->GetHistory();
Snapshot * newSnap = gameModel->GetSimulation()->CreateSnapshot();
if(newSnap)
{
if(history.size() >= 1) //History limit is current 1
{
Snapshot * snap = history.front();
history.pop_front();
//snap->Particles.clear();
delete snap;
}
history.push_back(newSnap);
gameModel->SetHistory(history);
}
}
GameView * GameController::GetView()
{
return gameView;

View File

@ -69,6 +69,9 @@ public:
void Install();
void HistoryRestore();
void HistorySnapshot();
void AdjustGridSize(int direction);
void InvertAirSim();
void LoadRenderPreset(RenderPreset preset);

View File

@ -253,6 +253,15 @@ void GameModel::BuildMenus()
notifyLastToolChanged();
}
std::deque<Snapshot*> GameModel::GetHistory()
{
return history;
}
void GameModel::SetHistory(std::deque<Snapshot*> newHistory)
{
history = newHistory;
}
void GameModel::SetVote(int direction)
{
if(currentSave)

View File

@ -57,6 +57,7 @@ private:
bool colourSelector;
ui::Colour colour;
float toolStrength;
std::deque<Snapshot*> history;
std::string infoTip;
std::string toolTip;
@ -100,6 +101,9 @@ public:
void BuildMenus();
void BuildQuickOptionMenu();
std::deque<Snapshot*> GetHistory();
void SetHistory(std::deque<Snapshot*> newHistory);
void UpdateQuickOptions();
void SetToolStrength(float value);

View File

@ -984,6 +984,8 @@ void GameView::OnMouseDown(int x, int y, unsigned button)
if(button == BUTTON_MIDDLE)
toolIndex = 2;
isMouseDown = true;
if(!pointQueue.size())
c->HistorySnapshot();
if(drawMode == DrawRect || drawMode == DrawLine)
{
drawPoint1 = ui::Point(x, y);
@ -1230,9 +1232,16 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool
c->ChangeBrush();
break;
case 'z':
if(ctrl)
{
c->HistoryRestore();
}
else
{
isMouseDown = false;
zoomCursorFixed = false;
c->SetZoomEnabled(true);
}
break;
case '`':
c->ShowConsole();
@ -1384,8 +1393,11 @@ void GameView::OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bo
disableShiftBehaviour();
break;
case 'z':
if(!ctrl)
{
if(!zoomCursorFixed && !alt)
c->SetZoomEnabled(false);
}
break;
}
}

View File

@ -16,6 +16,7 @@
#include "game/Brush.h"
#include "client/GameSave.h"
#include "Sample.h"
#include "Snapshot.h"
//#include "StorageClasses.h"
#undef LUACONSOLE
@ -214,6 +215,44 @@ GameSave * Simulation::Save(int fullX, int fullY, int fullX2, int fullY2)
return newSave;
}
Snapshot * Simulation::CreateSnapshot()
{
Snapshot * snap = new Snapshot();
snap->AirPressure.insert(snap->AirPressure.begin(), &pv[0][0], &pv[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->AirVelocityX.insert(snap->AirVelocityX.begin(), &vx[0][0], &vx[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->AirVelocityY.insert(snap->AirVelocityY.begin(), &vy[0][0], &vy[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->Particles.insert(snap->Particles.begin(), parts, parts+NPART);
snap->PortalParticles.insert(snap->PortalParticles.begin(), &portalp[0][0][0], &portalp[CHANNELS-1][8-1][80-1]);
snap->WirelessData.insert(snap->WirelessData.begin(), &wireless[0][0], &wireless[CHANNELS-1][2-1]);
snap->GravVelocityX.insert(snap->GravVelocityX.begin(), gravx, gravx+((XRES/CELL)*(YRES/CELL)));
snap->GravVelocityY.insert(snap->GravVelocityY.begin(), gravy, gravy+((XRES/CELL)*(YRES/CELL)));
snap->GravValue.insert(snap->GravValue.begin(), gravp, gravp+((XRES/CELL)*(YRES/CELL)));
snap->GravMap.insert(snap->GravMap.begin(), gravmap, gravmap+((XRES/CELL)*(YRES/CELL)));
snap->BlockMap.insert(snap->BlockMap.begin(), &bmap[0][0], &bmap[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->ElecMap.insert(snap->ElecMap.begin(), &emap[0][0], &emap[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->FanVelocityX.insert(snap->FanVelocityX.begin(), &fvx[0][0], &fvx[0][0]+((XRES/CELL)*(YRES/CELL)));
snap->FanVelocityY.insert(snap->FanVelocityY.begin(), &fvy[0][0], &fvy[0][0]+((XRES/CELL)*(YRES/CELL)));
return snap;
}
void Simulation::Restore(const Snapshot & snap)
{
std::copy(snap.AirPressure.begin(), snap.AirPressure.end(), &pv[0][0]);
std::copy(snap.AirVelocityX.begin(), snap.AirVelocityX.end(), &vx[0][0]);
std::copy(snap.AirVelocityY.begin(), snap.AirVelocityY.end(), &vy[0][0]);
std::copy(snap.Particles.begin(), snap.Particles.end(), parts);
std::copy(snap.PortalParticles.begin(), snap.PortalParticles.end(), &portalp[0][0][0]);
std::copy(snap.WirelessData.begin(), snap.WirelessData.end(), &wireless[0][0]);
std::copy(snap.GravVelocityX.begin(), snap.GravVelocityX.end(), gravx);
std::copy(snap.GravVelocityY.begin(), snap.GravVelocityY.end(), gravy);
std::copy(snap.GravValue.begin(), snap.GravValue.end(), gravp);
std::copy(snap.GravMap.begin(), snap.GravMap.end(), gravmap);
std::copy(snap.BlockMap.begin(), snap.BlockMap.end(), &bmap[0][0]);
std::copy(snap.ElecMap.begin(), snap.ElecMap.end(), &emap[0][0]);
std::copy(snap.FanVelocityX.begin(), snap.FanVelocityX.end(), &fvx[0][0]);
std::copy(snap.FanVelocityY.begin(), snap.FanVelocityY.end(), &fvy[0][0]);
}
/*int Simulation::Load(unsigned char * data, int dataLength)
{
return SaveLoader::Load(data, dataLength, this, true, 0, 0);

View File

@ -23,6 +23,7 @@
#define CHANNELS ((int)(MAX_TEMP-73)/100+2)
class Snapshot;
class Element;
class SimTool;
class Brush;
@ -122,6 +123,10 @@ public:
GameSave * Save();
GameSave * Save(int x1, int y1, int x2, int y2);
SimulationSample Get(int x, int y);
Snapshot * CreateSnapshot();
void Restore(const Snapshot & snap);
inline int is_blocking(int t, int x, int y);
inline int is_boundary(int pt, int x, int y);
inline int find_next_boundary(int pt, int *x, int *y, int dm, int *em);

53
src/simulation/Snapshot.h Normal file
View File

@ -0,0 +1,53 @@
#pragma once
#include <vector>
#include "Particle.h"
class Snapshot
{
public:
std::vector<float> AirPressure;
std::vector<float> AirVelocityX;
std::vector<float> AirVelocityY;
std::vector<Particle> Particles;
std::vector<Particle> PortalParticles;
std::vector<int> WirelessData;
std::vector<float> GravVelocityX;
std::vector<float> GravVelocityY;
std::vector<float> GravValue;
std::vector<float> GravMap;
std::vector<unsigned char> BlockMap;
std::vector<unsigned char> ElecMap;
std::vector<float> FanVelocityX;
std::vector<float> FanVelocityY;
Snapshot() :
AirPressure(),
AirVelocityX(),
AirVelocityY(),
Particles(),
PortalParticles(),
WirelessData(),
GravVelocityX(),
GravVelocityY(),
GravValue(),
GravMap(),
BlockMap(),
ElecMap(),
FanVelocityX(),
FanVelocityY()
{
}
virtual ~Snapshot()
{
}
};