From edad8f46af6cf2403c2ffa77ecfa138ae1b9f8d9 Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Thu, 16 Aug 2012 22:03:40 +0100 Subject: [PATCH] Undo/Snapshots, fixes #118 --- src/game/GameController.cpp | 35 +++++++++++++++++++++++ src/game/GameController.h | 3 ++ src/game/GameModel.cpp | 9 ++++++ src/game/GameModel.h | 4 +++ src/game/GameView.cpp | 22 +++++++++++---- src/simulation/Simulation.cpp | 41 ++++++++++++++++++++++++++- src/simulation/Simulation.h | 5 ++++ src/simulation/Snapshot.h | 53 +++++++++++++++++++++++++++++++++++ 8 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 src/simulation/Snapshot.h diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index 5237af71e..91c64c044 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -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 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 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; diff --git a/src/game/GameController.h b/src/game/GameController.h index c6d41b515..625ab60f3 100644 --- a/src/game/GameController.h +++ b/src/game/GameController.h @@ -69,6 +69,9 @@ public: void Install(); + void HistoryRestore(); + void HistorySnapshot(); + void AdjustGridSize(int direction); void InvertAirSim(); void LoadRenderPreset(RenderPreset preset); diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp index 9505397ce..8512a9aab 100644 --- a/src/game/GameModel.cpp +++ b/src/game/GameModel.cpp @@ -253,6 +253,15 @@ void GameModel::BuildMenus() notifyLastToolChanged(); } +std::deque GameModel::GetHistory() +{ + return history; +} +void GameModel::SetHistory(std::deque newHistory) +{ + history = newHistory; +} + void GameModel::SetVote(int direction) { if(currentSave) diff --git a/src/game/GameModel.h b/src/game/GameModel.h index 33cf1195f..0531f87a4 100644 --- a/src/game/GameModel.h +++ b/src/game/GameModel.h @@ -57,6 +57,7 @@ private: bool colourSelector; ui::Colour colour; float toolStrength; + std::deque history; std::string infoTip; std::string toolTip; @@ -100,6 +101,9 @@ public: void BuildMenus(); void BuildQuickOptionMenu(); + std::deque GetHistory(); + void SetHistory(std::deque newHistory); + void UpdateQuickOptions(); void SetToolStrength(float value); diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index af13797c8..5b6629b36 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -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': - isMouseDown = false; - zoomCursorFixed = false; - c->SetZoomEnabled(true); + 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(!zoomCursorFixed && !alt) - c->SetZoomEnabled(false); + if(!ctrl) + { + if(!zoomCursorFixed && !alt) + c->SetZoomEnabled(false); + } break; } } diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 2bbef6551..1eb7ed9cc 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -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); @@ -4577,4 +4616,4 @@ Simulation::Simulation(): clear_sim(); grav->gravity_mask(); -} +} \ No newline at end of file diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index b9401ded4..48e06d941 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -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); diff --git a/src/simulation/Snapshot.h b/src/simulation/Snapshot.h new file mode 100644 index 000000000..a1c34faea --- /dev/null +++ b/src/simulation/Snapshot.h @@ -0,0 +1,53 @@ +#pragma once + +#include + +#include "Particle.h" + +class Snapshot +{ +public: + std::vector AirPressure; + std::vector AirVelocityX; + std::vector AirVelocityY; + + std::vector Particles; + std::vector PortalParticles; + + std::vector WirelessData; + + std::vector GravVelocityX; + std::vector GravVelocityY; + std::vector GravValue; + std::vector GravMap; + + std::vector BlockMap; + std::vector ElecMap; + + std::vector FanVelocityX; + std::vector FanVelocityY; + + Snapshot() : + AirPressure(), + AirVelocityX(), + AirVelocityY(), + Particles(), + PortalParticles(), + WirelessData(), + GravVelocityX(), + GravVelocityY(), + GravValue(), + GravMap(), + BlockMap(), + ElecMap(), + FanVelocityX(), + FanVelocityY() + { + + } + + virtual ~Snapshot() + { + + } +}; \ No newline at end of file