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