← Back to team overview

widelands-dev team mailing list archive

[Merge] lp:~widelands-dev/widelands/refactoring-input-queue into lp:widelands

 

Notabilis has proposed merging lp:~widelands-dev/widelands/refactoring-input-queue into lp:widelands.

Requested reviews:
  Widelands Developers (widelands-dev)

For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/refactoring-input-queue/+merge/315313

Replaces usage of WareQueue with the new InputQueue where it makes sense,
simplifying some code parts in the process.
-- 
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/refactoring-input-queue into lp:widelands.
=== modified file 'src/ai/defaultai.cc'
--- src/ai/defaultai.cc	2017-01-06 09:00:11 +0000
+++ src/ai/defaultai.cc	2017-01-22 16:41:24 +0000
@@ -3117,11 +3117,11 @@
 	// the site is pending for upgrade - one possible cause is this is a freshly loaded game
 	if (!site.upgrade_pending) {
 		bool resetting_wares = false;
-		for (auto& queue : site.site->warequeues()) {
+		for (auto& queue : site.site->inputqueues()) {
 			if (queue->get_max_fill() == 0) {
 				resetting_wares = true;
 				game().send_player_set_input_max_fill(
-				   *site.site, queue->get_index(), wwWARE, queue->get_max_size());
+				   *site.site, queue->get_index(), queue->get_type(), queue->get_max_size());
 			}
 		}
 		if (resetting_wares) {
@@ -3135,7 +3135,7 @@
 		// The site is in process of emptying its input queues
 		// Counting remaining wares in the site now
 		int32_t left_wares = 0;
-		for (auto& queue : site.site->warequeues()) {
+		for (auto& queue : site.site->inputqueues()) {
 			left_wares += queue->get_filled();
 		}
 		// Do nothing when some wares are left, but do not wait more then 4 minutes
@@ -3221,8 +3221,8 @@
 		if (doing_upgrade) {
 
 			// reducing input queues
-			for (auto& queue : site.site->warequeues()) {
-				game().send_player_set_input_max_fill(*site.site, queue->get_index(), wwWARE, 0);
+			for (auto& queue : site.site->inputqueues()) {
+				game().send_player_set_input_max_fill(*site.site, queue->get_index(), queue->get_type(), 0);
 			}
 			site.bo->construction_decision_time = gametime;
 			en_bo.construction_decision_time = gametime;

=== modified file 'src/ai/defaultai_seafaring.cc'
--- src/ai/defaultai_seafaring.cc	2016-12-08 17:27:00 +0000
+++ src/ai/defaultai_seafaring.cc	2017-01-22 16:41:24 +0000
@@ -133,10 +133,11 @@
 
 			// counting stocks
 			uint8_t stocked_wares = 0;
-			std::vector<WaresQueue*> const warequeues = ps_obs.site->warequeues();
-			size_t const nr_warequeues = warequeues.size();
-			for (size_t i = 0; i < nr_warequeues; ++i) {
-				stocked_wares += warequeues[i]->get_filled();
+			std::vector<InputQueue*> const inputqueues = ps_obs.site->inputqueues();
+			for (InputQueue *queue : inputqueues) {
+				if (queue->get_type() == wwWARE) {
+					stocked_wares += queue->get_filled();
+				}
 			}
 			if (stocked_wares == 16 && ps_obs.site->is_stopped() && ps_obs.site->can_start_working()) {
 				idle_shipyard_stocked = true;
@@ -188,10 +189,11 @@
 				// make sure it is fully stocked
 				// counting stocks
 				uint8_t stocked_wares = 0;
-				std::vector<WaresQueue*> const warequeues = ps_obs.site->warequeues();
-				size_t const nr_warequeues = warequeues.size();
-				for (size_t i = 0; i < nr_warequeues; ++i) {
-					stocked_wares += warequeues[i]->get_filled();
+				std::vector<InputQueue*> const inputqueues = ps_obs.site->inputqueues();
+				for (InputQueue *queue : inputqueues) {
+					if (queue->get_type() == wwWARE) {
+						stocked_wares += queue->get_filled();
+					}
 				}
 				if (stocked_wares < 16) {
 					continue;

=== modified file 'src/ai/defaultai_warfare.cc'
--- src/ai/defaultai_warfare.cc	2017-01-06 09:00:11 +0000
+++ src/ai/defaultai_warfare.cc	2017-01-22 16:41:24 +0000
@@ -478,22 +478,26 @@
 	// reducing ware queues
 	// - for armours and weapons to 1
 	// - for others to 6
-	std::vector<WaresQueue*> const warequeues1 = tso.site->warequeues();
-	size_t nr_warequeues = warequeues1.size();
-	for (size_t i = 0; i < nr_warequeues; ++i) {
+	// - for others to 6
+	std::vector<InputQueue*> const inputqueues1 = tso.site->inputqueues();
+	for (InputQueue *queue : inputqueues1) {
+
+		if (queue->get_type() != wwWARE) {
+			continue;
+		}
 
 		// if it was decreased yet
-		if (warequeues1[i]->get_max_fill() <= 1) {
+		if (queue->get_max_fill() <= 1) {
 			continue;
 		}
 
 		// now modifying max_fill of armors and weapons
 		for (std::string pattern : armors_and_weapons) {
 
-			if (tribe_->get_ware_descr(warequeues1[i]->get_index())->name().find(pattern) !=
+			if (tribe_->get_ware_descr(queue->get_index())->name().find(pattern) !=
 			    std::string::npos) {
-				if (warequeues1[i]->get_max_fill() > 1) {
-					game().send_player_set_input_max_fill(*ts, warequeues1[i]->get_index(), wwWARE, 1);
+				if (queue->get_max_fill() > 1) {
+					game().send_player_set_input_max_fill(*ts, queue->get_index(), wwWARE, 1);
 					continue;
 				}
 			}
@@ -518,11 +522,13 @@
 		// minutes)
 		// we can accept also shortage up to 3
 		int32_t shortage = 0;
-		std::vector<WaresQueue*> const warequeues2 = tso.site->warequeues();
-		nr_warequeues = warequeues2.size();
-		for (size_t i = 0; i < nr_warequeues; ++i) {
-			if (tso.bo->substitute_inputs.count(warequeues2[i]->get_index()) > 0) {
-				filled += warequeues2[i]->get_filled();
+		std::vector<InputQueue*> const inputqueues2 = tso.site->inputqueues();
+		for (InputQueue *queue : inputqueues2) {
+			if (queue->get_type() != wwWARE) {
+				continue;
+			}
+			if (tso.bo->substitute_inputs.count(queue->get_index()) > 0) {
+				filled += queue->get_filled();
 			}
 		}
 		if (filled < 5) {
@@ -530,12 +536,15 @@
 		}
 
 		// checking non subsitutes
-		for (size_t i = 0; i < nr_warequeues; ++i) {
-			if (tso.bo->substitute_inputs.count(warequeues2[i]->get_index()) == 0) {
+		for (InputQueue *queue : inputqueues2) {
+			if (queue->get_type() != wwWARE) {
+				continue;
+			}
+			if (tso.bo->substitute_inputs.count(queue->get_index()) == 0) {
 				const uint32_t required_amount =
-				   (warequeues2[i]->get_max_fill() < 5) ? warequeues2[i]->get_max_fill() : 5;
-				if (warequeues2[i]->get_filled() < required_amount) {
-					shortage += required_amount - warequeues2[i]->get_filled();
+				   (queue->get_max_fill() < 5) ? queue->get_max_fill() : 5;
+				if (queue->get_filled() < required_amount) {
+					shortage += required_amount - queue->get_filled();
 				}
 			}
 		}

=== modified file 'src/economy/input_queue.h'
--- src/economy/input_queue.h	2017-01-05 19:51:34 +0000
+++ src/economy/input_queue.h	2017-01-22 16:41:24 +0000
@@ -53,7 +53,7 @@
 	 * when wares or workers arrive at the building and should be added to the queue.
 	 * @param game The game the queue is part of.
 	 * @param q The \c InputQueue the ware or worker should be added to.
-	 * @param ware The index of the ware which arrived, if the queue is a WaresQueue.
+	 * @param ware The index of the ware or worker which arrived.
 	 * @param worker The worker which arrived, if the queue is a WorkersQueue.
 	 * @param data Unspecified data which has been given when calling set_callback().
 	 */

=== modified file 'src/logic/map_objects/tribes/building.cc'
--- src/logic/map_objects/tribes/building.cc	2017-01-06 09:00:11 +0000
+++ src/logic/map_objects/tribes/building.cc	2017-01-22 16:41:24 +0000
@@ -32,8 +32,6 @@
 #include "economy/flag.h"
 #include "economy/input_queue.h"
 #include "economy/request.h"
-#include "economy/wares_queue.h"
-#include "economy/workers_queue.h"
 #include "graphic/graphic.h"
 #include "graphic/rendertarget.h"
 #include "io/filesystem/filesystem.h"
@@ -480,19 +478,7 @@
 }
 
 InputQueue& Building::inputqueue(DescriptionIndex const wi, WareWorker const t) {
-	if (t == wwWARE) {
-		return waresqueue(wi);
-	} else {
-		return workersqueue(wi);
-	}
-}
-
-WaresQueue& Building::waresqueue(DescriptionIndex const wi) {
-	throw wexception("%s (%u) has no WaresQueue for %u", descr().name().c_str(), serial(), wi);
-}
-
-WorkersQueue& Building::workersqueue(DescriptionIndex const wi) {
-	throw wexception("%s (%u) has no WorkersQueue for %u", descr().name().c_str(), serial(), wi);
+	throw wexception("%s (%u) has no InputQueue for %u", descr().name().c_str(), serial(), wi);
 }
 
 /*

=== modified file 'src/logic/map_objects/tribes/building.h'
--- src/logic/map_objects/tribes/building.h	2016-12-05 09:24:10 +0000
+++ src/logic/map_objects/tribes/building.h	2017-01-22 16:41:24 +0000
@@ -50,8 +50,6 @@
 struct Message;
 class TribeDescr;
 class InputQueue;
-class WaresQueue;
-class WorkersQueue;
 
 class Building;
 
@@ -240,12 +238,6 @@
 	/// \returns the queue for the matching ware or worker type or \throws WException.
 	virtual InputQueue& inputqueue(DescriptionIndex, WareWorker);
 
-	/// \returns the queue for a ware type or \throws WException.
-	virtual WaresQueue& waresqueue(DescriptionIndex);
-
-	/// \returns the queue for a worker type or \throws WException.
-	virtual WorkersQueue& workersqueue(DescriptionIndex);
-
 	virtual bool burn_on_destroy();
 	void destroy(EditorGameBase&) override;
 

=== modified file 'src/logic/map_objects/tribes/constructionsite.cc'
--- src/logic/map_objects/tribes/constructionsite.cc	2016-12-05 09:24:10 +0000
+++ src/logic/map_objects/tribes/constructionsite.cc	2017-01-22 16:41:24 +0000
@@ -80,14 +80,20 @@
 Access to the wares queues by id
 =======
 */
-WaresQueue& ConstructionSite::waresqueue(DescriptionIndex const wi) {
+InputQueue& ConstructionSite::inputqueue(DescriptionIndex const wi, WareWorker const type) {
+    // There are no worker queues here
+    // Hopefully, our construction sites are save enough not to kill workers
+    if (type != wwWARE) {
+		throw wexception("%s (%u) (building %s) has no WorkersQueues", descr().name().c_str(),
+					 serial(), building_->name().c_str());
+	}
 	for (WaresQueue* ware : wares_) {
 		if (ware->get_index() == wi) {
 			return *ware;
 		}
 	}
 	throw wexception("%s (%u) (building %s) has no WaresQueue for %u", descr().name().c_str(),
-	                 serial(), building_->name().c_str(), wi);
+					 serial(), building_->name().c_str(), wi);
 }
 
 /*

=== modified file 'src/logic/map_objects/tribes/constructionsite.h'
--- src/logic/map_objects/tribes/constructionsite.h	2016-11-13 22:30:07 +0000
+++ src/logic/map_objects/tribes/constructionsite.h	2017-01-22 16:41:24 +0000
@@ -89,7 +89,7 @@
 		return info_;
 	}
 
-	WaresQueue& waresqueue(DescriptionIndex) override;
+	InputQueue& inputqueue(DescriptionIndex, WareWorker) override;
 
 	void set_building(const BuildingDescr&) override;
 	const BuildingDescr& building() const {

=== modified file 'src/logic/map_objects/tribes/production_program.cc'
--- src/logic/map_objects/tribes/production_program.cc	2017-01-21 21:10:21 +0000
+++ src/logic/map_objects/tribes/production_program.cc	2017-01-22 16:41:24 +0000
@@ -31,8 +31,7 @@
 #include "config.h"
 #include "economy/economy.h"
 #include "economy/flag.h"
-#include "economy/wares_queue.h"
-#include "economy/workers_queue.h"
+#include "economy/input_queue.h"
 #include "graphic/graphic.h"
 #include "helper.h"
 #include "io/filesystem/layered_filesystem.h"
@@ -356,9 +355,9 @@
 }
 bool ProductionProgram::ActReturn::SiteHas::evaluate(const ProductionSite& ps) const {
 	uint8_t count = group.second;
-	for (WaresQueue* ip_queue : ps.warequeues()) {
-		for (const auto& ware_type : group.first) {
-			if (ware_type.first == ip_queue->get_index() && ware_type.second == wwWARE) {
+	for (InputQueue* ip_queue : ps.inputqueues()) {
+		for (const auto& input_type : group.first) {
+			if (input_type.first == ip_queue->get_index() && input_type.second == ip_queue->get_type()) {
 				uint8_t const filled = ip_queue->get_filled();
 				if (count <= filled)
 					return true;
@@ -804,39 +803,38 @@
 }
 
 void ProductionProgram::ActConsume::execute(Game& game, ProductionSite& ps) const {
-	std::vector<WaresQueue*> const warequeues = ps.warequeues();
-	std::vector<WorkersQueue*> const workerqueues = ps.workerqueues();
-	std::vector<uint8_t> consumption_quantities_wares(warequeues.size(), 0);
-	std::vector<uint8_t> consumption_quantities_workers(workerqueues.size(), 0);
+	std::vector<InputQueue*> const inputqueues = ps.inputqueues();
+	std::vector<uint8_t> consumption_quantities(inputqueues.size(), 0);
 
 	Groups l_groups = consumed_wares_workers_;  //  make a copy for local modification
 
 	//  Iterate over all input queues and see how much we should consume from
 	//  each of them.
 	bool found;
-	for (size_t i = 0; i < warequeues.size(); ++i) {
-		DescriptionIndex const ware_type = warequeues[i]->get_index();
-		uint8_t nr_available = warequeues[i]->get_filled();
-		consumption_quantities_wares[i] = 0;
+	for (size_t i = 0; i < inputqueues.size(); ++i) {
+		DescriptionIndex const input_index = inputqueues[i]->get_index();
+		WareWorker const input_type = inputqueues[i]->get_type();
+		uint8_t nr_available = inputqueues[i]->get_filled();
+		consumption_quantities[i] = 0;
 
 		//  Iterate over all consume groups and see if they want us to consume
 		//  any thing from the currently considered input queue.
 		for (Groups::iterator it = l_groups.begin(); it != l_groups.end();) {
 			found = false;
-			for (auto ware_it = it->first.begin(); ware_it != it->first.end(); ware_it++) {
-				if (ware_it->first == ware_type && ware_it->second == wwWARE) {
+			for (auto input_it = it->first.begin(); input_it != it->first.end(); input_it++) {
+				if (input_it->first == input_index && input_it->second == input_type) {
 					found = true;
 					if (it->second <= nr_available) {
 						//  There are enough wares of the currently considered type
 						//  to fulfill the requirements of the current group. We can
 						//  therefore erase the group.
-						consumption_quantities_wares[i] += it->second;
+						consumption_quantities[i] += it->second;
 						nr_available -= it->second;
 						it = l_groups.erase(it);
 						//  No increment here, erase moved next element to the position
 						//  pointed to by it.
 					} else {
-						consumption_quantities_wares[i] += nr_available;
+						consumption_quantities[i] += nr_available;
 						it->second -= nr_available;
 						++it;  //  Now check if the next group includes this ware type.
 					}
@@ -849,34 +847,6 @@
 		}
 	}
 
-	// Same for workers
-	for (size_t i = 0; i < workerqueues.size(); ++i) {
-		DescriptionIndex const worker_type = workerqueues[i]->get_index();
-		uint8_t nr_available = workerqueues[i]->get_filled();
-		consumption_quantities_workers[i] = 0;
-
-		for (Groups::iterator it = l_groups.begin(); it != l_groups.end();) {
-			found = false;
-			for (auto worker_it = it->first.begin(); worker_it != it->first.end(); worker_it++) {
-				if (worker_it->first == worker_type && worker_it->second == wwWORKER) {
-					found = true;
-					if (it->second <= nr_available) {
-						consumption_quantities_workers[i] += it->second;
-						nr_available -= it->second;
-						it = l_groups.erase(it);
-					} else {
-						consumption_quantities_workers[i] += nr_available;
-						it->second -= nr_available;
-						++it;
-					}
-					break;
-				}
-			}
-			if (!found)
-				++it;
-		}
-	}
-
 	// "Did not start working because .... is/are missing"
 	if (uint8_t const nr_missing_groups = l_groups.size()) {
 		const TribeDescr& tribe = ps.owner().tribe();
@@ -934,19 +904,15 @@
 		ps.set_production_result(result_string);
 		return ps.program_end(game, Failed);
 	} else {  //  we fulfilled all consumption requirements
-		for (size_t i = 0; i < warequeues.size(); ++i) {
-			if (uint8_t const q = consumption_quantities_wares[i]) {
-				assert(q <= warequeues[i]->get_filled());
-				warequeues[i]->set_filled(warequeues[i]->get_filled() - q);
+		for (size_t i = 0; i < inputqueues.size(); ++i) {
+			if (uint8_t const q = consumption_quantities[i]) {
+				assert(q <= inputqueues[i]->get_filled());
+				inputqueues[i]->set_filled(inputqueues[i]->get_filled() - q);
 
-				// Update consumption statistics
-				ps.owner().ware_consumed(warequeues[i]->get_index(), q);
-			}
-		}
-		for (size_t i = 0; i < workerqueues.size(); ++i) {
-			if (uint8_t const q = consumption_quantities_workers[i]) {
-				assert(q <= workerqueues[i]->get_filled());
-				workerqueues[i]->set_filled(workerqueues[i]->get_filled() - q);
+				// Update consumption statistic
+				if (inputqueues[i]->get_type() == wwWARE) {
+					ps.owner().ware_consumed(inputqueues[i]->get_index(), q);
+				}
 			}
 		}
 		return ps.program_step(game);
@@ -1508,7 +1474,7 @@
 	DescriptionIndex available_resource = INVALID_INDEX;
 
 	for (Buildcost::const_iterator it = buildcost.begin(); it != buildcost.end(); ++it) {
-		if (psite.waresqueue(it->first).get_filled() > 0) {
+		if (psite.inputqueue(it->first, wwWARE).get_filled() > 0) {
 			available_resource = it->first;
 			break;
 		}
@@ -1597,7 +1563,7 @@
 	}
 
 	for (Buildcost::const_iterator it = remaining.begin(); it != remaining.end(); ++it) {
-		WaresQueue& thiswq = psite.waresqueue(it->first);
+		WaresQueue& thiswq = dynamic_cast<WaresQueue&>(psite.inputqueue(it->first, wwWARE));
 		if (thiswq.get_filled() > 0) {
 			wq = &thiswq;
 			break;

=== modified file 'src/logic/map_objects/tribes/productionsite.cc'
--- src/logic/map_objects/tribes/productionsite.cc	2017-01-06 09:00:11 +0000
+++ src/logic/map_objects/tribes/productionsite.cc	2017-01-22 16:41:24 +0000
@@ -27,6 +27,7 @@
 #include "base/macros.h"
 #include "base/wexception.h"
 #include "economy/economy.h"
+#include "economy/input_queue.h"
 #include "economy/request.h"
 #include "economy/ware_instance.h"
 #include "economy/wares_queue.h"
@@ -326,24 +327,13 @@
 	}
 }
 
-WaresQueue& ProductionSite::waresqueue(DescriptionIndex const wi) {
-	for (WaresQueue* ip_queue : input_ware_queues_) {
-		if (ip_queue->get_index() == wi) {
-			return *ip_queue;
-		}
-	}
-	throw wexception("%s (%u) has no WaresQueue for %u", descr().name().c_str(), serial(), wi);
-}
-
-WorkersQueue& ProductionSite::workersqueue(DescriptionIndex const wi) {
-	// Check for perfect match
-	for (WorkersQueue* ip_queue : input_worker_queues_) {
-		if (ip_queue->get_index() == wi) {
-			return *ip_queue;
-		}
-	}
-	// Only check for perfect matches since they are requested by the queue
-	throw wexception("%s (%u) has no WorkersQueue for %u", descr().name().c_str(), serial(), wi);
+InputQueue& ProductionSite::inputqueue(DescriptionIndex const wi, WareWorker const type) {
+	for (InputQueue* ip_queue : input_queues_) {
+		if (ip_queue->get_index() == wi && ip_queue->get_type() == type) {
+			return *ip_queue;
+		}
+	}
+	throw wexception("%s (%u) has no InputQueue for %u", descr().name().c_str(), serial(), wi);
 }
 
 /**
@@ -414,15 +404,15 @@
 	Building::init(egbase);
 
 	const BillOfMaterials& input_wares = descr().input_wares();
-	input_ware_queues_.resize(input_wares.size());
+	const BillOfMaterials& input_workers = descr().input_workers();
+	input_queues_.resize(input_wares.size() + input_workers.size());
+
 	for (WareRange i(input_wares); i; ++i) {
-		input_ware_queues_[i.i] = new WaresQueue(*this, i.current->first, i.current->second);
+		input_queues_[i.i] = new WaresQueue(*this, i.current->first, i.current->second);
 	}
 
-	const BillOfMaterials& input_workers = descr().input_workers();
-	input_worker_queues_.resize(input_workers.size());
 	for (WareRange i(input_workers); i; ++i) {
-		input_worker_queues_[i.i] = new WorkersQueue(*this, i.current->first, i.current->second);
+		input_queues_[input_wares.size() + i.i] = new WorkersQueue(*this, i.current->first, i.current->second);
 	}
 
 	//  Request missing workers.
@@ -447,10 +437,7 @@
  */
 void ProductionSite::set_economy(Economy* const e) {
 	if (Economy* const old = get_economy()) {
-		for (WaresQueue* ip_queue : input_ware_queues_) {
-			ip_queue->remove_from_economy(*old);
-		}
-		for (WorkersQueue* ip_queue : input_worker_queues_) {
+		for (InputQueue* ip_queue : input_queues_) {
 			ip_queue->remove_from_economy(*old);
 		}
 	}
@@ -461,10 +448,7 @@
 			r->set_economy(e);
 
 	if (e) {
-		for (WaresQueue* ip_queue : input_ware_queues_) {
-			ip_queue->add_to_economy(*e);
-		}
-		for (WorkersQueue* ip_queue : input_worker_queues_) {
+		for (InputQueue* ip_queue : input_queues_) {
 			ip_queue->add_to_economy(*e);
 		}
 	}
@@ -489,17 +473,11 @@
 	}
 
 	// Cleanup the wares queues
-	for (uint32_t i = 0; i < input_ware_queues_.size(); ++i) {
-		input_ware_queues_[i]->cleanup();
-		delete input_ware_queues_[i];
-	}
-	input_ware_queues_.clear();
-
-	for (uint32_t i = 0; i < input_worker_queues_.size(); ++i) {
-		input_worker_queues_[i]->cleanup();
-		delete input_worker_queues_[i];
-	}
-	input_worker_queues_.clear();
+	for (InputQueue *iq : input_queues_) {
+		iq->cleanup();
+		delete iq;
+	}
+	input_queues_.clear();
 
 	Building::cleanup(egbase);
 }
@@ -827,8 +805,9 @@
 	}
 
 	// Drop all the wares that are too much out to the flag.
-	for (WaresQueue* queue : input_ware_queues_) {
-		if (queue->get_filled() > queue->get_max_fill()) {
+	// Input-workers are coming out by themselves
+	for (InputQueue* queue : input_queues_) {
+		if (queue->get_type() == wwWARE && queue->get_filled() > queue->get_max_fill()) {
 			queue->set_filled(queue->get_filled() - 1);
 			const WareDescr& wd = *owner().tribe().get_ware_descr(queue->get_index());
 			WareInstance& ware = *new WareInstance(queue->get_index(), &wd);

=== modified file 'src/logic/map_objects/tribes/productionsite.h'
--- src/logic/map_objects/tribes/productionsite.h	2016-11-09 21:29:44 +0000
+++ src/logic/map_objects/tribes/productionsite.h	2017-01-22 16:41:24 +0000
@@ -195,8 +195,7 @@
 		production_result_ = text;
 	}
 
-	WaresQueue& waresqueue(DescriptionIndex) override;
-	WorkersQueue& workersqueue(DescriptionIndex) override;
+	InputQueue& inputqueue(DescriptionIndex, WareWorker) override;
 
 	void init(EditorGameBase&) override;
 	void cleanup(EditorGameBase&) override;
@@ -210,14 +209,9 @@
 
 	void set_economy(Economy*) override;
 
-	using InputQueues = std::vector<WaresQueue*>;
-	const InputQueues& warequeues() const {
-		return input_ware_queues_;
-	}
-
-	using InputWorkerQueues = std::vector<WorkersQueue*>;
-	const InputWorkerQueues& workerqueues() const {
-		return input_worker_queues_;
+	using InputQueues = std::vector<InputQueue*>;
+	const InputQueues& inputqueues() const {
+		return input_queues_;
 	}
 
 	const std::vector<Worker*>& workers() const;
@@ -313,8 +307,7 @@
 
 	BillOfMaterials produced_wares_;
 	BillOfMaterials recruited_workers_;
-	InputQueues input_ware_queues_;          ///< input queues for all inputs
-	InputWorkerQueues input_worker_queues_;  ///< input queues for workers
+	InputQueues input_queues_;          ///< input queues for all inputs
 	std::vector<bool> statistics_;
 	uint8_t last_stat_percent_;
 	// integer 0-10000000, to be divided by 10000 to get a percent, to avoid float (target range:

=== modified file 'src/logic/map_objects/tribes/ship.cc'
--- src/logic/map_objects/tribes/ship.cc	2016-12-03 13:32:28 +0000
+++ src/logic/map_objects/tribes/ship.cc	2017-01-22 16:41:24 +0000
@@ -623,7 +623,7 @@
 				if (ware) {
 					// no, we don't transfer the wares, we create new ones out of
 					// air and remove the old ones ;)
-					WaresQueue& wq = cs->waresqueue(ware->descr_index());
+					WaresQueue& wq = dynamic_cast<WaresQueue&>(cs->inputqueue(ware->descr_index(), wwWARE));
 					const uint32_t cur = wq.get_filled();
 
 					// This is to help to debug the situation when colonization fails

=== modified file 'src/logic/map_objects/tribes/warehouse.cc'
--- src/logic/map_objects/tribes/warehouse.cc	2017-01-06 09:00:11 +0000
+++ src/logic/map_objects/tribes/warehouse.cc	2017-01-22 16:41:24 +0000
@@ -1271,9 +1271,10 @@
 	}
 }
 
-WaresQueue& Warehouse::waresqueue(DescriptionIndex index) {
+InputQueue& Warehouse::inputqueue(DescriptionIndex index, WareWorker type) {
 	assert(portdock_ != nullptr);
 	assert(portdock_->expedition_bootstrap() != nullptr);
+	assert(type == wwWARE);
 
 	return portdock_->expedition_bootstrap()->waresqueue(index);
 }

=== modified file 'src/logic/map_objects/tribes/warehouse.h'
--- src/logic/map_objects/tribes/warehouse.h	2017-01-06 09:00:11 +0000
+++ src/logic/map_objects/tribes/warehouse.h	2017-01-22 16:41:24 +0000
@@ -23,6 +23,7 @@
 #include "base/macros.h"
 #include "base/wexception.h"
 #include "economy/request.h"
+#include "economy/wares_queue.h"
 #include "logic/map_objects/attackable.h"
 #include "logic/map_objects/tribes/building.h"
 #include "logic/map_objects/tribes/soldiercontrol.h"
@@ -245,7 +246,7 @@
 
 	// Returns the waresqueue of the expedition if this is a port.
 	// Will throw an exception otherwise.
-	WaresQueue& waresqueue(DescriptionIndex) override;
+	InputQueue& inputqueue(DescriptionIndex, WareWorker) override;
 
 	void log_general_info(const EditorGameBase&) override;
 

=== modified file 'src/map_io/map_buildingdata_packet.cc'
--- src/map_io/map_buildingdata_packet.cc	2017-01-06 09:00:11 +0000
+++ src/map_io/map_buildingdata_packet.cc	2017-01-22 16:41:24 +0000
@@ -26,6 +26,7 @@
 #include "base/wexception.h"
 #include "economy/expedition_bootstrap.h"
 #include "economy/flag.h"
+#include "economy/input_queue.h"
 #include "economy/portdock.h"
 #include "economy/request.h"
 #include "economy/warehousesupply.h"
@@ -674,7 +675,7 @@
 			productionsite.program_time_ = fr.signed_32();
 
 			uint16_t nr_queues = fr.unsigned_16();
-			assert(!productionsite.input_ware_queues_.size());
+			assert(!productionsite.input_queues_.size());
 			for (uint16_t i = 0; i < nr_queues; ++i) {
 				WaresQueue* wq = new WaresQueue(productionsite, INVALID_INDEX, 0);
 				wq->read(fr, game, mol);
@@ -682,13 +683,12 @@
 				if (!game.tribes().ware_exists(wq->get_index())) {
 					delete wq;
 				} else {
-					productionsite.input_ware_queues_.push_back(wq);
+					productionsite.input_queues_.push_back(wq);
 				}
 			}
 
 			if (packet_version > 5) {
 				nr_queues = fr.unsigned_16();
-				assert(!productionsite.input_worker_queues_.size());
 				for (uint16_t i = 0; i < nr_queues; ++i) {
 					WorkersQueue* wq = new WorkersQueue(productionsite, INVALID_INDEX, 0);
 					wq->read(fr, game, mol);
@@ -696,7 +696,7 @@
 					if (!game.tribes().worker_exists(wq->get_index())) {
 						delete wq;
 					} else {
-						productionsite.input_worker_queues_.push_back(wq);
+						productionsite.input_queues_.push_back(wq);
 					}
 				}
 			}
@@ -1140,16 +1140,27 @@
 	fw.unsigned_8(productionsite.program_timer_);
 	fw.signed_32(productionsite.program_time_);
 
-	const uint16_t input_queues_size = productionsite.input_ware_queues_.size();
-	fw.unsigned_16(input_queues_size);
-	for (uint16_t i = 0; i < input_queues_size; ++i) {
-		productionsite.input_ware_queues_[i]->write(fw, game, mos);
+	// Get number of ware queues. Not very pretty but avoids changing the save file format
+	uint16_t input_ware_queues_size = 0;
+	for (InputQueue *iq : productionsite.inputqueues()) {
+		if (iq->get_type() == wwWARE) {
+			input_ware_queues_size++;
+		}
+	}
+	// Write count of ware queues and ware queues
+	fw.unsigned_16(input_ware_queues_size);
+	for (InputQueue *iq : productionsite.inputqueues()) {
+		if (iq->get_type() == wwWARE) {
+			iq->write(fw, game, mos);
+		}
 	}
 
-	const uint16_t input_worker_queues_size = productionsite.input_worker_queues_.size();
-	fw.unsigned_16(input_worker_queues_size);
-	for (uint16_t i = 0; i < input_worker_queues_size; ++i) {
-		productionsite.input_worker_queues_[i]->write(fw, game, mos);
+	// Same for worker queues
+	fw.unsigned_16(productionsite.input_queues_.size() - input_ware_queues_size);
+	for (InputQueue *iq : productionsite.inputqueues()) {
+		if (iq->get_type() == wwWORKER) {
+			iq->write(fw, game, mos);
+		}
 	}
 
 	const uint16_t statistics_size = productionsite.statistics_.size();

=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc	2017-01-22 09:42:03 +0000
+++ src/scripting/lua_map.cc	2017-01-22 16:41:24 +0000
@@ -26,8 +26,7 @@
 #include "base/log.h"
 #include "base/macros.h"
 #include "base/wexception.h"
-#include "economy/wares_queue.h"
-#include "economy/workers_queue.h"
+#include "economy/input_queue.h"
 #include "graphic/graphic.h"
 #include "logic/findimmovable.h"
 #include "logic/map_objects/checkstep.h"
@@ -4669,22 +4668,12 @@
 				             ps->descr().name().c_str());
 			}
 		}
-		if (sp.first.second == wwWARE) {
-			WaresQueue& wq = ps->waresqueue(sp.first.first);
-			if (sp.second > wq.get_max_size()) {
-				report_error(
-				   L, "Not enough space for %u items, only for %i", sp.second, wq.get_max_size());
-			}
-			wq.set_filled(sp.second);
-		} else {
-			assert(sp.first.second == wwWORKER);
-			WorkersQueue& wq = ps->workersqueue(sp.first.first);
-			if (sp.second > wq.get_max_size()) {
-				report_error(
-				   L, "Not enough space for %u workers, only for %i", sp.second, wq.get_max_size());
-			}
-			wq.set_filled(sp.second);
+		InputQueue& iq = ps->inputqueue(sp.first.first, sp.first.second);
+		if (sp.second > iq.get_max_size()) {
+			report_error(
+			   L, "Not enough space for %u inputs, only for %i", sp.second, iq.get_max_size());
 		}
+		iq.set_filled(sp.second);
 	}
 
 	return 0;
@@ -4715,11 +4704,7 @@
 	for (const auto& input : input_set) {
 		uint32_t cnt = 0;
 		if (valid_inputs.count(input)) {
-			if (input.second == wwWARE) {
-				cnt = ps->waresqueue(input.first).get_filled();
-			} else {
-				cnt = ps->workersqueue(input.first).get_filled();
-			}
+			cnt = ps->inputqueue(input.first, input.second).get_filled();
 		}
 
 		if (return_number) {  // this is the only thing the customer wants to know

=== modified file 'src/wui/buildingwindow.cc'
--- src/wui/buildingwindow.cc	2017-01-21 09:41:07 +0000
+++ src/wui/buildingwindow.cc	2017-01-22 16:41:24 +0000
@@ -448,12 +448,12 @@
 	}
 }
 
-void BuildingWindow::create_ware_queue_panel(UI::Box* const box,
+void BuildingWindow::create_input_queue_panel(UI::Box* const box,
                                              Widelands::Building& b,
-                                             Widelands::WaresQueue* const wq,
+                                             Widelands::InputQueue* const iq,
                                              bool show_only) {
 	// The *max* width should be larger than the default width
-	box->add(new InputQueueDisplay(box, 0, 0, igbase(), b, wq, show_only), UI::Align::kLeft);
+	box->add(new InputQueueDisplay(box, 0, 0, igbase(), b, iq, show_only), UI::Align::kLeft);
 }
 
 /**

=== modified file 'src/wui/buildingwindow.h'
--- src/wui/buildingwindow.h	2016-08-04 15:49:05 +0000
+++ src/wui/buildingwindow.h	2017-01-22 16:41:24 +0000
@@ -78,7 +78,7 @@
 	void clicked_goto();
 
 	void
-	create_ware_queue_panel(UI::Box*, Widelands::Building&, Widelands::WaresQueue*, bool = false);
+	create_input_queue_panel(UI::Box*, Widelands::Building&, Widelands::InputQueue*, bool = false);
 
 	virtual void create_capsbuttons(UI::Box* buttons);
 

=== modified file 'src/wui/dismantlesitewindow.cc'
--- src/wui/dismantlesitewindow.cc	2016-08-04 15:59:26 +0000
+++ src/wui/dismantlesitewindow.cc	2017-01-22 16:41:24 +0000
@@ -56,7 +56,7 @@
 
 	// Add the wares queue
 	for (uint32_t i = 0; i < cs.get_nrwaresqueues(); ++i)
-		BuildingWindow::create_ware_queue_panel(&box, cs, cs.get_waresqueue(i), true);
+		BuildingWindow::create_input_queue_panel(&box, cs, cs.get_waresqueue(i), true);
 
 	get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), &box, _("Building materials"));
 }

=== modified file 'src/wui/productionsitewindow.cc'
--- src/wui/productionsitewindow.cc	2016-11-13 22:30:07 +0000
+++ src/wui/productionsitewindow.cc	2017-01-22 16:41:24 +0000
@@ -21,8 +21,8 @@
 
 #include <boost/format.hpp>
 
+#include "economy/input_queue.h"
 #include "economy/request.h"
-#include "economy/workers_queue.h"
 #include "graphic/graphic.h"
 #include "logic/map_objects/tribes/constructionsite.h"
 #include "logic/map_objects/tribes/militarysite.h"
@@ -47,21 +47,16 @@
                                            ProductionSite& ps,
                                            UI::Window*& registry)
    : BuildingWindow(parent, ps, registry) {
-	const std::vector<Widelands::WaresQueue*>& warequeues = ps.warequeues();
-	const std::vector<Widelands::WorkersQueue*>& workerqueues = ps.workerqueues();
+	const std::vector<Widelands::InputQueue*>& inputqueues = ps.inputqueues();
 
-	if (warequeues.size() || workerqueues.size()) {
+	if (inputqueues.size()) {
 		// Add the wares tab
 		UI::Box* prod_box = new UI::Box(
 		   get_tabs(), 0, 0, UI::Box::Vertical, g_gr->get_xres() - 80, g_gr->get_yres() - 80);
 
-		for (uint32_t i = 0; i < warequeues.size(); ++i) {
-			prod_box->add(
-			   new InputQueueDisplay(prod_box, 0, 0, igbase(), ps, warequeues[i]), UI::Align::kLeft);
-		}
-		for (uint32_t i = 0; i < workerqueues.size(); ++i) {
-			prod_box->add(
-			   new InputQueueDisplay(prod_box, 0, 0, igbase(), ps, workerqueues[i]), UI::Align::kLeft);
+		for (uint32_t i = 0; i < inputqueues.size(); ++i) {
+			prod_box->add(
+			   new InputQueueDisplay(prod_box, 0, 0, igbase(), ps, inputqueues[i]), UI::Align::kLeft);
 		}
 
 		get_tabs()->add("wares", g_gr->images().get(pic_tab_wares), prod_box, _("Wares"));


Follow ups