← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/bug-1695701-militarywindow-crash into lp:widelands

 

GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1695701-militarywindow-crash into lp:widelands.

Commit message:
Fix crash when a militarysite window is open while the enemy conquers it

- Turned buildings in building windows from pointer to reference, so we can check whether it's still there.
- Die if there is no building or building's owner.
- Refactored out die() function to avoid code duplication.

Requested reviews:
  Widelands Developers (widelands-dev)
Related bugs:
  Bug #1695701 in widelands: "Crash when a militarysite window is open while the enemy conquers it"
  https://bugs.launchpad.net/widelands/+bug/1695701

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1695701-militarywindow-crash/+merge/325040
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1695701-militarywindow-crash into lp:widelands.
=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc	2017-04-17 14:13:55 +0000
+++ src/wui/buildingwindow.cc	2017-06-04 08:48:14 +0000
@@ -52,7 +52,7 @@
    : UI::UniqueWindow(&parent, "building_window", &reg, Width, 0, b.descr().descname()),
      is_dying_(false),
      parent_(&parent),
-     building_(b),
+     building_(&b),
      workarea_overlay_id_(0),
      avoid_fastclick_(avoid_fastclick),
      expeditionbtn_(nullptr) {
@@ -67,7 +67,7 @@
 }
 
 void BuildingWindow::on_building_note(const Widelands::NoteBuilding& note) {
-	if (note.serial == building_.serial()) {
+	if (note.serial == building_->serial()) {
 		switch (note.action) {
 		// The building's state has changed
 		case Widelands::NoteBuilding::Action::kChanged:
@@ -77,13 +77,9 @@
 			break;
 		// The building is no more
 		case Widelands::NoteBuilding::Action::kStartWarp:
-			igbase()->add_wanted_building_window(building().get_position(), get_pos(), is_minimal());
+			igbase()->add_wanted_building_window(building()->get_position(), get_pos(), is_minimal());
 		// Fallthrough intended
 		case Widelands::NoteBuilding::Action::kDeleted:
-			// Stop everybody from thinking to avoid segfaults
-			is_dying_ = true;
-			set_thinks(false);
-			vbox_.reset(nullptr);
 			die();
 			break;
 		default:
@@ -117,6 +113,14 @@
 	show_workarea();
 }
 
+// Stop everybody from thinking to avoid segfaults
+void BuildingWindow::die() {
+	is_dying_ = true;
+	set_thinks(false);
+	vbox_.reset(nullptr);
+	UniqueWindow::die();
+}
+
 /*
 ===============
 Draw a picture of the building in the background.
@@ -127,7 +131,7 @@
 
 	// TODO(sirver): chang this to directly blit the animation. This needs support for or removal of
 	// RenderTarget.
-	const Image* image = building().representative_image();
+	const Image* image = building()->representative_image();
 	dst.blitrect_scale(
 	   Rectf((get_inner_w() - image->width()) / 2.f, (get_inner_h() - image->height()) / 2.f,
 	         image->width(), image->height()),
@@ -140,11 +144,13 @@
 ===============
 */
 void BuildingWindow::think() {
-	if (!igbase()->can_see(building().owner().player_number()))
+	if (!building() || !building()->get_owner() || !igbase()->can_see(building()->owner().player_number())) {
 		die();
+		return;
+	}
 
 	if (!caps_setup_ || capscache_player_number_ != igbase()->player_number() ||
-	    building().get_playercaps() != capscache_) {
+	    building()->get_playercaps() != capscache_) {
 		capsbuttons_->free_children();
 		create_capsbuttons(capsbuttons_);
 		if (!avoid_fastclick_) {
@@ -165,10 +171,10 @@
  * \note Children of \p box must be allocated on the heap
  */
 void BuildingWindow::create_capsbuttons(UI::Box* capsbuttons) {
-	capscache_ = building().get_playercaps();
+	capscache_ = building()->get_playercaps();
 	capscache_player_number_ = igbase()->player_number();
 
-	const Widelands::Player& owner = building().owner();
+	const Widelands::Player& owner = building()->owner();
 	const Widelands::PlayerNumber owner_number = owner.player_number();
 	const bool can_see = igbase()->can_see(owner_number);
 	const bool can_act = igbase()->can_act(owner_number);
@@ -176,7 +182,7 @@
 	bool requires_destruction_separator = false;
 	if (can_act) {
 		// Check if this is a port building and if yes show expedition button
-		if (upcast(Widelands::Warehouse const, warehouse, &building_)) {
+		if (upcast(Widelands::Warehouse const, warehouse, building_)) {
 			if (Widelands::PortDock* pd = warehouse->get_portdock()) {
 				expeditionbtn_ =
 				   new UI::Button(capsbuttons, "start_or_cancel_expedition", 0, 0, 34, 34,
@@ -196,7 +202,7 @@
 					      }
 					   });
 			}
-		} else if (upcast(const Widelands::ProductionSite, productionsite, &building_)) {
+		} else if (upcast(const Widelands::ProductionSite, productionsite, building_)) {
 			if (!is_a(Widelands::MilitarySite, productionsite)) {
 				const bool is_stopped = productionsite->is_stopped();
 				UI::Button* stopbtn = new UI::Button(
@@ -223,7 +229,7 @@
 		}  // upcast to productionsite
 
 		if (capscache_ & Widelands::Building::PCap_Enhancable) {
-			const Widelands::DescriptionIndex& enhancement = building_.descr().enhancement();
+			const Widelands::DescriptionIndex& enhancement = building_->descr().enhancement();
 			const Widelands::TribeDescr& tribe = owner.tribe();
 			if (owner.is_building_type_allowed(enhancement)) {
 				const Widelands::BuildingDescr& building_descr = *tribe.get_building_descr(enhancement);
@@ -257,7 +263,7 @@
 
 		if (capscache_ & Widelands::Building::PCap_Dismantle) {
 			const Widelands::Buildcost wares =
-			   Widelands::DismantleSite::count_returned_wares(&building_);
+			   Widelands::DismantleSite::count_returned_wares(building_);
 			if (!wares.empty()) {
 				UI::Button* dismantlebtn = new UI::Button(
 				   capsbuttons, "dismantle", 0, 0, 34, 34,
@@ -282,10 +288,10 @@
 
 	if (can_see) {
 		WorkareaInfo wa_info;
-		if (upcast(Widelands::ConstructionSite, csite, &building_)) {
+		if (upcast(Widelands::ConstructionSite, csite, building_)) {
 			wa_info = csite->building().workarea_info_;
 		} else {
-			wa_info = building_.descr().workarea_info_;
+			wa_info = building_->descr().workarea_info_;
 		}
 		if (!wa_info.empty()) {
 			toggle_workarea_ = new UI::Button(
@@ -324,10 +330,10 @@
 		   g_gr->images().get("images/ui_basic/menu_help.png"), _("Help"));
 
 		UI::UniqueWindow::Registry& registry =
-		   igbase()->unique_windows().get_registry(building_.descr().name() + "_help");
+		   igbase()->unique_windows().get_registry(building_->descr().name() + "_help");
 		registry.open_window = [this, &registry] {
-			new UI::BuildingHelpWindow(igbase(), registry, building_.descr(),
-			                           building_.owner().tribe(), &igbase()->egbase().lua());
+			new UI::BuildingHelpWindow(igbase(), registry, building_->descr(),
+			                           building_->owner().tribe(), &igbase()->egbase().lua());
 		};
 
 		helpbtn->sigclicked.connect(
@@ -343,10 +349,10 @@
 */
 void BuildingWindow::act_bulldoze() {
 	if (SDL_GetModState() & KMOD_CTRL) {
-		if (building_.get_playercaps() & Widelands::Building::PCap_Bulldoze)
-			igbase()->game().send_player_bulldoze(building_);
+		if (building_->get_playercaps() & Widelands::Building::PCap_Bulldoze)
+			igbase()->game().send_player_bulldoze(*building_);
 	} else {
-		show_bulldoze_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), building_);
+		show_bulldoze_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), *building_);
 	}
 }
 
@@ -357,10 +363,10 @@
 */
 void BuildingWindow::act_dismantle() {
 	if (SDL_GetModState() & KMOD_CTRL) {
-		if (building_.get_playercaps() & Widelands::Building::PCap_Dismantle)
-			igbase()->game().send_player_dismantle(building_);
+		if (building_->get_playercaps() & Widelands::Building::PCap_Dismantle)
+			igbase()->game().send_player_dismantle(*building_);
 	} else {
-		show_dismantle_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), building_);
+		show_dismantle_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), *building_);
 	}
 }
 
@@ -370,8 +376,8 @@
 ===============
 */
 void BuildingWindow::act_start_stop() {
-	if (dynamic_cast<const Widelands::ProductionSite*>(&building_)) {
-		igbase()->game().send_player_start_stop_building(building_);
+	if (dynamic_cast<const Widelands::ProductionSite*>(building_)) {
+		igbase()->game().send_player_start_stop_building(*building_);
 	}
 }
 
@@ -381,10 +387,10 @@
 ===============
 */
 void BuildingWindow::act_start_or_cancel_expedition() {
-	if (upcast(Widelands::Warehouse const, warehouse, &building_)) {
+	if (upcast(Widelands::Warehouse const, warehouse, building_)) {
 		if (warehouse->get_portdock()) {
 			expeditionbtn_->set_enabled(false);
-			igbase()->game().send_player_start_or_cancel_expedition(building_);
+			igbase()->game().send_player_start_or_cancel_expedition(*building_);
 		}
 		get_tabs()->activate("expedition_wares_queue");
 	}
@@ -400,10 +406,10 @@
 */
 void BuildingWindow::act_enhance(Widelands::DescriptionIndex id) {
 	if (SDL_GetModState() & KMOD_CTRL) {
-		if (building_.get_playercaps() & Widelands::Building::PCap_Enhancable)
-			igbase()->game().send_player_enhance_building(building_, id);
+		if (building_->get_playercaps() & Widelands::Building::PCap_Enhancable)
+			igbase()->game().send_player_enhance_building(*building_, id);
 	} else {
-		show_enhance_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), building_, id);
+		show_enhance_confirm(dynamic_cast<InteractivePlayer&>(*igbase()), *building_, id);
 	}
 }
 
@@ -413,7 +419,7 @@
 ===============
 */
 void BuildingWindow::act_debug() {
-	show_field_debug(*igbase(), igbase()->game().map().get_fcoords(building_.get_position()));
+	show_field_debug(*igbase(), igbase()->game().map().get_fcoords(building_->get_position()));
 }
 
 /**
@@ -424,15 +430,15 @@
 		return;  // already shown, nothing to be done
 	}
 	WorkareaInfo workarea_info;
-	if (upcast(Widelands::ConstructionSite, csite, &building_)) {
+	if (upcast(Widelands::ConstructionSite, csite, building_)) {
 		workarea_info = csite->building().workarea_info_;
 	} else {
-		workarea_info = building_.descr().workarea_info_;
+		workarea_info = building_->descr().workarea_info_;
 	}
 	if (workarea_info.empty()) {
 		return;
 	}
-	workarea_overlay_id_ = igbase()->show_work_area(workarea_info, building_.get_position());
+	workarea_overlay_id_ = igbase()->show_work_area(workarea_info, building_->get_position());
 
 	configure_workarea_button();
 }
@@ -485,7 +491,7 @@
  * for the corresponding button.
  */
 void BuildingWindow::clicked_goto() {
-	igbase()->scroll_to_field(building().get_position(), MapView::Transition::Smooth);
+	igbase()->scroll_to_field(building()->get_position(), MapView::Transition::Smooth);
 }
 
 void BuildingWindow::update_expedition_button(bool expedition_was_canceled) {

=== modified file 'src/wui/buildingwindow.h'
--- src/wui/buildingwindow.h	2017-02-27 18:28:39 +0000
+++ src/wui/buildingwindow.h	2017-06-04 08:48:14 +0000
@@ -51,7 +51,7 @@
 
 	virtual ~BuildingWindow();
 
-	Widelands::Building& building() {
+	Widelands::Building* building() {
 		return building_;
 	}
 
@@ -64,6 +64,7 @@
 
 protected:
 	virtual void init(bool avoid_fastclick);
+	void die() override;
 
 	UI::TabPanel* get_tabs() {
 		return tabs_;
@@ -92,7 +93,7 @@
 	InteractiveGameBase* parent_;
 	/// Actions performed when a NoteBuilding is received.
 	void on_building_note(const Widelands::NoteBuilding& note);
-	Widelands::Building& building_;
+	Widelands::Building* building_;
 
 	std::unique_ptr<UI::Box> vbox_;
 

=== modified file 'src/wui/constructionsitewindow.cc'
--- src/wui/constructionsitewindow.cc	2017-02-27 18:28:39 +0000
+++ src/wui/constructionsitewindow.cc	2017-06-04 08:48:14 +0000
@@ -37,7 +37,7 @@
 
 void ConstructionSiteWindow::init(bool avoid_fastclick) {
 	BuildingWindow::init(avoid_fastclick);
-	Widelands::ConstructionSite& cs = dynamic_cast<Widelands::ConstructionSite&>(building());
+	Widelands::ConstructionSite* cs = dynamic_cast<Widelands::ConstructionSite*>(building());
 	UI::Box& box = *new UI::Box(get_tabs(), 0, 0, UI::Box::Vertical);
 
 	// Add the progress bar
@@ -49,12 +49,12 @@
 	box.add_space(8);
 
 	// Add the wares queue
-	for (uint32_t i = 0; i < cs.get_nrwaresqueues(); ++i)
-		box.add(new InputQueueDisplay(&box, 0, 0, *igbase(), cs, cs.get_waresqueue(i)));
+	for (uint32_t i = 0; i < cs->get_nrwaresqueues(); ++i)
+		box.add(new InputQueueDisplay(&box, 0, 0, *igbase(), *cs, cs->get_waresqueue(i)));
 
 	get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), &box, _("Building materials"));
 
-	set_title((boost::format("(%s)") % cs.building().descname()).str());
+	set_title((boost::format("(%s)") % cs->building().descname()).str());
 	think();
 }
 
@@ -66,7 +66,7 @@
 void ConstructionSiteWindow::think() {
 	BuildingWindow::think();
 
-	const Widelands::ConstructionSite& cs = dynamic_cast<Widelands::ConstructionSite&>(building());
+	const Widelands::ConstructionSite* cs = dynamic_cast<Widelands::ConstructionSite*>(building());
 
-	progress_->set_state(cs.get_built_per64k());
+	progress_->set_state(cs->get_built_per64k());
 }

=== modified file 'src/wui/dismantlesitewindow.cc'
--- src/wui/dismantlesitewindow.cc	2017-02-27 12:21:59 +0000
+++ src/wui/dismantlesitewindow.cc	2017-06-04 08:48:14 +0000
@@ -34,7 +34,7 @@
 
 void DismantleSiteWindow::init(bool avoid_fastclick) {
 	BuildingWindow::init(avoid_fastclick);
-	Widelands::DismantleSite& ds = dynamic_cast<Widelands::DismantleSite&>(building());
+	Widelands::DismantleSite* ds = dynamic_cast<Widelands::DismantleSite*>(building());
 	UI::Box& box = *new UI::Box(get_tabs(), 0, 0, UI::Box::Vertical);
 
 	// Add the progress bar
@@ -46,8 +46,8 @@
 	box.add_space(8);
 
 	// Add the wares queue
-	for (uint32_t i = 0; i < ds.get_nrwaresqueues(); ++i)
-		BuildingWindow::create_input_queue_panel(&box, ds, ds.get_waresqueue(i), true);
+	for (uint32_t i = 0; i < ds->get_nrwaresqueues(); ++i)
+		BuildingWindow::create_input_queue_panel(&box, *ds, ds->get_waresqueue(i), true);
 
 	get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), &box, _("Building materials"));
 	think();
@@ -61,7 +61,7 @@
 void DismantleSiteWindow::think() {
 	BuildingWindow::think();
 
-	const Widelands::DismantleSite& ds = dynamic_cast<Widelands::DismantleSite&>(building());
+	const Widelands::DismantleSite* ds = dynamic_cast<Widelands::DismantleSite*>(building());
 
-	progress_->set_state(ds.get_built_per64k());
+	progress_->set_state(ds->get_built_per64k());
 }

=== modified file 'src/wui/militarysitewindow.cc'
--- src/wui/militarysitewindow.cc	2017-02-27 18:28:39 +0000
+++ src/wui/militarysitewindow.cc	2017-06-04 08:48:14 +0000
@@ -41,6 +41,6 @@
 void MilitarySiteWindow::init(bool avoid_fastclick) {
 	BuildingWindow::init(avoid_fastclick);
 	get_tabs()->add("soldiers", g_gr->images().get(pic_tab_military),
-	                create_soldier_list(*get_tabs(), *igbase(), militarysite()), _("Soldiers"));
+	                create_soldier_list(*get_tabs(), *igbase(), *militarysite()), _("Soldiers"));
 	think();
 }

=== modified file 'src/wui/militarysitewindow.h'
--- src/wui/militarysitewindow.h	2017-02-14 12:11:58 +0000
+++ src/wui/militarysitewindow.h	2017-06-04 08:48:14 +0000
@@ -32,8 +32,8 @@
 	                   Widelands::MilitarySite&,
 	                   bool avoid_fastclick);
 
-	Widelands::MilitarySite& militarysite() {
-		return dynamic_cast<Widelands::MilitarySite&>(building());
+	Widelands::MilitarySite* militarysite() {
+		return dynamic_cast<Widelands::MilitarySite*>(building());
 	}
 
 protected:

=== modified file 'src/wui/productionsitewindow.cc'
--- src/wui/productionsitewindow.cc	2017-02-27 18:28:39 +0000
+++ src/wui/productionsitewindow.cc	2017-06-04 08:48:14 +0000
@@ -45,7 +45,7 @@
    : BuildingWindow(parent, reg, ps, avoid_fastclick) {
 	productionsitenotes_subscriber_ = Notifications::subscribe<Widelands::NoteBuilding>(
 	   [this](const Widelands::NoteBuilding& note) {
-		   if (note.serial == building().serial() && !is_dying_) {
+		   if (note.serial == building()->serial() && !is_dying_) {
 			   switch (note.action) {
 			   case Widelands::NoteBuilding::Action::kWorkersChanged:
 				   update_worker_table();
@@ -60,7 +60,7 @@
 
 void ProductionSiteWindow::init(bool avoid_fastclick) {
 	BuildingWindow::init(avoid_fastclick);
-	const std::vector<Widelands::InputQueue*>& inputqueues = productionsite().inputqueues();
+	const std::vector<Widelands::InputQueue*>& inputqueues = productionsite()->inputqueues();
 
 	if (inputqueues.size()) {
 		// Add the wares tab
@@ -69,14 +69,14 @@
 
 		for (uint32_t i = 0; i < inputqueues.size(); ++i) {
 			prod_box->add(
-			   new InputQueueDisplay(prod_box, 0, 0, *igbase(), productionsite(), inputqueues[i]));
+			   new InputQueueDisplay(prod_box, 0, 0, *igbase(), *productionsite(), inputqueues[i]));
 		}
 
 		get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), prod_box, _("Wares"));
 	}
 
 	// Add workers tab if applicable
-	if (!productionsite().descr().nr_working_positions()) {
+	if (!productionsite()->descr().nr_working_positions()) {
 		worker_table_ = nullptr;
 	} else {
 		UI::Box* worker_box = new UI::Box(get_tabs(), 0, 0, UI::Box::Vertical);
@@ -84,16 +84,16 @@
 		worker_caps_ = new UI::Box(worker_box, 0, 0, UI::Box::Horizontal);
 
 		worker_table_->add_column(
-		   210, (ngettext("Worker", "Workers", productionsite().descr().nr_working_positions())));
+		   210, (ngettext("Worker", "Workers", productionsite()->descr().nr_working_positions())));
 		worker_table_->add_column(60, _("Exp"));
 		worker_table_->add_column(150, _("Next Level"));
 
-		for (unsigned int i = 0; i < productionsite().descr().nr_working_positions(); ++i) {
+		for (unsigned int i = 0; i < productionsite()->descr().nr_working_positions(); ++i) {
 			worker_table_->add(i);
 		}
 		worker_table_->fit_height();
 
-		if (igbase()->can_act(building().owner().player_number())) {
+		if (igbase()->can_act(building()->owner().player_number())) {
 			worker_caps_->add_inf_space();
 			UI::Button* evict_button = new UI::Button(
 			   worker_caps_, "evict", 0, 0, 34, 34, g_gr->images().get("images/ui_basic/but4.png"),
@@ -109,7 +109,7 @@
 		worker_box->add(worker_caps_, UI::Box::Resizing::kFullSize);
 		get_tabs()->add(
 		   "workers", g_gr->images().get(pic_tab_workers), worker_box,
-		   (ngettext("Worker", "Workers", productionsite().descr().nr_working_positions())));
+		   (ngettext("Worker", "Workers", productionsite()->descr().nr_working_positions())));
 		update_worker_table();
 	}
 	think();
@@ -119,8 +119,8 @@
 	BuildingWindow::think();
 	// If we have pending requests, update table each tick.
 	// This is required to update from 'vacant' to 'coming'
-	for (unsigned int i = 0; i < productionsite().descr().nr_working_positions(); ++i) {
-		Widelands::Request* r = productionsite().working_positions()[i].worker_request;
+	for (unsigned int i = 0; i < productionsite()->descr().nr_working_positions(); ++i) {
+		Widelands::Request* r = productionsite()->working_positions()[i].worker_request;
 		if (r) {
 			update_worker_table();
 			break;
@@ -132,11 +132,11 @@
 	if (worker_table_ == nullptr) {
 		return;
 	}
-	assert(productionsite().descr().nr_working_positions() == worker_table_->size());
+	assert(productionsite()->descr().nr_working_positions() == worker_table_->size());
 
-	for (unsigned int i = 0; i < productionsite().descr().nr_working_positions(); ++i) {
-		const Widelands::Worker* worker = productionsite().working_positions()[i].worker;
-		const Widelands::Request* request = productionsite().working_positions()[i].worker_request;
+	for (unsigned int i = 0; i < productionsite()->descr().nr_working_positions(); ++i) {
+		const Widelands::Worker* worker = productionsite()->working_positions()[i].worker;
+		const Widelands::Request* request = productionsite()->working_positions()[i].worker_request;
 		UI::Table<uintptr_t>::EntryRecord& er = worker_table_->get_record(i);
 
 		if (worker) {
@@ -162,7 +162,7 @@
 			}
 		} else if (request) {
 			const Widelands::WorkerDescr* desc =
-			   productionsite().owner().tribe().get_worker_descr(request->get_index());
+			   productionsite()->owner().tribe().get_worker_descr(request->get_index());
 			er.set_picture(0, desc->icon(), request->is_open() ? _("(vacant)") : _("(coming)"));
 
 			er.set_string(1, "");
@@ -177,7 +177,7 @@
 void ProductionSiteWindow::evict_worker() {
 	if (worker_table_->has_selection()) {
 		Widelands::Worker* worker =
-		   productionsite().working_positions()[worker_table_->get_selected()].worker;
+		   productionsite()->working_positions()[worker_table_->get_selected()].worker;
 		if (worker) {
 			igbase()->game().send_player_evict_worker(*worker);
 		}

=== modified file 'src/wui/productionsitewindow.h'
--- src/wui/productionsitewindow.h	2017-02-14 12:11:58 +0000
+++ src/wui/productionsitewindow.h	2017-06-04 08:48:14 +0000
@@ -32,8 +32,8 @@
 	                     Widelands::ProductionSite&,
 	                     bool avoid_fastclick);
 
-	Widelands::ProductionSite& productionsite() {
-		return dynamic_cast<Widelands::ProductionSite&>(building());
+	Widelands::ProductionSite* productionsite() {
+		return dynamic_cast<Widelands::ProductionSite*>(building());
 	}
 	void update_worker_table();
 

=== modified file 'src/wui/trainingsitewindow.cc'
--- src/wui/trainingsitewindow.cc	2017-02-27 18:28:39 +0000
+++ src/wui/trainingsitewindow.cc	2017-06-04 08:48:14 +0000
@@ -40,7 +40,7 @@
 void TrainingSiteWindow::init(bool avoid_fastclick) {
 	ProductionSiteWindow::init(avoid_fastclick);
 	get_tabs()->add("soldiers", g_gr->images().get(pic_tab_military),
-	                create_soldier_list(*get_tabs(), *igbase(), trainingsite()),
+	                create_soldier_list(*get_tabs(), *igbase(), *trainingsite()),
 	                _("Soldiers in training"));
 	think();
 }

=== modified file 'src/wui/trainingsitewindow.h'
--- src/wui/trainingsitewindow.h	2017-02-14 12:11:58 +0000
+++ src/wui/trainingsitewindow.h	2017-06-04 08:48:14 +0000
@@ -33,8 +33,8 @@
 	                   Widelands::TrainingSite&,
 	                   bool avoid_fastclick);
 
-	Widelands::TrainingSite& trainingsite() {
-		return dynamic_cast<Widelands::TrainingSite&>(building());
+	Widelands::TrainingSite* trainingsite() {
+		return dynamic_cast<Widelands::TrainingSite*>(building());
 	}
 
 protected:

=== modified file 'src/wui/warehousewindow.cc'
--- src/wui/warehousewindow.cc	2017-05-14 04:38:39 +0000
+++ src/wui/warehousewindow.cc	2017-06-04 08:48:14 +0000
@@ -184,14 +184,14 @@
 	BuildingWindow::init(avoid_fastclick);
 	get_tabs()->add(
 	   "wares", g_gr->images().get(pic_tab_wares),
-	   new WarehouseWaresPanel(get_tabs(), Width, *igbase(), warehouse(), Widelands::wwWARE),
+	   new WarehouseWaresPanel(get_tabs(), Width, *igbase(), *warehouse(), Widelands::wwWARE),
 	   _("Wares"));
 	get_tabs()->add(
 	   "workers", g_gr->images().get(pic_tab_workers),
-	   new WarehouseWaresPanel(get_tabs(), Width, *igbase(), warehouse(), Widelands::wwWORKER),
+	   new WarehouseWaresPanel(get_tabs(), Width, *igbase(), *warehouse(), Widelands::wwWORKER),
 	   _("Workers"));
 
-	if (Widelands::PortDock* pd = warehouse().get_portdock()) {
+	if (Widelands::PortDock* pd = warehouse()->get_portdock()) {
 		get_tabs()->add("dock_wares", g_gr->images().get(pic_tab_dock_wares),
 		                create_portdock_wares_display(get_tabs(), Width, *pd, Widelands::wwWARE),
 		                _("Wares waiting to be shipped"));
@@ -200,7 +200,7 @@
 		                _("Workers waiting to embark"));
 		if (pd->expedition_started()) {
 			get_tabs()->add("expedition_wares_queue", g_gr->images().get(pic_tab_expedition),
-			                create_portdock_expedition_display(get_tabs(), warehouse(), *igbase()),
+			                create_portdock_expedition_display(get_tabs(), *warehouse(), *igbase()),
 			                _("Expedition"));
 		}
 	}

=== modified file 'src/wui/warehousewindow.h'
--- src/wui/warehousewindow.h	2017-02-14 12:11:58 +0000
+++ src/wui/warehousewindow.h	2017-06-04 08:48:14 +0000
@@ -32,8 +32,8 @@
 	                Widelands::Warehouse&,
 	                bool avoid_fastclick);
 
-	Widelands::Warehouse& warehouse() {
-		return dynamic_cast<Widelands::Warehouse&>(building());
+	Widelands::Warehouse* warehouse() {
+		return dynamic_cast<Widelands::Warehouse*>(building());
 	}
 
 protected:


Follow ups