1 #include "AppInterface.h"
2 
3 #include "../parse/Parse.h"
4 #include "../Empire/EmpireManager.h"
5 #include "../universe/BuildingType.h"
6 #include "../universe/Encyclopedia.h"
7 #include "../universe/FieldType.h"
8 #include "../universe/Special.h"
9 #include "../universe/Species.h"
10 #include "../universe/ShipDesign.h"
11 #include "../universe/ShipPart.h"
12 #include "../universe/ShipHull.h"
13 #include "../universe/Tech.h"
14 #include "../util/Directories.h"
15 #include "../util/GameRules.h"
16 #include "../util/Pending.h"
17 
18 #include <boost/filesystem.hpp>
19 
20 #include <future>
21 
22 extern template TechManager::TechParseTuple parse::techs<TechManager::TechParseTuple>(const boost::filesystem::path& path);
23 
24 const int INVALID_GAME_TURN = -(2 << 15) + 1;
25 const int BEFORE_FIRST_TURN = -(2 << 14);
26 const int IMPOSSIBLY_LARGE_TURN = 2 << 15;
27 
28 IApp*  IApp::s_app = nullptr;
29 
IApp()30 IApp::IApp() {
31     if (s_app)
32         throw std::runtime_error("Attempted to construct a second instance of Application");
33 
34     s_app = this;
35 }
36 
~IApp()37 IApp::~IApp()
38 { s_app = nullptr; }
39 
GetApp()40 IApp* IApp::GetApp()
41 { return s_app; }
42 
43 
MAX_AI_PLAYERS()44 int IApp::MAX_AI_PLAYERS() {
45     // This is not just a constant to avoid the static initialization
46     // order fiasco, because it is used in more than one compilation
47     // unit during static initialization, albeit a the moment in two
48     // different threads.
49     static const int max_number_AIs = 40;
50     return max_number_AIs;
51 }
52 
StartBackgroundParsing()53 void IApp::StartBackgroundParsing() {
54     namespace fs = boost::filesystem;
55 
56     const auto& rdir = GetResourceDir();
57     if (!fs::exists(rdir) || !fs::is_directory(rdir)) {
58         ErrorLogger() << "Background parse given non-existant resources directory!";
59         return;
60     }
61 
62     if (fs::exists(rdir / "scripting/buildings"))
63         GetBuildingTypeManager().SetBuildingTypes(Pending::StartParsing(parse::buildings, rdir / "scripting/buildings"));
64     else
65         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/buildings").string();
66 
67     if (fs::exists(rdir / "scripting/encyclopedia"))
68         GetEncyclopedia().SetArticles(Pending::StartParsing(parse::encyclopedia_articles, rdir / "scripting/encyclopedia"));
69     else
70         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/encyclopedia").string();
71 
72     if (fs::exists(rdir / "scripting/fields"))
73         GetFieldTypeManager().SetFieldTypes(Pending::StartParsing(parse::fields, rdir / "scripting/fields"));
74     else
75         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/fields").string();
76 
77     if (fs::exists(rdir / "scripting/specials"))
78         GetSpecialsManager().SetSpecialsTypes(Pending::StartParsing(parse::specials, rdir / "scripting/specials"));
79     else
80         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/specials").string();
81 
82     if (fs::exists(rdir / "scripting/species"))
83         GetSpeciesManager().SetSpeciesTypes(Pending::StartParsing(parse::species, rdir / "scripting/species"));
84     else
85         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/species").string();
86 
87     if (fs::exists(rdir / "scripting/ship_parts"))
88         GetShipPartManager().SetShipParts(Pending::StartParsing(parse::ship_parts, rdir / "scripting/ship_parts"));
89     else
90         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/ship_parts").string();
91 
92     if (fs::exists(rdir / "scripting/ship_hulls"))
93         GetShipHullManager().SetShipHulls(Pending::StartParsing(parse::ship_hulls, rdir / "scripting/ship_hulls"));
94     else
95         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/ship_hulls").string();
96 
97     if (fs::exists(rdir / "scripting/ship_designs"))
98         GetPredefinedShipDesignManager().SetShipDesignTypes(Pending::StartParsing(parse::ship_designs, rdir / "scripting/ship_designs"));
99     else
100         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/ship_designs").string();
101 
102     if (fs::exists(rdir / "scripting/monster_designs"))
103         GetPredefinedShipDesignManager().SetMonsterDesignTypes(Pending::StartParsing(parse::ship_designs, rdir / "scripting/monster_designs"));
104     else
105         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/monster_designs").string();
106 
107     if (fs::exists(rdir / "scripting/game_rules.focs.txt"))
108         GetGameRules().Add(Pending::StartParsing(parse::game_rules, rdir / "scripting/game_rules.focs.txt"));
109     else
110         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/game_rules.focs.txt").string();
111 
112     if (fs::exists(rdir / "scripting/techs"))
113         GetTechManager().SetTechs(Pending::StartParsing(parse::techs<TechManager::TechParseTuple>, rdir / "scripting/techs"));
114     else
115         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "scripting/techs").string();
116 
117     if (fs::exists(rdir / "empire_colors.xml"))
118         InitEmpireColors(rdir / "empire_colors.xml");
119     else
120         ErrorLogger() << "Background parse path doesn't exist: " << (rdir / "empire_colors.xml").string();
121 }
122