1 /*
2  * Copyright (C) 2006-2020 by the Widelands Development Team
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  */
19 
20 #ifndef WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H
21 #define WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H
22 
23 #include <memory>
24 
25 #include "economy/request.h"
26 #include "economy/wares_queue.h"
27 #include "logic/map_objects/tribes/bill_of_materials.h"
28 #include "logic/map_objects/tribes/building.h"
29 
30 namespace Widelands {
31 
32 class MarketDescr : public BuildingDescr {
33 public:
34 	MarketDescr(const std::string& init_descname, const LuaTable& t, const Tribes& tribes);
~MarketDescr()35 	~MarketDescr() override {
36 	}
37 
38 	Building& create_object() const override;
39 
carrier()40 	DescriptionIndex carrier() const {
41 		return carrier_;
42 	}
43 
44 private:
45 	DescriptionIndex carrier_;
46 };
47 
48 class Market : public Building {
49 	MO_DESCR(MarketDescr)
50 public:
51 	explicit Market(const MarketDescr& descr);
52 	~Market() override;
53 
54 	void new_trade(int trade_id, const BillOfMaterials& items, int num_batches, Serial other_side);
55 	void cancel_trade(int trade_id);
56 
57 	InputQueue& inputqueue(DescriptionIndex, WareWorker) override;
58 	void cleanup(EditorGameBase&) override;
59 
60 	void try_launching_batch(Game* game);
61 	void traded_ware_arrived(int trade_id, DescriptionIndex ware_index, Game* game);
62 
63 private:
64 	struct TradeOrder {
65 		BillOfMaterials items;
66 		int initial_num_batches;
67 		int num_shipped_batches;
68 		Serial other_side;
69 
70 		int received_traded_wares_in_this_batch;
71 
72 		// The invariant here is that worker.size() + worker_request.get_count()
73 		// == 'num_wares_per_batch()'
74 		std::unique_ptr<Request> worker_request;
75 		std::vector<Worker*> workers;
76 
77 		// The number of individual wares in 'items', i.e. the sum of all '.second's.
78 		int num_wares_per_batch() const;
79 
80 		// True if the 'num_shipped_batches' equals the 'initial_num_batches'
81 		bool fulfilled() const;
82 	};
83 
84 	static void
85 	worker_arrived_callback(Game&, Request&, DescriptionIndex, Worker*, PlayerImmovable&);
86 	static void
87 	ware_arrived_callback(Game& g, InputQueue* q, DescriptionIndex ware, Worker* worker, void* data);
88 
89 	void ensure_wares_queue_exists(int ware_index);
90 	bool is_ready_to_launch_batch(int trade_id);
91 	void launch_batch(int trade_id, Game* game);
92 
93 	std::map<int, TradeOrder> trade_orders_;                  // Key is 'trade_id's.
94 	std::map<int, std::unique_ptr<WaresQueue>> wares_queue_;  // Key is 'ware_index'.
95 
96 	DISALLOW_COPY_AND_ASSIGN(Market);
97 };
98 
99 }  // namespace Widelands
100 
101 #endif  // end of include guard: WL_LOGIC_MAP_OBJECTS_TRIBES_MARKET_H
102