← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/lock_game_logic into lp:widelands

 

SirVer has proposed merging lp:~widelands-dev/widelands/lock_game_logic into lp:widelands.

Commit message:
Decouples UI update frequency from game update frequency (which is now 15 times per second).

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1545098 in widelands: "Desync in bzr7818[trunk] "
  https://bugs.launchpad.net/widelands/+bug/1545098

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/lock_game_logic/+merge/285980

This is a hacky-hack. The game logic should not be driven by the UI, but that is such a fundamental design in Widelands that I am not sure if we can ever pull that apart. 

For now, this should fix desyncs, I could not reproduce them on my system anymore.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/lock_game_logic into lp:widelands.
=== modified file 'src/economy/request.cc'
--- src/economy/request.cc	2016-02-07 06:10:47 +0000
+++ src/economy/request.cc	2016-02-13 19:22:05 +0000
@@ -351,7 +351,7 @@
 			economy_->remove_request(*this);
 		economy_ = e;
 		if (economy_ && is_open())
-			economy_->   add_request(*this);
+			economy_->add_request(*this);
 	}
 }
 

=== modified file 'src/ui_basic/panel.cc'
--- src/ui_basic/panel.cc	2016-02-07 16:31:06 +0000
+++ src/ui_basic/panel.cc	2016-02-13 19:22:05 +0000
@@ -148,41 +148,53 @@
 	// Panel-specific startup code. This might call end_modal()!
 	start();
 
-	const uint32_t minimum_frame_time =
+	// think() is called at most 15 times per second.
+	const uint32_t kGameLogicDelay = 1000 / 15;
+
+	const uint32_t draw_delay =
 	   1000 / std::max(5, g_options.pull_section("global").get_int("maxfps", 30));
 
+	static InputCallback input_callback = {
+		Panel::ui_mousepress,
+		Panel::ui_mouserelease,
+		Panel::ui_mousemove,
+		Panel::ui_key,
+		Panel::ui_textinput,
+		Panel::ui_mousewheel
+	};
+
+	uint32_t next_think_time = SDL_GetTicks() + kGameLogicDelay;
+	uint32_t next_draw_time = SDL_GetTicks() + draw_delay;
 	while (_running) {
-		const uint32_t startTime = SDL_GetTicks();
-
-		static InputCallback icb = {
-			Panel::ui_mousepress,
-			Panel::ui_mouserelease,
-			Panel::ui_mousemove,
-			Panel::ui_key,
-			Panel::ui_textinput,
-			Panel::ui_mousewheel
-		};
-
-		app->handle_input(&icb);
-		if (app->should_die())
-			end_modal<Returncodes>(Returncodes::kBack);
-
-		do_think();
-
-		RenderTarget& rt = *g_gr->get_render_target();
-		forefather->do_draw(rt);
-		rt.blit(app->get_mouse_position() - Point(3, 7),
-		        WLApplication::get()->is_mouse_pressed() ? s_default_cursor_click : s_default_cursor);
-		forefather->do_tooltip();
-		g_gr->refresh();
-
-		if (_flags & pf_child_die)
-			check_child_death();
-
-		//  Wait until 1second/maxfps are over.
-		const uint32_t frame_time = SDL_GetTicks() - startTime;
-		if (frame_time < minimum_frame_time) {
-			SDL_Delay(minimum_frame_time - frame_time);
+		const uint32_t start_time = SDL_GetTicks();
+
+		app->handle_input(&input_callback);
+
+		if (start_time >= next_think_time) {
+			if (app->should_die())
+				end_modal<Returncodes>(Returncodes::kBack);
+
+			do_think();
+
+			if (_flags & pf_child_die)
+				check_child_death();
+			next_think_time = start_time + kGameLogicDelay;
+		}
+
+		if (start_time >= next_draw_time) {
+			RenderTarget& rt = *g_gr->get_render_target();
+			forefather->do_draw(rt);
+			rt.blit(app->get_mouse_position() - Point(3, 7), WLApplication::get()->is_mouse_pressed() ?
+			                                                    s_default_cursor_click :
+			                                                    s_default_cursor);
+			forefather->do_tooltip();
+			g_gr->refresh();
+			next_draw_time = start_time + draw_delay;
+		}
+
+		int32_t delay = std::min<int32_t>(next_draw_time, next_think_time) - SDL_GetTicks();
+		if (delay > 0) {
+			SDL_Delay(delay);
 		}
 	}
 	end();

=== modified file 'src/wui/interactive_base.cc'
--- src/wui/interactive_base.cc	2016-02-01 11:46:58 +0000
+++ src/wui/interactive_base.cc	2016-02-13 19:22:05 +0000
@@ -307,13 +307,6 @@
 */
 void InteractiveBase::think()
 {
-	// Timing
-	uint32_t curframe = SDL_GetTicks();
-
-	frametime_ = curframe - lastframe_;
-	avg_usframetime_ = ((avg_usframetime_  * 15) + (frametime_  * 1000)) / 16;
-	lastframe_ = curframe;
-
 	// If one of the arrow keys is pressed, scroll here
 	const uint32_t scrollval = 10;
 
@@ -347,6 +340,13 @@
 ===============
 */
 void InteractiveBase::draw_overlay(RenderTarget& dst) {
+	// Timing
+	uint32_t curframe = SDL_GetTicks();
+
+	frametime_ = curframe - lastframe_;
+	avg_usframetime_ = ((avg_usframetime_  * 15) + (frametime_  * 1000)) / 16;
+	lastframe_ = curframe;
+
 
 	const Map & map = egbase().map();
 	const bool is_game = dynamic_cast<const Game*>(&egbase());


Follow ups