1 #ifndef _ResearchQueue_h_
2 #define _ResearchQueue_h_
3 
4 #include "../util/Export.h"
5 
6 #include <deque>
7 #include <map>
8 #include <string>
9 #include <vector>
10 #include <boost/serialization/access.hpp>
11 #include <boost/signals2/signal.hpp>
12 
13 FO_COMMON_API extern const int ALL_EMPIRES;
14 
15 struct FO_COMMON_API ResearchQueue {
16     /** The type of a single element in the research queue. */
17     struct Element {
18         explicit Element() = default;
19         Element(const std::string& name_, int empire_id_, float spending_,
20                 int turns_left_, bool paused_ = false) :
nameResearchQueue::Element21             name(name_),
22             empire_id(empire_id_),
23             allocated_rp(spending_),
24             turns_left(turns_left_),
25             paused(paused_)
26         {}
27         std::string Dump() const;
28 
29         std::string name;
30         int         empire_id = ALL_EMPIRES;
31         float       allocated_rp = 0.0f;
32         int         turns_left = 0;
33         bool        paused = false;
34     private:
35         friend class boost::serialization::access;
36         template <typename Archive>
37         void serialize(Archive& ar, const unsigned int version);
38     };
39 
40     typedef std::deque<Element> QueueType;
41 
42     /** The ResearchQueue iterator type.  Dereference yields an Element. */
43     typedef QueueType::iterator iterator;
44     /** The const ResearchQueue iterator type.  Dereference yields an Element. */
45     typedef QueueType::const_iterator const_iterator;
46 
47     /** \name Structors */ //@{
ResearchQueueResearchQueue48     ResearchQueue(int empire_id) :
49         m_empire_id(empire_id)
50     {}
51     //@}
52 
53     /** \name Accessors */ //@{
54     bool                        InQueue(const std::string& tech_name) const;///< Returns true iff \a tech is in this queue.
55     bool                        Paused(const std::string& tech_name) const; ///< Returns true iff \a tech is in this queue and paused.
56     bool                        Paused(int idx) const;                      ///< Returns true iff there are at least \a idx - 1 items in the queue and item with index \a idx is paused
57     int                         ProjectsInProgress() const;                 ///< Returns the number of research projects currently (perhaps partially) funded.
58     float                       TotalRPsSpent() const;                      ///< Returns the number of RPs currently spent on the projects in this queue.
EmpireIDResearchQueue59     int                         EmpireID() const { return m_empire_id; }
60     std::vector<std::string>    AllEnqueuedProjects() const;
61     std::string                 Dump() const;
62 
63     // STL container-like interface
64     bool            empty() const;
65     unsigned int    size() const;
66     const_iterator  begin() const;
67     const_iterator  end() const;
68     const_iterator  find(const std::string& tech_name) const;
69     const Element&  operator[](int i) const;
70     //@}
71 
72     /** \name Mutators */ //@{
73     /** Recalculates the RPs spent on and number of turns left for each project
74       * in the queue.  Also determines the number of projects in prgress, and
75       * the total number of RPs spent on the projects in the queue.  \note A
76       * precondition of this function that \a RPs must be greater than some
77       * epsilon > 0; see the implementation for the actual value used for
78       * epsilon. */
79     void            Update(float RPs, const std::map<std::string, float>& research_progress);
80 
81     // STL container-like interface
82     void            push_back(const std::string& tech_name, bool paused = false);
83     void            insert(iterator it, const std::string& tech_name, bool paused = false);
84     void            erase(iterator it);
85 
86     iterator        begin();
87     iterator        end();
88     iterator        find(const std::string& tech_name);
89 
90     void            clear();
91 
92     mutable boost::signals2::signal<void ()> ResearchQueueChangedSignal;
93     //@}
94 
95 private:
96     QueueType   m_queue;
97     int         m_projects_in_progress = 0;
98     float       m_total_RPs_spent = 0.0f;
99     int         m_empire_id = ALL_EMPIRES;
100 
101     friend class boost::serialization::access;
102     template <typename Archive>
103     void serialize(Archive& ar, const unsigned int version);
104 };
105 
106 #endif // _ResearchQueue_h_
107