Merge lp:~widelands-dev/widelands/lua_mapview_persistence into lp:widelands
- lua_mapview_persistence
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merge reported by: | SirVer | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~widelands-dev/widelands/lua_mapview_persistence | ||||
Merge into: | lp:widelands | ||||
Diff against target: |
438 lines (+25/-156) 7 files modified
src/game_io/game_interactive_player_data_packet.cc (+0/-114) src/game_io/game_interactive_player_data_packet.h (+0/-38) src/game_io/game_loader.cc (+2/-2) src/game_io/game_saver.cc (+2/-2) src/scripting/lua_ui.cc (+7/-0) src/scripting/lua_ui.h (+3/-0) test/lua/persistence.wmf/scripting/init.lua (+11/-0) |
||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/lua_mapview_persistence | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
SirVer | Approve | ||
Review via email: mp+177251@code.launchpad.net |
Commit message
Description of the change
This is first attempt to persist the mapview. I thought that census and statistics test failed, but after merging trunk and testing again the test seems to pass now - I have no idea why.
I also tried to reproduce the bug as explained in the report, and could not trigger the crash, even on empire 2.
cghislai (charlyghislain) wrote : | # |
I think so. but, then, the fix is already there, as I think mapview saves the state (census/
So, in this case, the L_Mapview class shoud override __persits/
Now for the other window, that would need another data paquet class, which would look for UniqueWindow registries, or buildingwindows serials, or field windows coords, and save positions and so. I am not sure for the scripted windows though.
SirVer (sirver) wrote : | # |
>
> So, in this case, the L_Mapview class shoud override __persits/
> and make sure the pointer is correct upon loading (or it is not even needed?).
I think nothing is needed - just two empty functions.
> Now for the other window, that would need another data paquet class, which
> would look for UniqueWindow registries, or buildingwindows serials, or field
> windows coords, and save positions and so.
the unique windows would need special treatment. Building windows would need special treatment. And mission texts would be very difficult to get right. Starting with the unique windows would be a possiblity, but I think all of this is pretty low priority right now.
> I am not sure for the scripted windows though.
SirVer (sirver) wrote : | # |
btw, is this ready for review too?
cghislai (charlyghislain) wrote : | # |
Yes it is. I just needed to restore the m_panel pointer in the __unpersist method.
SirVer (sirver) wrote : | # |
I think this is the very right approach to doing this. I am still in the USA right now, and pretty loaded, so I am still slow to review code. However one thing immediately: game_mapview_
SirVer (sirver) : | # |
cghislai (charlyghislain) wrote : | # |
I revert the renaming interactiveplay
Speaking of which, does game.get_ibase() sometimes return null? Here the check is made, but I remember some place in the code where it assumed the pointed object exists.
SirVer (sirver) wrote : | # |
I applied a diff of this to trunk and committed this as a new revision. That means your editing history is gone, but I didn't feel comfortable having this removed and added of the same file in the same commit - I do not trust bzr this far :).
This is therefore merged, i.e. it's content is in trunk.
Preview Diff
1 | === added file 'src/game_io/game_interactive_player_data_packet.cc' |
2 | --- src/game_io/game_interactive_player_data_packet.cc 1970-01-01 00:00:00 +0000 |
3 | +++ src/game_io/game_interactive_player_data_packet.cc 2013-08-01 08:24:32 +0000 |
4 | @@ -0,0 +1,116 @@ |
5 | +/* |
6 | + * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team |
7 | + * |
8 | + * This program is free software; you can redistribute it and/or |
9 | + * modify it under the terms of the GNU General Public License |
10 | + * as published by the Free Software Foundation; either version 2 |
11 | + * of the License, or (at your option) any later version. |
12 | + * |
13 | + * This program is distributed in the hope that it will be useful, |
14 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | + * GNU General Public License for more details. |
17 | + * |
18 | + * You should have received a copy of the GNU General Public License |
19 | + * along with this program; if not, write to the Free Software |
20 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
21 | + * |
22 | + */ |
23 | + |
24 | +#include "game_io/game_interactive_player_data_packet.h" |
25 | + |
26 | +#include "logic/game.h" |
27 | +#include "logic/game_data_error.h" |
28 | +#include "logic/player.h" |
29 | +#include "logic/tribe.h" |
30 | +#include "logic/widelands_fileread.h" |
31 | +#include "logic/widelands_filewrite.h" |
32 | +#include "wui/interactive_player.h" |
33 | +#include "wui/mapview.h" |
34 | +#include "wui/overlay_manager.h" |
35 | + |
36 | +namespace Widelands { |
37 | + |
38 | +#define CURRENT_PACKET_VERSION 2 |
39 | + |
40 | + |
41 | +void Game_Interactive_Player_Data_Paquet::Read |
42 | + (FileSystem & fs, Game & game, Map_Map_Object_Loader *) |
43 | +{ |
44 | + try { |
45 | + FileRead fr; |
46 | + fr.Open(fs, "binary/interactive_player"); |
47 | + uint16_t const packet_version = fr.Unsigned16(); |
48 | + if (packet_version == CURRENT_PACKET_VERSION) { |
49 | + Player_Number player_number = |
50 | + fr.Player_Number8(game.map().get_nrplayers()); |
51 | + if (not game.get_player(player_number)) { |
52 | + // This happens if the player, that saved the game, was a spectator |
53 | + // and the slot for player 1 was not used in the game. |
54 | + // So now we try to create an InteractivePlayer object for another |
55 | + // player instead. |
56 | + const Player_Number max = game.map().get_nrplayers(); |
57 | + for (player_number = 1; player_number <= max; ++player_number) |
58 | + if (game.get_player(player_number)) |
59 | + break; |
60 | + if (player_number > max) |
61 | + throw game_data_error(_("The game has no players!")); |
62 | + } |
63 | + int32_t const x = fr.Unsigned16(); |
64 | + int32_t const y = fr.Unsigned16(); |
65 | + uint32_t const display_flags = fr.Unsigned32(); |
66 | + |
67 | + if (Interactive_Base * const ibase = game.get_ibase()) { |
68 | + ibase->set_viewpoint(Point(x, y), true); |
69 | + |
70 | + uint32_t const loaded_df = |
71 | + Interactive_Base::dfShowCensus | |
72 | + Interactive_Base::dfShowStatistics; |
73 | + uint32_t const olddf = ibase->get_display_flags(); |
74 | + uint32_t const realdf = |
75 | + (olddf & ~loaded_df) | (display_flags & loaded_df); |
76 | + ibase->set_display_flags(realdf); |
77 | + } |
78 | + if (Interactive_Player * const ipl = game.get_ipl()) { |
79 | + ipl->set_player_number(player_number); |
80 | + } |
81 | + } else |
82 | + throw game_data_error |
83 | + (_("unknown/unhandled version %u"), packet_version); |
84 | + } catch (const _wexception & e) { |
85 | + throw game_data_error(_("interactive player: %s"), e.what()); |
86 | + } |
87 | +} |
88 | + |
89 | +/* |
90 | + * Write Function |
91 | + */ |
92 | +void Game_Interactive_Player_Data_Paquet::Write |
93 | + (FileSystem & fs, Game & game, Map_Map_Object_Saver * const) |
94 | +{ |
95 | + FileWrite fw; |
96 | + |
97 | + // Now packet version |
98 | + fw.Unsigned16(CURRENT_PACKET_VERSION); |
99 | + |
100 | + Interactive_Base * const ibase = game.get_ibase(); |
101 | + Interactive_Player * const iplayer = game.get_ipl(); |
102 | + |
103 | + // Player number |
104 | + fw.Unsigned8(iplayer ? iplayer->player_number() : 1); |
105 | + |
106 | + // Map Position |
107 | + if (ibase) { |
108 | + assert(0 <= ibase->get_viewpoint().x); |
109 | + assert(0 <= ibase->get_viewpoint().y); |
110 | + } |
111 | + fw.Unsigned16(ibase ? ibase->get_viewpoint().x : 0); |
112 | + fw.Unsigned16(ibase ? ibase->get_viewpoint().y : 0); |
113 | + |
114 | + // Display flags |
115 | + fw.Unsigned32(ibase ? ibase->get_display_flags() : 0); |
116 | + |
117 | + fw.Write(fs, "binary/interactive_player"); |
118 | +} |
119 | + |
120 | +} |
121 | |
122 | === removed file 'src/game_io/game_interactive_player_data_packet.cc' |
123 | --- src/game_io/game_interactive_player_data_packet.cc 2013-07-26 20:19:36 +0000 |
124 | +++ src/game_io/game_interactive_player_data_packet.cc 1970-01-01 00:00:00 +0000 |
125 | @@ -1,114 +0,0 @@ |
126 | -/* |
127 | - * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team |
128 | - * |
129 | - * This program is free software; you can redistribute it and/or |
130 | - * modify it under the terms of the GNU General Public License |
131 | - * as published by the Free Software Foundation; either version 2 |
132 | - * of the License, or (at your option) any later version. |
133 | - * |
134 | - * This program is distributed in the hope that it will be useful, |
135 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
136 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
137 | - * GNU General Public License for more details. |
138 | - * |
139 | - * You should have received a copy of the GNU General Public License |
140 | - * along with this program; if not, write to the Free Software |
141 | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
142 | - * |
143 | - */ |
144 | - |
145 | -#include "game_io/game_interactive_player_data_packet.h" |
146 | - |
147 | -#include "logic/game.h" |
148 | -#include "logic/game_data_error.h" |
149 | -#include "logic/player.h" |
150 | -#include "logic/tribe.h" |
151 | -#include "logic/widelands_fileread.h" |
152 | -#include "logic/widelands_filewrite.h" |
153 | -#include "wui/interactive_player.h" |
154 | -#include "wui/mapview.h" |
155 | -#include "wui/overlay_manager.h" |
156 | - |
157 | -namespace Widelands { |
158 | - |
159 | -#define CURRENT_PACKET_VERSION 2 |
160 | - |
161 | - |
162 | -void Game_Interactive_Player_Data_Packet::Read |
163 | - (FileSystem & fs, Game & game, Map_Map_Object_Loader *) |
164 | -{ |
165 | - try { |
166 | - FileRead fr; |
167 | - fr.Open(fs, "binary/interactive_player"); |
168 | - uint16_t const packet_version = fr.Unsigned16(); |
169 | - if (packet_version == CURRENT_PACKET_VERSION) { |
170 | - Player_Number player_number = |
171 | - fr.Player_Number8(game.map().get_nrplayers()); |
172 | - if (not game.get_player(player_number)) { |
173 | - // This happens if the player, that saved the game, was a spectator |
174 | - // and the slot for player 1 was not used in the game. |
175 | - // So now we try to create an InteractivePlayer object for another |
176 | - // player instead. |
177 | - const Player_Number max = game.map().get_nrplayers(); |
178 | - for (player_number = 1; player_number <= max; ++player_number) |
179 | - if (game.get_player(player_number)) |
180 | - break; |
181 | - if (player_number > max) |
182 | - throw game_data_error(_("The game has no players!")); |
183 | - } |
184 | - int32_t const x = fr.Unsigned16(); |
185 | - int32_t const y = fr.Unsigned16(); |
186 | - uint32_t const display_flags = fr.Unsigned32(); |
187 | - |
188 | - if (Interactive_Player * const plr = game.get_ipl()) { |
189 | - plr->set_player_number(player_number); |
190 | - |
191 | - plr->set_viewpoint(Point(x, y), true); |
192 | - |
193 | - uint32_t const loaded_df = |
194 | - Interactive_Base::dfShowCensus | |
195 | - Interactive_Base::dfShowStatistics; |
196 | - uint32_t const olddf = plr->get_display_flags(); |
197 | - uint32_t const realdf = |
198 | - (olddf & ~loaded_df) | (display_flags & loaded_df); |
199 | - plr->set_display_flags(realdf); |
200 | - } |
201 | - } else |
202 | - throw game_data_error |
203 | - (_("unknown/unhandled version %u"), packet_version); |
204 | - } catch (const _wexception & e) { |
205 | - throw game_data_error(_("interactive player: %s"), e.what()); |
206 | - } |
207 | -} |
208 | - |
209 | -/* |
210 | - * Write Function |
211 | - */ |
212 | -void Game_Interactive_Player_Data_Packet::Write |
213 | - (FileSystem & fs, Game & game, Map_Map_Object_Saver * const) |
214 | -{ |
215 | - FileWrite fw; |
216 | - |
217 | - // Now packet version |
218 | - fw.Unsigned16(CURRENT_PACKET_VERSION); |
219 | - |
220 | - Interactive_Player * const plr = game.get_ipl(); |
221 | - |
222 | - // Player number |
223 | - fw.Unsigned8(plr ? plr->player_number() : 1); |
224 | - |
225 | - // Map Position |
226 | - if (plr) { |
227 | - assert(0 <= plr->get_viewpoint().x); |
228 | - assert(0 <= plr->get_viewpoint().y); |
229 | - } |
230 | - fw.Unsigned16(plr ? plr->get_viewpoint().x : 0); |
231 | - fw.Unsigned16(plr ? plr->get_viewpoint().y : 0); |
232 | - |
233 | - // Display flags |
234 | - fw.Unsigned32(plr ? plr->get_display_flags() : 0); |
235 | - |
236 | - fw.Write(fs, "binary/interactive_player"); |
237 | -} |
238 | - |
239 | -} |
240 | |
241 | === added file 'src/game_io/game_interactive_player_data_packet.h' |
242 | --- src/game_io/game_interactive_player_data_packet.h 1970-01-01 00:00:00 +0000 |
243 | +++ src/game_io/game_interactive_player_data_packet.h 2013-08-01 08:24:32 +0000 |
244 | @@ -0,0 +1,38 @@ |
245 | +/* |
246 | + * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team |
247 | + * |
248 | + * This program is free software; you can redistribute it and/or |
249 | + * modify it under the terms of the GNU General Public License |
250 | + * as published by the Free Software Foundation; either version 2 |
251 | + * of the License, or (at your option) any later version. |
252 | + * |
253 | + * This program is distributed in the hope that it will be useful, |
254 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
255 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
256 | + * GNU General Public License for more details. |
257 | + * |
258 | + * You should have received a copy of the GNU General Public License |
259 | + * along with this program; if not, write to the Free Software |
260 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
261 | + * |
262 | + */ |
263 | + |
264 | +#ifndef GAME_INTERACTIVE_PLAYER_DATA_PACKET_H |
265 | +#define GAME_INTERACTIVE_PLAYER_DATA_PACKET_H |
266 | + |
267 | +#include "game_io/game_data_packet.h" |
268 | + |
269 | +namespace Widelands { |
270 | + |
271 | +/* |
272 | + * Information about the interactive player. Mostly scrollpos, |
273 | + * player number and so on |
274 | + */ |
275 | +struct Game_Interactive_Player_Data_Paquet : public Game_Data_Packet { |
276 | + void Read (FileSystem &, Game &, Map_Map_Object_Loader * = 0); |
277 | + void Write(FileSystem &, Game &, Map_Map_Object_Saver * = 0); |
278 | +}; |
279 | + |
280 | +} |
281 | + |
282 | +#endif |
283 | |
284 | === removed file 'src/game_io/game_interactive_player_data_packet.h' |
285 | --- src/game_io/game_interactive_player_data_packet.h 2013-07-26 20:19:36 +0000 |
286 | +++ src/game_io/game_interactive_player_data_packet.h 1970-01-01 00:00:00 +0000 |
287 | @@ -1,38 +0,0 @@ |
288 | -/* |
289 | - * Copyright (C) 2002-2004, 2006-2009 by the Widelands Development Team |
290 | - * |
291 | - * This program is free software; you can redistribute it and/or |
292 | - * modify it under the terms of the GNU General Public License |
293 | - * as published by the Free Software Foundation; either version 2 |
294 | - * of the License, or (at your option) any later version. |
295 | - * |
296 | - * This program is distributed in the hope that it will be useful, |
297 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
298 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
299 | - * GNU General Public License for more details. |
300 | - * |
301 | - * You should have received a copy of the GNU General Public License |
302 | - * along with this program; if not, write to the Free Software |
303 | - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
304 | - * |
305 | - */ |
306 | - |
307 | -#ifndef GAME_INTERACTIVE_PLAYER_DATA_PACKET_H |
308 | -#define GAME_INTERACTIVE_PLAYER_DATA_PACKET_H |
309 | - |
310 | -#include "game_io/game_data_packet.h" |
311 | - |
312 | -namespace Widelands { |
313 | - |
314 | -/* |
315 | - * Information about the interactive player. Mostly scrollpos, |
316 | - * player number and so on |
317 | - */ |
318 | -struct Game_Interactive_Player_Data_Packet : public Game_Data_Packet { |
319 | - void Read (FileSystem &, Game &, Map_Map_Object_Loader * = 0); |
320 | - void Write(FileSystem &, Game &, Map_Map_Object_Saver * = 0); |
321 | -}; |
322 | - |
323 | -} |
324 | - |
325 | -#endif |
326 | |
327 | === modified file 'src/game_io/game_loader.cc' |
328 | --- src/game_io/game_loader.cc 2013-07-27 15:09:18 +0000 |
329 | +++ src/game_io/game_loader.cc 2013-08-01 08:24:32 +0000 |
330 | @@ -24,8 +24,8 @@ |
331 | |
332 | #include "game_io/game_cmd_queue_data_packet.h" |
333 | #include "game_io/game_game_class_data_packet.h" |
334 | +#include "game_io/game_map_data_packet.h" |
335 | #include "game_io/game_interactive_player_data_packet.h" |
336 | -#include "game_io/game_map_data_packet.h" |
337 | #include "game_io/game_player_economies_data_packet.h" |
338 | #include "game_io/game_player_info_data_packet.h" |
339 | #include "game_io/game_preload_data_packet.h" |
340 | @@ -126,7 +126,7 @@ |
341 | // player. |
342 | if (!multiplayer) { |
343 | log("Game: Reading Interactive Player Data ... "); |
344 | - {Game_Interactive_Player_Data_Packet p; p.Read(m_fs, m_game, mol);} |
345 | + {Game_Interactive_Player_Data_Paquet p; p.Read(m_fs, m_game, mol);} |
346 | log(" done\n"); |
347 | } |
348 | |
349 | |
350 | === modified file 'src/game_io/game_saver.cc' |
351 | --- src/game_io/game_saver.cc 2013-07-26 20:19:36 +0000 |
352 | +++ src/game_io/game_saver.cc 2013-08-01 08:24:32 +0000 |
353 | @@ -21,8 +21,8 @@ |
354 | |
355 | #include "game_io/game_cmd_queue_data_packet.h" |
356 | #include "game_io/game_game_class_data_packet.h" |
357 | +#include "game_io/game_map_data_packet.h" |
358 | #include "game_io/game_interactive_player_data_packet.h" |
359 | -#include "game_io/game_map_data_packet.h" |
360 | #include "game_io/game_player_economies_data_packet.h" |
361 | #include "game_io/game_player_info_data_packet.h" |
362 | #include "game_io/game_preload_data_packet.h" |
363 | @@ -70,7 +70,7 @@ |
364 | log(" done\n"); |
365 | |
366 | log("Game: Writing Interactive Player Data ... "); |
367 | - {Game_Interactive_Player_Data_Packet p; p.Write(m_fs, m_game, mos);} |
368 | + {Game_Interactive_Player_Data_Paquet p; p.Write(m_fs, m_game, mos);} |
369 | log(" done\n"); |
370 | } |
371 | |
372 | |
373 | === modified file 'src/scripting/lua_ui.cc' |
374 | --- src/scripting/lua_ui.cc 2013-07-26 20:19:36 +0000 |
375 | +++ src/scripting/lua_ui.cc 2013-08-01 08:24:32 +0000 |
376 | @@ -25,6 +25,7 @@ |
377 | #include "logic/player.h" |
378 | #include "scripting/c_utils.h" |
379 | #include "scripting/lua_map.h" |
380 | +#include "scripting/luna.h" |
381 | #include "upcast.h" |
382 | #include "wui/interactive_player.h" |
383 | |
384 | @@ -525,6 +526,12 @@ |
385 | L_Panel(get_egbase(L).get_ibase()) { |
386 | } |
387 | |
388 | +void L_MapView::__unpersist(lua_State* L) |
389 | +{ |
390 | + Widelands::Game & game = get_game(L); |
391 | + m_panel = game.get_ibase(); |
392 | +} |
393 | + |
394 | |
395 | /* |
396 | * Properties |
397 | |
398 | === modified file 'src/scripting/lua_ui.h' |
399 | --- src/scripting/lua_ui.h 2013-07-26 20:19:36 +0000 |
400 | +++ src/scripting/lua_ui.h 2013-08-01 08:24:32 +0000 |
401 | @@ -179,6 +179,9 @@ |
402 | L_MapView(lua_State * L); |
403 | virtual ~L_MapView() {} |
404 | |
405 | + virtual void __persist(lua_State * L) {} |
406 | + virtual void __unpersist(lua_State * L); |
407 | + |
408 | /* |
409 | * Properties |
410 | */ |
411 | |
412 | === modified file 'test/lua/persistence.wmf/scripting/init.lua' |
413 | --- test/lua/persistence.wmf/scripting/init.lua 2013-07-19 17:07:41 +0000 |
414 | +++ test/lua/persistence.wmf/scripting/init.lua 2013-08-01 08:24:32 +0000 |
415 | @@ -51,6 +51,12 @@ |
416 | map:get_field(10,10), map:get_field(10,10), map:get_field(10,11) |
417 | } |
418 | |
419 | + mapview = wl.ui.MapView() |
420 | + mapview.viewpoint_x = 10 |
421 | + mapview.viewpoint_y = 40 |
422 | + mapview.statistics = false |
423 | + mapview.census = true |
424 | + |
425 | game:save("lua_persistence") |
426 | print("Save requested\n"); |
427 | |
428 | @@ -121,6 +127,11 @@ |
429 | assert_equal(2, myset.size) |
430 | assert_true(myset:contains(map:get_field(10,10))) |
431 | assert_true(myset:contains(map:get_field(10,11))) |
432 | + mapview = wl.ui.MapView() |
433 | + assert_equal(mapview.viewpoint_x, 10) |
434 | + assert_equal(mapview.viewpoint_y, 40) |
435 | + assert_equal(false, mapview.statistics) |
436 | + assert_equal(true, mapview.census) |
437 | |
438 | print("################### ALL TEST PASS!") |
439 |
I think this is the wrong approach - the LuaClass does not have any data members, so it should not persist anything at all. The MapView (c++ class) should save its data to save games one day, so that you have the same view and so on when loading.
For the Lua fix here, all clases that can get a handle again on the c++ class on a reaload should overwrite the __persists methods which basically does nothing.
The logic here is: if you have a handle to a Window (e.g. a building window of any building) in a lua variable and the game is saved what should the window persist? It cannot reopen the window again after reload (since there is no open_window(name) method), the reloaded game will not have opened the window too, so the variable would contain crap after reloading. For the MapView this is not true: you can always get a hold on the map view again, because there is always a singular one available.
mmh, I fear this was not very well explained. Do you still get what I mean?