Merge lp:~widelands-dev/widelands/memory_leak into lp:widelands
- memory_leak
- Merge into trunk
Status: | Merged | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 7735 | ||||||||||||||||
Proposed branch: | lp:~widelands-dev/widelands/memory_leak | ||||||||||||||||
Merge into: | lp:widelands | ||||||||||||||||
Diff against target: |
539 lines (+140/-142) 6 files modified
src/graphic/rendertarget.cc (+92/-82) src/graphic/rendertarget.h (+8/-6) src/graphic/text/font_io.cc (+1/-1) src/logic/map_objects/world/world.cc (+2/-2) src/ui_basic/table.cc (+5/-19) src/ui_fsmenu/loadgame.cc (+32/-32) |
||||||||||||||||
To merge this branch: | bzr merge lp:~widelands-dev/widelands/memory_leak | ||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
GunChleoc | Approve | ||
Tino | Approve | ||
Review via email: mp+283690@code.launchpad.net |
Commit message
- Fix big memory leak and extra work in UI::Table::draw.
- Fix a couple of minor memory leaks around the code I found using the Leaks tool in Apple's Instruments.
- Correctly crop destination and source rectangle while blitting.
Major leak explanation:
On each frame we created a downscaled texture if the image of a table entry was too small and leaked this texture immediately. This extra scaling work we did there was even unnecessary since OpenGL can scale down images while blitting for free.
Deleted that rescaling code, which makes the texture creation unnecessary, gets rid of the memory leak and also buys CPU cycles since a lot of work is now never done.
Description of the change
bunnybot (widelandsofficial) wrote : | # |
GunChleoc (gunchleoc) wrote : | # |
Have you tested that this doesn't regress https:/
This bug was the reason I stopped using blitrect_scale.
bunnybot (widelandsofficial) wrote : | # |
Travis build 343 has changed state to: errored. Details: https:/
SirVer (sirver) wrote : | # |
> Have you tested that this doesn't regress https:/
No, I did not. It very likely regresses that as blitrect_scale does not change the source rect when cropping. I'll look into that, but I'd like to get https:/
bunnybot (widelandsofficial) wrote : | # |
Travis build 343 has changed state to: passed. Details: https:/
kaputtnik (franku) wrote : | # |
> Have you tested that this doesn't regress https:/
This branch regresses that bug. It looks likes the images are in an additional row. I attached a screenshot to the bug, look : https:/
I am in hurry, want to test further this afternoon.
GunChleoc (gunchleoc) wrote : | # |
The problem is that blitrect_scale doesn't crop.
kaputtnik (franku) wrote : | # |
I get increasing memory for about 30-100k per second. Opening the message window does not increase the memory usage anymore.
All looks good, except the overlapping images in the message menu.
Do not approve, because bug 1522564 is linked here.
SirVer (sirver) wrote : | # |
> I get increasing memory for about 30-100k per second.
Does this ever stop or grow boundless?
I just pushed a commit that should fix bug 1522564 too. This is ready for code review and another round of testing.
kaputtnik (franku) wrote : | # |
It increases boundless. I believe this caused by the wares which are produced... but i am not sure.
Today i have no time anymore for testing.
Tino (tino79) wrote : | # |
I do not experience any more memory leaking on windows.
And no overlapping icons in the message menu.
bunnybot (widelandsofficial) wrote : | # |
Travis build 354 has changed state to: failed. Details: https:/
GunChleoc (gunchleoc) wrote : | # |
Graphics now look OK on Ubuntu. Code LGTM.
Travis fail is because of Codecheck - I fixed all but 1 Codecheck warning in https:/
kaputtnik (franku) wrote : | # |
To fiddle out why the memory increases will take some time. So we could merge this and i open a new bug if i found the something.
SirVer (sirver) wrote : | # |
Widelands is currently not leaking memory during normal gameplay. I checked that yesterday. So the increases you see are probably just due to map objects being created.
I'd still like a code review if possible.
> Am 24.01.2016 um 11:27 schrieb kaputtnik <email address hidden>:
>
> To fiddle out why the memory increases will take some time. So we could merge this and i open a new bug if i found the something.
>
>
> --
> https:/
> You proposed lp:~widelands-dev/widelands/memory_leak for merging.
SirVer (sirver) wrote : | # |
Oh, gun already reviewed the code. did not see that.
@bunnybot merge
kaputtnik (franku) wrote : | # |
> So the increases you see are probably just due to map objects being created.
Yes that is probably be the reason.
Preview Diff
1 | === modified file 'src/graphic/rendertarget.cc' |
2 | --- src/graphic/rendertarget.cc 2016-01-17 19:54:32 +0000 |
3 | +++ src/graphic/rendertarget.cc 2016-01-24 08:40:10 +0000 |
4 | @@ -154,17 +154,13 @@ |
5 | void RenderTarget::blit(const Point& dst, const Image* image, BlendMode blend_mode, UI::Align align) |
6 | { |
7 | Point destination_point(dst); |
8 | - |
9 | UI::correct_for_align(align, image->width(), image->height(), &destination_point); |
10 | |
11 | - Rect srcrc(Point(0, 0), image->width(), image->height()); |
12 | + Rect source_rect(Point(0, 0), image->width(), image->height()); |
13 | + Rect destination_rect(destination_point.x, destination_point.y, source_rect.w, source_rect.h); |
14 | |
15 | - if (to_surface_geometry(&destination_point, &srcrc)) { |
16 | - m_surface->blit(Rect(destination_point.x, destination_point.y, srcrc.w, srcrc.h), |
17 | - *image, |
18 | - srcrc, |
19 | - 1., |
20 | - blend_mode); |
21 | + if (to_surface_geometry(&destination_rect, &source_rect)) { |
22 | + m_surface->blit(destination_rect, *image, source_rect, 1., blend_mode); |
23 | } |
24 | } |
25 | |
26 | @@ -172,14 +168,13 @@ |
27 | const Image* image, |
28 | const RGBAColor& blend_mode, UI::Align align) { |
29 | Point destination_point(dst); |
30 | - |
31 | UI::correct_for_align(align, image->width(), image->height(), &destination_point); |
32 | |
33 | - Rect srcrc(Point(0, 0), image->width(), image->height()); |
34 | + Rect source_rect(Point(0, 0), image->width(), image->height()); |
35 | + Rect destination_rect(destination_point.x, destination_point.y, source_rect.w, source_rect.h); |
36 | |
37 | - if (to_surface_geometry(&destination_point, &srcrc)) { |
38 | - m_surface->blit_monochrome(Rect(destination_point.x, destination_point.y, srcrc.w, srcrc.h), |
39 | - *image, srcrc, blend_mode); |
40 | + if (to_surface_geometry(&destination_rect, &source_rect)) { |
41 | + m_surface->blit_monochrome(destination_rect, *image, source_rect, blend_mode); |
42 | } |
43 | } |
44 | |
45 | @@ -194,49 +189,33 @@ |
46 | |
47 | // We want to use the given srcrc, but we must make sure that we are not |
48 | // blitting outside of the boundaries of 'image'. |
49 | - Rect srcrc(gsrcrc.x, |
50 | + Rect source_rect(gsrcrc.x, |
51 | gsrcrc.y, |
52 | std::min<int32_t>(image->width() - gsrcrc.x, gsrcrc.w), |
53 | std::min<int32_t>(image->height() - gsrcrc.y, gsrcrc.h)); |
54 | + Rect destination_rect(dst.x, dst.y, source_rect.w, source_rect.h); |
55 | |
56 | - Point destination_point(dst); |
57 | - if (to_surface_geometry(&destination_point, &srcrc)) |
58 | - m_surface->blit(Rect(destination_point.x, destination_point.y, srcrc.w, srcrc.h), |
59 | - *image, |
60 | - srcrc, |
61 | - 1., |
62 | - blend_mode); |
63 | + if (to_surface_geometry(&destination_rect, &source_rect)) { |
64 | + m_surface->blit(destination_rect, *image, source_rect, 1., blend_mode); |
65 | + } |
66 | } |
67 | |
68 | -void RenderTarget::blitrect_scale(const Rect& dst, |
69 | +void RenderTarget::blitrect_scale(Rect destination_rect, |
70 | const Image* image, |
71 | - const Rect& source_rect, |
72 | - const float opacity, |
73 | + Rect source_rect, |
74 | + const float opacity, |
75 | const BlendMode blend_mode) { |
76 | - |
77 | - Point destination_point(dst.x, dst.y); |
78 | - Rect srcrect(source_rect); |
79 | - if (to_surface_geometry(&destination_point, &srcrect)) { |
80 | - m_surface->blit(Rect(destination_point.x, destination_point.y, dst.w, dst.h), |
81 | - *image, |
82 | - source_rect, |
83 | - opacity, |
84 | - blend_mode); |
85 | + if (to_surface_geometry(&destination_rect, &source_rect)) { |
86 | + m_surface->blit(destination_rect, *image, source_rect, opacity, blend_mode); |
87 | } |
88 | } |
89 | |
90 | -void RenderTarget::blitrect_scale_monochrome(const Rect& destination_rect, |
91 | +void RenderTarget::blitrect_scale_monochrome(Rect destination_rect, |
92 | const Image* image, |
93 | - const Rect& source_rect, |
94 | + Rect source_rect, |
95 | const RGBAColor& blend) { |
96 | - Point destination_point(destination_rect.x, destination_rect.y); |
97 | - Rect srcrect(source_rect); |
98 | - if (to_surface_geometry(&destination_point, &srcrect)) { |
99 | - m_surface->blit_monochrome( |
100 | - Rect(destination_point.x, destination_point.y, destination_rect.w, destination_rect.h), |
101 | - *image, |
102 | - source_rect, |
103 | - blend); |
104 | + if (to_surface_geometry(&destination_rect, &source_rect)) { |
105 | + m_surface->blit_monochrome(destination_rect, *image, source_rect, blend); |
106 | } |
107 | } |
108 | |
109 | @@ -347,12 +326,13 @@ |
110 | uint32_t time, |
111 | const RGBColor* player_color, |
112 | const Rect& source_rect) { |
113 | - Point destination_point = dst - animation.hotspot(); |
114 | - destination_point += source_rect.origin(); |
115 | + Rect destination_rect(dst.x - animation.hotspot().x + source_rect.x, |
116 | + dst.y - animation.hotspot().y + source_rect.y, source_rect.w, |
117 | + source_rect.h); |
118 | |
119 | Rect srcrc(source_rect); |
120 | - if (to_surface_geometry(&destination_point, &srcrc)) |
121 | - animation.blit(time, destination_point, srcrc, player_color, m_surface); |
122 | + if (to_surface_geometry(&destination_rect, &srcrc)) |
123 | + animation.blit(time, destination_rect.origin(), srcrc, player_color, m_surface); |
124 | |
125 | // Look if there is a sound effect registered for this frame and trigger the |
126 | // effect (see SoundHandler::stereo_position). |
127 | @@ -423,41 +403,71 @@ |
128 | * Clip against window and source bitmap, returns false if blitting is |
129 | * unnecessary because image is not inside the target surface. |
130 | */ |
131 | -bool RenderTarget::to_surface_geometry(Point* dst, Rect* srcrc) const |
132 | +bool RenderTarget::to_surface_geometry(Rect* destination_rect, Rect* source_rect) const |
133 | { |
134 | - assert(0 <= srcrc->x); |
135 | - assert(0 <= srcrc->y); |
136 | - *dst += m_offset; |
137 | - |
138 | - // Clipping |
139 | - if (dst->x < 0) { |
140 | - if (srcrc->w <= -dst->x) |
141 | - return false; |
142 | - srcrc->x -= dst->x; |
143 | - srcrc->w += dst->x; |
144 | - dst->x = 0; |
145 | - } |
146 | - |
147 | - if (dst->x + srcrc->w > m_rect.w) { |
148 | - if (m_rect.w <= dst->x) |
149 | - return false; |
150 | - srcrc->w = m_rect.w - dst->x; |
151 | - } |
152 | - |
153 | - if (dst->y < 0) { |
154 | - if (srcrc->h <= -dst->y) |
155 | - return false; |
156 | - srcrc->y -= dst->y; |
157 | - srcrc->h += dst->y; |
158 | - dst->y = 0; |
159 | - } |
160 | - |
161 | - if (dst->y + srcrc->h > m_rect.h) { |
162 | - if (m_rect.h <= dst->y) |
163 | - return false; |
164 | - srcrc->h = m_rect.h - dst->y; |
165 | - } |
166 | - |
167 | - *dst += m_rect.origin(); |
168 | + assert(0 <= source_rect->x); |
169 | + assert(0 <= source_rect->y); |
170 | + destination_rect->x += m_offset.x; |
171 | + destination_rect->y += m_offset.y; |
172 | + |
173 | + // We have to clip the target rect against our own drawing area. If we make |
174 | + // changes to any side of our rectangle, we have to change the source rect |
175 | + // too. But since the source_rectangle might have a different size than the |
176 | + // destination_rect, we do this by making the proportional change. |
177 | + |
178 | + // Clipping, from the left. |
179 | + if (destination_rect->x < 0) { |
180 | + if (destination_rect->w <= -destination_rect->x) { |
181 | + return false; |
182 | + } |
183 | + // Adding 0.5 is a cheap way of turning integer truncation into a rounded value. |
184 | + const int source_rect_pixel_change = |
185 | + 0.5 + -static_cast<double>(destination_rect->x) / destination_rect->w * source_rect->w; |
186 | + source_rect->x += source_rect_pixel_change; |
187 | + source_rect->w -= source_rect_pixel_change; |
188 | + destination_rect->w += destination_rect->x; |
189 | + destination_rect->x = 0; |
190 | + } |
191 | + |
192 | + // Clipping, from the right. |
193 | + if (destination_rect->x + destination_rect->w > m_rect.w) { |
194 | + if (m_rect.w <= destination_rect->x) { |
195 | + return false; |
196 | + } |
197 | + const int new_destination_w = m_rect.w - destination_rect->x; |
198 | + // Adding 0.5 is a cheap way of turning integer truncation into a rounded value. |
199 | + source_rect->w = |
200 | + 0.5 + static_cast<double>(new_destination_w) / destination_rect->w * source_rect->w; |
201 | + destination_rect->w = new_destination_w; |
202 | + } |
203 | + |
204 | + // Clipping, from the top. |
205 | + if (destination_rect->y < 0) { |
206 | + if (destination_rect->h <= -destination_rect->y) { |
207 | + return false; |
208 | + } |
209 | + // Adding 0.5 is a cheap way of turning integer truncation into a rounded value. |
210 | + const int source_rect_pixel_change = 0.5 + |
211 | + -static_cast<double>(destination_rect->y) / destination_rect->h * source_rect->h; |
212 | + source_rect->y += source_rect_pixel_change; |
213 | + source_rect->h -= source_rect_pixel_change; |
214 | + destination_rect->h += destination_rect->y; |
215 | + destination_rect->y = 0; |
216 | + } |
217 | + |
218 | + // Clipping, from the bottom. |
219 | + if (destination_rect->y + destination_rect->h > m_rect.h) { |
220 | + if (m_rect.h <= destination_rect->y) { |
221 | + return false; |
222 | + } |
223 | + const int new_destination_h = m_rect.h - destination_rect->y; |
224 | + // Adding 0.5 is a cheap way of turning integer truncation into a rounded value. |
225 | + source_rect->h = |
226 | + 0.5 + static_cast<double>(new_destination_h) / destination_rect->h * source_rect->h; |
227 | + destination_rect->h = new_destination_h; |
228 | + } |
229 | + |
230 | + destination_rect->x += m_rect.x; |
231 | + destination_rect->y += m_rect.y; |
232 | return true; |
233 | } |
234 | |
235 | === modified file 'src/graphic/rendertarget.h' |
236 | --- src/graphic/rendertarget.h 2016-01-23 10:08:40 +0000 |
237 | +++ src/graphic/rendertarget.h 2016-01-24 08:40:10 +0000 |
238 | @@ -83,16 +83,18 @@ |
239 | // multiplied with 'opacity' before blitting. The 'blend_mode' |
240 | // defines if values are blended with whats already there or just |
241 | // copied over. |
242 | - void blitrect_scale(const Rect& destination_rect, |
243 | + // Rect's are taken by value on purpose. |
244 | + void blitrect_scale(Rect destination_rect, |
245 | const Image* image, |
246 | - const Rect& source_rect, |
247 | + Rect source_rect, |
248 | float opacity, |
249 | BlendMode blend_mode); |
250 | |
251 | - // Like blitrect_scale. See MonochromeBlitProgram for details. |
252 | - void blitrect_scale_monochrome(const Rect& destination_rect, |
253 | + // Like blitrect_scale. See MonochromeBlitProgram for details. Rect's are |
254 | + // taken by value on purpose. |
255 | + void blitrect_scale_monochrome(Rect destination_rect, |
256 | const Image* image, |
257 | - const Rect& source_rect, |
258 | + Rect source_rect, |
259 | const RGBAColor& blend); |
260 | |
261 | void tile(const Rect&, |
262 | @@ -118,7 +120,7 @@ |
263 | |
264 | protected: |
265 | bool clip(Rect & r) const; |
266 | - bool to_surface_geometry(Point* dst, Rect* srcrc) const; |
267 | + bool to_surface_geometry(Rect* destination_rect, Rect* source_rect) const; |
268 | |
269 | // Does the actual blitting. |
270 | void do_blit_animation(const Point& dst, |
271 | |
272 | === modified file 'src/graphic/text/font_io.cc' |
273 | --- src/graphic/text/font_io.cc 2014-11-18 17:45:58 +0000 |
274 | +++ src/graphic/text/font_io.cc 2016-01-24 08:40:10 +0000 |
275 | @@ -40,7 +40,7 @@ |
276 | // this class is destroyed. |
277 | std::unique_ptr<std::string> memory; |
278 | { |
279 | - FileRead* fr = new FileRead(); |
280 | + std::unique_ptr<FileRead> fr(new FileRead()); |
281 | fr->open(*g_fs, filename); |
282 | memory.reset(new std::string(fr->data(0), fr->get_size())); |
283 | } |
284 | |
285 | === modified file 'src/logic/map_objects/world/world.cc' |
286 | --- src/logic/map_objects/world/world.cc 2016-01-13 07:27:55 +0000 |
287 | +++ src/logic/map_objects/world/world.cc 2016-01-24 08:40:10 +0000 |
288 | @@ -50,15 +50,15 @@ |
289 | for (size_t i = 0; i < terrains_->size(); ++i) { |
290 | TerrainDescription* terrain = terrains_->get_mutable(i); |
291 | for (size_t j = 0; j < terrain->texture_paths().size(); ++j) { |
292 | - SDL_Surface* sdl_surface = load_image_as_sdl_surface(terrain->texture_paths()[j]); |
293 | - |
294 | // Set the minimap color on the first loaded image. |
295 | if (j == 0) { |
296 | + SDL_Surface* sdl_surface = load_image_as_sdl_surface(terrain->texture_paths()[j]); |
297 | uint8_t top_left_pixel = static_cast<uint8_t*>(sdl_surface->pixels)[0]; |
298 | const SDL_Color top_left_pixel_color = |
299 | sdl_surface->format->palette->colors[top_left_pixel]; |
300 | terrain->set_minimap_color( |
301 | RGBColor(top_left_pixel_color.r, top_left_pixel_color.g, top_left_pixel_color.b)); |
302 | + SDL_FreeSurface(sdl_surface); |
303 | } |
304 | terrain->add_texture(g_gr->images().get(terrain->texture_paths()[j])); |
305 | } |
306 | |
307 | === modified file 'src/ui_basic/table.cc' |
308 | --- src/ui_basic/table.cc 2016-01-11 15:18:51 +0000 |
309 | +++ src/ui_basic/table.cc 2016-01-24 08:40:10 +0000 |
310 | @@ -283,7 +283,7 @@ |
311 | Columns::size_type const nr_columns = m_columns.size(); |
312 | for (uint32_t i = 0, curx = 0; i < nr_columns; ++i) { |
313 | const Column& column = m_columns[i]; |
314 | - int const curw = column.width; |
315 | + int const curw = column.width; |
316 | Align alignment = mirror_alignment(column.alignment); |
317 | |
318 | const Image* entry_picture = er.get_picture(i); |
319 | @@ -291,11 +291,10 @@ |
320 | |
321 | Point point(curx, y); |
322 | int picw = 0; |
323 | - int pich = 0; |
324 | |
325 | - if (entry_picture) { |
326 | + if (entry_picture != nullptr) { |
327 | picw = entry_picture->width(); |
328 | - pich = entry_picture->height(); |
329 | + const int pich = entry_picture->height(); |
330 | |
331 | int draw_x = point.x; |
332 | |
333 | @@ -319,22 +318,9 @@ |
334 | draw_x += curw - blit_width; |
335 | } |
336 | |
337 | - // Temporary texture for the scaled image |
338 | - Texture* scaled_texture = new Texture(blit_width, max_pic_height); |
339 | - |
340 | - // Initialize the rectangle |
341 | - scaled_texture->fill_rect(Rect(0, 0, blit_width, max_pic_height), |
342 | - RGBAColor(255, 255, 255, 0)); |
343 | - |
344 | // Create the scaled image |
345 | - scaled_texture->blit(Rect(0, 0, blit_width, max_pic_height), |
346 | - *entry_picture, |
347 | - Rect(0, 0, picw, pich), |
348 | - 1., |
349 | - BlendMode::UseAlpha); |
350 | - |
351 | - // This will now blit with any appropriate cropping |
352 | - dst.blit(Point(draw_x, point.y + 1), scaled_texture); |
353 | + dst.blitrect_scale(Rect(draw_x, point.y + 1, blit_width, max_pic_height), |
354 | + entry_picture, Rect(0, 0, picw, pich), 1., BlendMode::UseAlpha); |
355 | |
356 | // For text alignment below |
357 | picw = blit_width; |
358 | |
359 | === modified file 'src/ui_fsmenu/loadgame.cc' |
360 | --- src/ui_fsmenu/loadgame.cc 2016-01-17 08:29:59 +0000 |
361 | +++ src/ui_fsmenu/loadgame.cc 2016-01-24 08:40:10 +0000 |
362 | @@ -435,16 +435,16 @@ |
363 | m_games_data.clear(); |
364 | m_table.clear(); |
365 | |
366 | - SavegameData* gamedata = new SavegameData(); |
367 | |
368 | if (m_settings && !m_settings->settings().saved_games.empty()) { |
369 | + SavegameData gamedata; |
370 | for (uint32_t i = 0; i < m_settings->settings().saved_games.size(); ++i) { |
371 | - gamedata->filename = m_settings->settings().saved_games.at(i).path; |
372 | - m_games_data.push_back(*gamedata); |
373 | + gamedata.filename = m_settings->settings().saved_games.at(i).path; |
374 | + m_games_data.push_back(gamedata); |
375 | |
376 | UI::Table<uintptr_t const>::EntryRecord & te = |
377 | m_table.add(m_games_data.size() - 1); |
378 | - te.set_string(0, FileSystem::filename_without_ext(gamedata->filename.c_str()).c_str()); |
379 | + te.set_string(0, FileSystem::filename_without_ext(gamedata.filename.c_str()).c_str()); |
380 | } |
381 | } else { // Normal case |
382 | // Fill it with all files we find. |
383 | @@ -465,7 +465,7 @@ |
384 | continue; |
385 | } |
386 | |
387 | - gamedata = new SavegameData(); |
388 | + SavegameData gamedata; |
389 | |
390 | std::string savename = gamefilename; |
391 | if (m_is_replay) savename += WLGF_SUFFIX; |
392 | @@ -474,30 +474,30 @@ |
393 | continue; |
394 | } |
395 | |
396 | - gamedata->filename = gamefilename; |
397 | + gamedata.filename = gamefilename; |
398 | |
399 | try { |
400 | Widelands::GameLoader gl(savename.c_str(), m_game); |
401 | gl.preload_game(gpdp); |
402 | |
403 | - gamedata->gametype = gpdp.get_gametype(); |
404 | + gamedata.gametype = gpdp.get_gametype(); |
405 | |
406 | if (!m_is_replay) { |
407 | if (m_settings->settings().multiplayer) { |
408 | - if (gamedata->gametype == GameController::GameType::SINGLEPLAYER) { |
409 | + if (gamedata.gametype == GameController::GameType::SINGLEPLAYER) { |
410 | continue; |
411 | } |
412 | - } else if (gamedata->gametype > GameController::GameType::SINGLEPLAYER) { |
413 | + } else if (gamedata.gametype > GameController::GameType::SINGLEPLAYER) { |
414 | continue; |
415 | } |
416 | } |
417 | |
418 | - gamedata->mapname = gpdp.get_mapname(); |
419 | - gamedata->gametime = gpdp.get_gametime(); |
420 | - gamedata->nrplayers = gpdp.get_number_of_players(); |
421 | - gamedata->version = gpdp.get_version(); |
422 | + gamedata.mapname = gpdp.get_mapname(); |
423 | + gamedata.gametime = gpdp.get_gametime(); |
424 | + gamedata.nrplayers = gpdp.get_number_of_players(); |
425 | + gamedata.version = gpdp.get_version(); |
426 | |
427 | - gamedata->savetimestamp = gpdp.get_savetimestamp(); |
428 | + gamedata.savetimestamp = gpdp.get_savetimestamp(); |
429 | time_t t; |
430 | time(&t); |
431 | struct tm * currenttime = localtime(&t); |
432 | @@ -506,9 +506,9 @@ |
433 | int8_t current_month = currenttime->tm_mon; |
434 | int8_t current_day = currenttime->tm_mday; |
435 | |
436 | - struct tm * savedate = localtime(&gamedata->savetimestamp); |
437 | + struct tm * savedate = localtime(&gamedata.savetimestamp); |
438 | |
439 | - if (gamedata->savetimestamp > 0) { |
440 | + if (gamedata.savetimestamp > 0) { |
441 | if (savedate->tm_year == current_year && |
442 | savedate->tm_mon == current_month && |
443 | savedate->tm_mday == current_day) { // Today |
444 | @@ -518,7 +518,7 @@ |
445 | |
446 | /** TRANSLATORS: Display date for choosing a savegame/replay */ |
447 | /** TRANSLATORS: hour:minute */ |
448 | - gamedata->savedatestring = (boost::format(_("Today, %1%:%2%")) |
449 | + gamedata.savedatestring = (boost::format(_("Today, %1%:%2%")) |
450 | % savedate->tm_hour % minute).str(); |
451 | } else if ((savedate->tm_year == current_year && |
452 | savedate->tm_mon == current_month && |
453 | @@ -531,13 +531,13 @@ |
454 | |
455 | /** TRANSLATORS: Display date for choosing a savegame/replay */ |
456 | /** TRANSLATORS: hour:minute */ |
457 | - gamedata->savedatestring = (boost::format(_("Yesterday, %1%:%2%")) |
458 | + gamedata.savedatestring = (boost::format(_("Yesterday, %1%:%2%")) |
459 | % savedate->tm_hour % minute).str(); |
460 | } else { // Older |
461 | |
462 | /** TRANSLATORS: Display date for choosing a savegame/replay */ |
463 | /** TRANSLATORS: month day, year */ |
464 | - gamedata->savedatestring = (boost::format(_("%2% %1%, %3%")) |
465 | + gamedata.savedatestring = (boost::format(_("%2% %1%, %3%")) |
466 | % savedate->tm_mday |
467 | % localize_month(savedate->tm_mon) |
468 | % (1900 + savedate->tm_year)).str(); |
469 | @@ -546,18 +546,18 @@ |
470 | |
471 | { |
472 | i18n::Textdomain td("win_conditions"); |
473 | - gamedata->wincondition = _(gpdp.get_win_condition()); |
474 | + gamedata.wincondition = _(gpdp.get_win_condition()); |
475 | } |
476 | - gamedata->minimap_path = gpdp.get_minimap_path(); |
477 | - m_games_data.push_back(*gamedata); |
478 | + gamedata.minimap_path = gpdp.get_minimap_path(); |
479 | + m_games_data.push_back(gamedata); |
480 | |
481 | UI::Table<uintptr_t const>::EntryRecord & te = |
482 | m_table.add(m_games_data.size() - 1); |
483 | - te.set_string(0, gamedata->savedatestring); |
484 | + te.set_string(0, gamedata.savedatestring); |
485 | |
486 | if (m_is_replay || m_settings->settings().multiplayer) { |
487 | std::string gametypestring; |
488 | - switch (gamedata->gametype) { |
489 | + switch (gamedata.gametype) { |
490 | case GameController::GameType::SINGLEPLAYER: |
491 | /** TRANSLATORS: "Single Player" entry in the Game Mode table column. */ |
492 | /** TRANSLATORS: "Keep this to 6 letters maximum. */ |
493 | @@ -572,7 +572,7 @@ |
494 | /** TRANSLATORS: Make sure that this translation is consistent with the tooltip. */ |
495 | /** TRANSLATORS: %1% is the number of players */ |
496 | gametypestring = (boost::format(_("H (%1%)")) |
497 | - % static_cast<unsigned int>(gamedata->nrplayers)).str(); |
498 | + % static_cast<unsigned int>(gamedata.nrplayers)).str(); |
499 | break; |
500 | case GameController::GameType::NETCLIENT: |
501 | /** TRANSLATORS: "Multiplayer" entry in the Game Mode table column. */ |
502 | @@ -581,20 +581,20 @@ |
503 | /** TRANSLATORS: Make sure that this translation is consistent with the tooltip. */ |
504 | /** TRANSLATORS: %1% is the number of players */ |
505 | gametypestring = (boost::format(_("MP (%1%)")) |
506 | - % static_cast<unsigned int>(gamedata->nrplayers)).str(); |
507 | + % static_cast<unsigned int>(gamedata.nrplayers)).str(); |
508 | break; |
509 | case GameController::GameType::REPLAY: |
510 | gametypestring = ""; |
511 | break; |
512 | } |
513 | te.set_string(1, gametypestring); |
514 | - te.set_string(2, map_filename(gamedata->filename, gamedata->mapname)); |
515 | + te.set_string(2, map_filename(gamedata.filename, gamedata.mapname)); |
516 | } else { |
517 | - te.set_string(1, map_filename(gamedata->filename, gamedata->mapname)); |
518 | + te.set_string(1, map_filename(gamedata.filename, gamedata.mapname)); |
519 | } |
520 | } catch (const WException & e) { |
521 | // we simply skip illegal entries |
522 | - gamedata->errormessage = |
523 | + gamedata.errormessage = |
524 | ((boost::format("%s\n\n%s\n\n%s")) |
525 | /** TRANSLATORS: Error message introduction for when an old savegame can't be loaded */ |
526 | % _("This file has the wrong format and can’t be loaded." |
527 | @@ -603,9 +603,9 @@ |
528 | % _("Error message:") |
529 | % e.what()).str(); |
530 | |
531 | - const std::string fs_filename = FileSystem::filename_without_ext(gamedata->filename.c_str()); |
532 | - gamedata->mapname = fs_filename; |
533 | - m_games_data.push_back(*gamedata); |
534 | + const std::string fs_filename = FileSystem::filename_without_ext(gamedata.filename.c_str()); |
535 | + gamedata.mapname = fs_filename; |
536 | + m_games_data.push_back(gamedata); |
537 | |
538 | UI::Table<uintptr_t const>::EntryRecord & te = |
539 | m_table.add(m_games_data.size() - 1); |
Hi, I am bunnybot (https:/ /github. com/widelands/ bunnybot).
I am keeping the source branch lp:~widelands-dev/widelands/memory_leak mirrored to https:/ /github. com/widelands/ widelands/ tree/_widelands _dev_widelands_ memory_ leak
You can give me commands by starting a line with @bunnybot <command>. I understand:
merge: Merges the source branch into the target branch, closing the merge proposal. I will use the proposed commit message if it is set.