← Back to team overview

widelands-dev team mailing list archive

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

 

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

Commit message:
Draw resources and player starting positions overlays in the editor without the overlay manager.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1696064 in widelands: "Resources disappear in editor"
  https://bugs.launchpad.net/widelands/+bug/1696064

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/reduce_overlay_manager_use/+merge/329807
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/reduce_overlay_manager_use into lp:widelands.
=== modified file 'src/editor/editorinteractive.cc'
--- src/editor/editorinteractive.cc	2017-08-28 12:44:08 +0000
+++ src/editor/editorinteractive.cc	2017-08-29 12:21:52 +0000
@@ -63,27 +63,6 @@
 	egbase->tribes();
 }
 
-// Updates the resources overlays after a field has changed.
-void update_resource_overlay(const Widelands::NoteFieldResourceChanged& note,
-                             const Widelands::World& world,
-                             FieldOverlayManager* field_overlay_manager) {
-	//  Ok, we're doing something. First remove the current overlays.
-	if (note.old_resource != Widelands::kNoResource) {
-		const std::string str = world.get_resource(note.old_resource)->editor_image(note.old_amount);
-		const Image* pic = g_gr->images().get(str);
-		field_overlay_manager->remove_overlay(note.fc, pic);
-	}
-
-	const auto amount = note.fc.field->get_resources_amount();
-	const auto resource_type = note.fc.field->get_resources();
-	if (amount > 0 && resource_type != Widelands::kNoResource) {
-		const std::string str =
-		   world.get_resource(note.fc.field->get_resources())->editor_image(amount);
-		const Image* pic = g_gr->images().get(str);
-		field_overlay_manager->register_overlay(note.fc, pic, OverlayLevel::kResource);
-	}
-}
-
 }  // namespace
 
 EditorInteractive::EditorInteractive(Widelands::EditorGameBase& e)
@@ -168,43 +147,9 @@
 		map_clicked(node_and_triangle, false);
 	});
 
-	// Subscribe to changes of the resource type on a field..
-	field_resource_changed_subscriber_ =
-	   Notifications::subscribe<Widelands::NoteFieldResourceChanged>(
-	      [this](const Widelands::NoteFieldResourceChanged& note) {
-		      update_resource_overlay(note, egbase().world(), mutable_field_overlay_manager());
-		   });
-
 	minimap_registry().minimap_type = MiniMapType::kStaticMap;
 }
 
-void EditorInteractive::register_overlays() {
-	Widelands::Map* map = egbase().mutable_map();
-
-	//  Starting locations
-	Widelands::PlayerNumber const nr_players = map->get_nrplayers();
-	assert(nr_players <= kMaxPlayers);
-	iterate_player_numbers(p, nr_players) {
-		if (Widelands::Coords const sp = map->get_starting_pos(p)) {
-			tools_->set_starting_pos.set_starting_pos(*this, p, sp, map);
-		}
-	}
-
-	//  Resources: we do not calculate default resources, therefore we do not
-	//  expect to meet them here.
-	Widelands::Extent const extent = map->extent();
-	iterate_Map_FCoords(*map, extent, fc) {
-		if (uint8_t const amount = fc.field->get_resources_amount()) {
-			const std::string& immname =
-			   egbase().world().get_resource(fc.field->get_resources())->editor_image(amount);
-			if (immname.size()) {
-				mutable_field_overlay_manager()->register_overlay(
-				   fc, g_gr->images().get(immname), OverlayLevel::kResource);
-			}
-		}
-	}
-}
-
 void EditorInteractive::load(const std::string& filename) {
 	assert(filename.size());
 
@@ -318,6 +263,18 @@
 	const float scale = 1.f / map_view()->view().zoom;
 	const uint32_t gametime = ebase.get_gametime();
 
+	// The map provides a mapping from player number to Coords, while we require
+	// the inverse here. We construct this, but this is done on every frame and
+	// therefore potentially expensive - though it never showed up in any of my
+	// profiles. We could change the Map should this become a bottleneck, since
+	// plrnum -> coords is needed less often.
+	const auto& map = ebase.map();
+	std::map<Widelands::Coords, int> starting_positions;
+	for (int i = 1; i <= map.get_nrplayers(); ++i) {
+		starting_positions[map.get_starting_pos(i)] = i;
+	}
+
+	const auto& world = ebase.world();
 	for (size_t idx = 0; idx < fields_to_draw->size(); ++idx) {
 		const FieldsToDraw::Field& field = fields_to_draw->at(idx);
 		if (draw_immovables_) {
@@ -334,15 +291,37 @@
 			}
 		}
 
+		const auto blit_overlay = [&dst, &field, scale](const Image* pic, const Vector2i& hotspot) {
+			dst.blitrect_scale(Rectf(field.rendertarget_pixel - hotspot.cast<float>() * scale,
+			                         pic->width() * scale, pic->height() * scale),
+			                   pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
+			                   BlendMode::UseAlpha);
+		};
+
+		// Draw resource overlay.
+		uint8_t const amount = field.fcoords.field->get_resources_amount();
+		if (draw_resources_ && amount > 0) {
+			const std::string& immname =
+			   world.get_resource(field.fcoords.field->get_resources())->editor_image(amount);
+			if (!immname.empty()) {
+				const auto* pic = g_gr->images().get(immname);
+				blit_overlay(pic, Vector2i(pic->width() / 2, pic->height() / 2));
+			}
+		}
+
 		// TODO(sirver): Do not use the field_overlay_manager, instead draw the
 		// overlays we are interested in here directly.
-		field_overlay_manager().foreach_overlay(
-		   field.fcoords, [&dst, &field, scale](const Image* pic, const Vector2i& hotspot) {
-			   dst.blitrect_scale(Rectf(field.rendertarget_pixel - hotspot.cast<float>() * scale,
-			                            pic->width() * scale, pic->height() * scale),
-			                      pic, Recti(0, 0, pic->width(), pic->height()), 1.f,
-			                      BlendMode::UseAlpha);
-			});
+		field_overlay_manager().foreach_overlay(field.fcoords, blit_overlay);
+
+		// Draw the player starting position overlays.
+		const auto it = starting_positions.find(field.fcoords);
+		if (it != starting_positions.end()) {
+			const Image* player_image =
+			   playercolor_image(it->second - 1, "images/players/player_position.png");
+			assert(player_image != nullptr);
+			constexpr int kStartingPosHotspotY = 55;
+			blit_overlay(player_image, Vector2i(player_image->width() / 2, kStartingPosHotspotY));
+		}
 	}
 }
 
@@ -382,10 +361,8 @@
 }
 
 void EditorInteractive::toggle_resources() {
-	auto* overlay_manager = mutable_field_overlay_manager();
-	const bool value = !overlay_manager->is_enabled(OverlayLevel::kResource);
-	overlay_manager->set_enabled(OverlayLevel::kResource, value);
-	toggle_resources_->set_perm_pressed(value);
+	draw_resources_ = !draw_resources_;
+	toggle_resources_->set_perm_pressed(draw_resources_);
 }
 
 void EditorInteractive::toggle_immovables() {
@@ -706,7 +683,6 @@
 	}
 
 	mutable_field_overlay_manager()->remove_all_overlays();
-	register_overlays();
 }
 
 EditorInteractive::Tools* EditorInteractive::tools() {

=== modified file 'src/editor/editorinteractive.h'
--- src/editor/editorinteractive.h	2017-08-20 16:12:28 +0000
+++ src/editor/editorinteractive.h	2017-08-29 12:21:52 +0000
@@ -150,9 +150,6 @@
 		void const* object;
 	};
 
-	// Registers the overlays for player starting positions.
-	void register_overlays();
-
 	void on_buildhelp_changed(const bool value) override;
 
 	void toggle_resources();
@@ -165,8 +162,6 @@
 	uint32_t realtime_;
 	bool is_painting_;
 
-	std::unique_ptr<Notifications::Subscriber<Widelands::NoteFieldResourceChanged>>
-	   field_resource_changed_subscriber_;
 	UI::UniqueWindow::Registry toolmenu_;
 
 	UI::UniqueWindow::Registry toolsizemenu_;
@@ -190,6 +185,7 @@
 	std::unique_ptr<Tools> tools_;
 	std::unique_ptr<EditorHistory> history_;
 
+	bool draw_resources_ = true;
 	bool draw_immovables_ = true;
 	bool draw_bobs_ = true;
 };

=== modified file 'src/editor/tools/set_starting_pos_tool.cc'
--- src/editor/tools/set_starting_pos_tool.cc	2017-08-13 18:38:27 +0000
+++ src/editor/tools/set_starting_pos_tool.cc	2017-08-29 12:21:52 +0000
@@ -55,14 +55,13 @@
 	return 0;
 }
 
-EditorSetStartingPosTool::EditorSetStartingPosTool()
-   : EditorTool(*this, *this, false), overlay_ids_(kMaxPlayers, 0) {
+EditorSetStartingPosTool::EditorSetStartingPosTool() : EditorTool(*this, *this, false) {
 	current_player_ = 1;
 }
 
 int32_t EditorSetStartingPosTool::handle_click_impl(const Widelands::World&,
                                                     const Widelands::NodeAndTriangle<>& center,
-                                                    EditorInteractive& eia,
+                                                    EditorInteractive&,
                                                     EditorActionArgs*,
                                                     Widelands::Map* map) {
 	assert(0 <= center.node.x);
@@ -80,35 +79,12 @@
 
 		//  check if field is valid
 		if (editor_tool_set_starting_pos_callback(map->get_fcoords(center.node), *map)) {
-			set_starting_pos(eia, current_player_, center.node, map);
+			map->set_starting_pos(current_player_, center.node);
 		}
 	}
 	return 1;
 }
 
-void EditorSetStartingPosTool::set_starting_pos(EditorInteractive& eia,
-                                                Widelands::PlayerNumber plnum,
-                                                const Widelands::Coords& c,
-                                                Widelands::Map* map) {
-	FieldOverlayManager* overlay_manager = eia.mutable_field_overlay_manager();
-	//  remove old overlay if any
-	overlay_manager->remove_overlay(overlay_ids_.at(plnum - 1));
-
-	//  add new overlay
-	FieldOverlayManager::OverlayId overlay_id = overlay_manager->next_overlay_id();
-	overlay_ids_[plnum - 1] = overlay_id;
-
-	const Image* player_image = playercolor_image(plnum - 1, "images/players/player_position.png");
-	assert(player_image);
-
-	overlay_manager->register_overlay(c, player_image, OverlayLevel::kPlayerStartingPosition,
-	                                  Vector2i(player_image->width() / 2, STARTING_POS_HOTSPOT_Y),
-	                                  overlay_id);
-
-	//  set new player pos
-	map->set_starting_pos(plnum, c);
-}
-
 Widelands::PlayerNumber EditorSetStartingPosTool::get_current_player() const {
 	return current_player_;
 }

=== modified file 'src/editor/tools/set_starting_pos_tool.h'
--- src/editor/tools/set_starting_pos_tool.h	2017-08-13 18:02:53 +0000
+++ src/editor/tools/set_starting_pos_tool.h	2017-08-29 12:21:52 +0000
@@ -30,7 +30,6 @@
 // How much place should be left around a player position
 // where no other player can start
 #define MIN_PLACE_AROUND_PLAYERS 24
-#define STARTING_POS_HOTSPOT_Y 55
 
 /// Sets the starting position of players.
 struct EditorSetStartingPosTool : public EditorTool {
@@ -50,13 +49,6 @@
 	bool has_size_one() const override {
 		return true;
 	}
-	void set_starting_pos(EditorInteractive& eia,
-	                      Widelands::PlayerNumber plnum,
-	                      const Widelands::Coords& c,
-	                      Widelands::Map* map);
-
-private:
-	std::vector<FieldOverlayManager::OverlayId> overlay_ids_;
 };
 
 int32_t editor_tool_set_starting_pos_callback(const Widelands::FCoords& c, Widelands::Map& map);

=== modified file 'src/logic/map.cc'
--- src/logic/map.cc	2017-08-20 17:45:42 +0000
+++ src/logic/map.cc	2017-08-29 12:21:52 +0000
@@ -1816,14 +1816,9 @@
 	if (resource_type == Widelands::kNoResource) {
 		amount = 0;
 	}
-	const auto note = NoteFieldResourceChanged{
-	   c, c.field->resources, c.field->initial_res_amount, c.field->res_amount,
-	};
-
 	c.field->resources = resource_type;
 	c.field->initial_res_amount = amount;
 	c.field->res_amount = amount;
-	Notifications::publish(note);
 }
 
 void Map::set_resources(const FCoords& c, ResourceAmount amount) {
@@ -1831,11 +1826,7 @@
 	if (c.field->resources == Widelands::kNoResource) {
 		return;
 	}
-	const auto note = NoteFieldResourceChanged{
-	   c, c.field->resources, c.field->initial_res_amount, c.field->res_amount,
-	};
 	c.field->res_amount = amount;
-	Notifications::publish(note);
 }
 
 void Map::clear_resources(const FCoords& c) {

=== modified file 'src/logic/map.h'
--- src/logic/map.h	2017-08-20 17:45:42 +0000
+++ src/logic/map.h	2017-08-29 12:21:52 +0000
@@ -74,16 +74,6 @@
 	MapIndex map_index;
 };
 
-/// Send when the resource of a field is changed.
-struct NoteFieldResourceChanged {
-	CAN_BE_SENT_AS_NOTE(NoteId::FieldResourceTypeChanged)
-
-	FCoords fc;
-	DescriptionIndex old_resource;
-	ResourceAmount old_initial_amount;
-	ResourceAmount old_amount;
-};
-
 struct ImmovableFound {
 	BaseImmovable* object;
 	Coords coords;

=== modified file 'src/wui/field_overlay_manager.h'
--- src/wui/field_overlay_manager.h	2017-08-15 17:37:57 +0000
+++ src/wui/field_overlay_manager.h	2017-08-29 12:21:52 +0000
@@ -53,10 +53,8 @@
 // drawn below the buildhelp, everything higher above.
 enum class OverlayLevel {
 	kWorkAreaPreview = 0,
-	kResource = 4,
 	kSelection = 7,
 	kRoadBuildSlope = 8,
-	kPlayerStartingPosition = 9,
 };
 
 struct FieldOverlayManager {


Follow ups