1 #ifndef _ProductionQueue_h_ 2 #define _ProductionQueue_h_ 3 4 #include "../util/Export.h" 5 #include "../universe/Enums.h" 6 7 #include <deque> 8 #include <map> 9 #include <memory> 10 #include <set> 11 #include <string> 12 #include <boost/serialization/access.hpp> 13 #include <boost/signals2/signal.hpp> 14 #include <boost/uuid/uuid.hpp> 15 16 class ResourcePool; 17 FO_COMMON_API extern const int INVALID_DESIGN_ID; 18 FO_COMMON_API extern const int INVALID_OBJECT_ID; 19 FO_COMMON_API extern const int ALL_EMPIRES; 20 21 22 struct FO_COMMON_API ProductionQueue { 23 /** The type that specifies a single production item (BuildType and name string). */ 24 struct FO_COMMON_API ProductionItem { 25 explicit ProductionItem(); 26 explicit ProductionItem(BuildType build_type_); ///< basic ctor for BuildTypes only have one type of item (e.g. stockpile transfer item) 27 ProductionItem(BuildType build_type_, std::string name_); ///< basic ctor for BuildTypes that use std::string to identify specific items (BuildingTypes) 28 ProductionItem(BuildType build_type_, int design_id_); ///< basic ctor for BuildTypes that use int to indentify the design of the item (ShipDesigns) 29 30 bool CostIsProductionLocationInvariant() const; ///< indicates whether production location can change the cost of this item. This is useful for cachcing cost results per-location or once for all locations. 31 32 bool operator<(const ProductionItem& rhs) const; 33 34 bool EnqueueConditionPassedAt(int location_id) const; 35 36 std::map<std::string, std::map<int, float>> CompletionSpecialConsumption(int location_id) const;// for each special name, what object ids have those special capacities reduced by what amount 37 std::map<MeterType, std::map<int, float>> CompletionMeterConsumption(int location_id) const; // for each meter type, what object ids have those meters reduced by what amount 38 39 std::string Dump() const; 40 41 BuildType build_type = INVALID_BUILD_TYPE; 42 // only one of these may be valid, depending on BuildType 43 std::string name; 44 int design_id = INVALID_DESIGN_ID; 45 46 private: 47 friend class boost::serialization::access; 48 template <typename Archive> 49 void serialize(Archive& ar, const unsigned int version); 50 }; 51 52 /** The type of a single element in the production queue. */ 53 struct FO_COMMON_API Element { 54 Element(); 55 56 Element(ProductionItem item_, int empire_id_, 57 boost::uuids::uuid uuid_, 58 int ordered_, int remaining_, int blocksize_, 59 int location_, bool paused_ = false, 60 bool allowed_imperial_stockpile_use_ = true); 61 62 Element(BuildType build_type, std::string name, int empire_id_, 63 boost::uuids::uuid uuid_, 64 int ordered_, int remaining_, int blocksize_, 65 int location_, bool paused_ = false, 66 bool allowed_imperial_stockpile_use_ = true); 67 68 Element(BuildType build_type, int design_id, int empire_id_, 69 boost::uuids::uuid uuid_, 70 int ordered_, int remaining_, int blocksize_, 71 int location_, bool paused_ = false, 72 bool allowed_imperial_stockpile_use_ = true); 73 74 ProductionItem item; 75 int empire_id = ALL_EMPIRES; 76 int ordered = 0; ///< how many of item (blocks) to produce 77 int blocksize = 1; ///< size of block to produce (default=1) 78 int remaining = 0; ///< how many left to produce 79 int location = INVALID_OBJECT_ID;///< the ID of the UniverseObject at which this item is being produced 80 float allocated_pp = 0.0f; ///< PP allocated to this ProductionQueue Element by Empire production update 81 float progress = 0.0f; ///< fraction of this item that is complete. 82 float progress_memory = 0.0f; ///< updated by server turn processing; aides in allowing blocksize changes to be undone in same turn w/o progress loss 83 int blocksize_memory = 1; ///< used along with progress_memory 84 int turns_left_to_next_item = -1; 85 int turns_left_to_completion = -1; 86 int rally_point_id = INVALID_OBJECT_ID; 87 bool paused = false; 88 bool allowed_imperial_stockpile_use = true; 89 boost::uuids::uuid uuid; 90 91 std::string Dump() const; 92 93 private: 94 friend class boost::serialization::access; 95 template <typename Archive> 96 void serialize(Archive& ar, const unsigned int version); 97 }; 98 99 typedef std::deque<Element> QueueType; 100 101 /** The ProductionQueue iterator type. Dereference yields a Element. */ 102 typedef QueueType::iterator iterator; 103 /** The const ProductionQueue iterator type. Dereference yields a Element. */ 104 typedef QueueType::const_iterator const_iterator; 105 106 /** \name Structors */ //@{ 107 ProductionQueue(int empire_id); 108 //@} 109 110 /** \name Accessors */ //@{ 111 int ProjectsInProgress() const; ///< Returns the number of production projects currently (perhaps partially) funded. 112 float TotalPPsSpent() const; ///< Returns the number of PPs currently spent on the projects in this queue. EmpireIDProductionQueue113 int EmpireID() const { return m_empire_id; } 114 115 /** Returns map from sets of object ids that can share resources to amount 116 * of PP available in those groups of objects ; does not include stockpile */ 117 std::map<std::set<int>, float> AvailablePP(const std::shared_ptr<ResourcePool>& industry_pool) const; 118 119 /** Returns map from sets of object ids that can share resources to amount 120 * of PP allocated to production queue elements that have build locations 121 * in systems in the group. */ 122 const std::map<std::set<int>, float>& AllocatedPP() const; 123 124 /** Returns map from sets of object ids that can share resources to amount 125 * of stockpile PP allocated to production queue elements that have build locations 126 * in systems in the group. */ 127 const std::map<std::set<int>, float>& AllocatedStockpilePP() const; 128 129 /** Returns sum of stockpile meters of empire-owned objects. */ 130 float StockpileCapacity() const; 131 132 /** Returns the value expected for the Imperial Stockpile for the next turn, based on the current 133 * ProductionQueue allocations. */ ExpectedNewStockpileAmountProductionQueue134 float ExpectedNewStockpileAmount() const { return m_expected_new_stockpile_amount; } 135 136 /** Returns the PP amount expected to be transferred via stockpiling projects to the Imperial Stockpile 137 * for the next turn, based on the current ProductionQueue allocations. */ ExpectedProjectTransferToStockpileProductionQueue138 float ExpectedProjectTransferToStockpile() const { return m_expected_project_transfer_to_stockpile; } 139 140 /** Returns sets of object ids that have more available than allocated PP */ 141 std::set<std::set<int>> ObjectsWithWastedPP(const std::shared_ptr<ResourcePool>& industry_pool) const; 142 143 // STL container-like interface 144 bool empty() const; 145 unsigned int size() const; 146 const_iterator begin() const; 147 const_iterator end() const; 148 const_iterator find(int i) const; 149 const Element& operator[](int i) const; 150 151 const_iterator find(boost::uuids::uuid uuid) const; 152 int IndexOfUUID(boost::uuids::uuid uuid) const; 153 154 /** \name Mutators */ //@{ 155 /** Recalculates the PPs spent on and number of turns left for each project in the queue. Also 156 * determines the number of projects in progress, and the industry consumed by projects 157 * in each resource-sharing group of systems. Does not actually "spend" the PP; a later call to 158 * empire->CheckProductionProgress() will actually spend PP, remove items from queue and create them 159 * in the universe. */ 160 void Update(); 161 162 // STL container-like interface 163 void push_back(const Element& element); 164 void insert(iterator it, const Element& element); 165 void erase(int i); 166 iterator erase(iterator it); 167 168 iterator begin(); 169 iterator end(); 170 iterator find(int i); 171 Element& operator[](int i); 172 173 void clear(); 174 175 mutable boost::signals2::signal<void ()> ProductionQueueChangedSignal; 176 //@} 177 178 private: 179 QueueType m_queue; 180 int m_projects_in_progress = 0; 181 std::map<std::set<int>, float> m_object_group_allocated_pp; 182 std::map<std::set<int>, float> m_object_group_allocated_stockpile_pp; 183 float m_expected_new_stockpile_amount = 0.0f; 184 float m_expected_project_transfer_to_stockpile = 0.0f; 185 int m_empire_id = ALL_EMPIRES; 186 187 friend class boost::serialization::access; 188 template <typename Archive> 189 void serialize(Archive& ar, const unsigned int version); 190 }; 191 192 #endif // _ProductionQueue_h_ 193