Experimental-ish rollback functionality
[oweals/minetest.git] / src / rollback_interface.h
1 /*
2 Minetest-c55
3 Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #ifndef ROLLBACK_INTERFACE_HEADER
21 #define ROLLBACK_INTERFACE_HEADER
22
23 #include "irr_v3d.h"
24 #include <string>
25 #include <iostream>
26 #include "exceptions.h"
27
28 class Map;
29 class IGameDef;
30 struct MapNode;
31 class InventoryManager;
32
33 struct RollbackNode
34 {
35         std::string name;
36         int param1;
37         int param2;
38         std::string meta;
39
40         bool operator==(const RollbackNode &other)
41         {
42                 return (name == other.name && param1 == other.param1 &&
43                                 param2 == other.param2 && meta == other.meta);
44         }
45         bool operator!=(const RollbackNode &other)
46         {
47                 return !(*this == other);
48         }
49
50         RollbackNode():
51                 param1(0),
52                 param2(0)
53         {}
54
55         RollbackNode(Map *map, v3s16 p, IGameDef *gamedef);
56 };
57
58 struct RollbackAction
59 {
60         enum Type{
61                 TYPE_NOTHING,
62                 TYPE_SET_NODE,
63                 TYPE_MODIFY_INVENTORY_STACK,
64         } type;
65
66         int unix_time;
67         std::string actor;
68
69         v3s16 p;
70         RollbackNode n_old;
71         RollbackNode n_new;
72         
73         std::string inventory_location;
74         std::string inventory_list;
75         u32 inventory_index;
76         bool inventory_add;
77         std::string inventory_stack;
78
79         RollbackAction():
80                 type(TYPE_NOTHING)
81         {}
82
83         void setSetNode(v3s16 p_, const RollbackNode &n_old_,
84                         const RollbackNode &n_new_)
85         {
86                 type = TYPE_SET_NODE;
87                 p = p_;
88                 n_old = n_old_;
89                 n_new = n_new_;
90         }
91
92         void setModifyInventoryStack(const std::string &inventory_location_,
93                         const std::string &inventory_list_, int index_,
94                         bool add_, const std::string &inventory_stack_)
95         {
96                 type = TYPE_MODIFY_INVENTORY_STACK;
97                 inventory_location = inventory_location_;
98                 inventory_list = inventory_list_;
99                 inventory_index = index_;
100                 inventory_add = add_;
101                 inventory_stack = inventory_stack_;
102         }
103         
104         // String should not contain newlines or nulls
105         std::string toString() const;
106         void fromStream(std::istream &is) throw(SerializationError);
107         
108         // Eg. flowing water level changes are not important
109         bool isImportant(IGameDef *gamedef) const;
110
111         bool applyRevert(Map *map, InventoryManager *imgr, IGameDef *gamedef) const;
112 };
113
114 class IRollbackReportSink
115 {
116 public:
117         virtual ~IRollbackReportSink(){}
118         virtual void reportAction(const RollbackAction &action) = 0;
119         virtual std::string getActor() = 0;
120         virtual void setActor(const std::string &actor) = 0;
121 };
122
123 class RollbackScopeActor
124 {
125 public:
126         RollbackScopeActor(IRollbackReportSink *sink, const std::string &actor):
127                 m_sink(sink)
128         {
129                 if(m_sink){
130                         m_actor_was = m_sink->getActor();
131                         m_sink->setActor(actor);
132                 }
133         }
134         ~RollbackScopeActor()
135         {
136                 if(m_sink){
137                         m_sink->setActor(m_actor_was);
138                 }
139         }
140 private:
141         IRollbackReportSink *m_sink;
142         std::string m_actor_was;
143 };
144
145 #endif