Symphony Of Empires
world.hpp
Go to the documentation of this file.
1 // Symphony of Empires
2 // Copyright (C) 2021, Symphony of Empires contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (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, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // world.hpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <cstdlib>
28 #include <cstdint>
29 #include <cstddef>
30 #include <cstring>
31 #include <cassert>
32 #include <ctime>
33 #include <algorithm>
34 #include <mutex>
35 #include <string>
36 #include <memory>
37 #include <array>
38 
39 #include <glm/vec2.hpp>
40 
41 #include "eng3d/profiler.hpp"
42 #include "eng3d/string.hpp"
43 #include "eng3d/log.hpp"
44 #include "eng3d/luavm.hpp"
45 
46 #include "nation.hpp"
47 #include "product.hpp"
48 #include "indpobj.hpp"
49 #include "building.hpp"
50 #include "indpobj.hpp"
51 #include "indpobj.hpp"
52 #include "server/lua_api.hpp"
53 #include "server/economy.hpp"
54 #include "province.hpp"
55 #include "unit.hpp"
56 #include "indpobj.hpp"
57 #include "event.hpp"
58 #include "diplomacy.hpp"
59 #include "indpobj.hpp"
60 
61 // Create a new list from a type, with helper functions
62 #define LIST_FOR_TYPE(type, list, list_type)\
63  inline const list_type<type*>& get_list(const type* = nullptr) const {\
64  return list;\
65  };\
66  inline list_type<type*>& get_list(const type* = nullptr) {\
67  return list;\
68  };\
69  list_type<type*> list;
70 
71 #define CONST_LIST_FOR_LOCAL_TYPE(type, list, list_type)\
72  inline const list_type<type>& get_list(const type* = nullptr) const {\
73  return list;\
74  };\
75  inline list_type<type>& get_list(const type* = nullptr) {\
76  return list;\
77  };\
78  inline void insert(type& ptr) {\
79  auto& type_list = this->get_list((type*)nullptr);\
80  std::scoped_lock lock(list_mutex);\
81  ptr.cached_id = type::Id(type_list.size());\
82  Eng3D::Log::debug("world_insert", "Inserting object " #type " with ID=" + std::to_string(static_cast<size_t>(ptr.cached_id)));\
83  type_list.push_back(ptr);\
84  };\
85  list_type<type> list;
86 
87 #define LIST_FOR_LOCAL_TYPE(type, list, list_type)\
88  inline const list_type<type>& get_list(const type* = nullptr) const {\
89  return list;\
90  };\
91  inline list_type<type>& get_list(const type* = nullptr) {\
92  return list;\
93  };\
94  inline void insert(type& ptr) {\
95  auto& type_list = this->get_list((type*)nullptr);\
96  std::scoped_lock lock(list_mutex);\
97  ptr.cached_id = type::Id(type_list.size());\
98  Eng3D::Log::debug("world_insert", "Inserting object " #type " with ID=" + std::to_string(static_cast<size_t>(ptr.cached_id)));\
99  type_list.push_back(ptr);\
100  };\
101  inline void remove(type& ptr) {\
102  size_t cached_id = static_cast<size_t>(this->get_id<type>(ptr));\
103  auto& type_list = this->get_list((type*)nullptr);\
104  std::scoped_lock lock(list_mutex);\
105  cached_id = type_list.size();\
106  Eng3D::Log::debug("world_remove", "Removing object " #type " with ID=" + std::to_string(static_cast<size_t>(cached_id)));\
107  for(size_t i = cached_id + 1; i < type_list.size(); i++)\
108  type_list[i].cached_id = type::Id(static_cast<size_t>(type_list[i].cached_id) - 1);\
109  type_list.erase(type_list.begin() + cached_id);\
110  };\
111  list_type<type> list;
112 
113 // Contains the main world class object, containing all the data relevant for the simulation
114 class World {
115 public:
116  constexpr static unsigned int ticks_per_month = 30;
117 
118  World() = default;
119  World& operator=(const World&) = delete;
120  ~World() = default;
121  static World& get_instance() {
122  extern World g_world;
123  return g_world;
124  }
125  void do_tick();
126  void init_lua();
127  void load_initial();
128  void load_mod();
129  void fire_special_event(const std::string_view event_ref_name, const std::string_view nation_ref_name, const std::string_view other_nation_ref_name);
131 
132  LIST_FOR_LOCAL_TYPE(Commodity, commodities, std::vector)
133  LIST_FOR_LOCAL_TYPE(Language, languages, std::vector)
134  LIST_FOR_LOCAL_TYPE(PopType, pop_types, std::vector)
135  LIST_FOR_LOCAL_TYPE(UnitType, unit_types, std::vector)
136  LIST_FOR_LOCAL_TYPE(BuildingType, building_types, std::vector)
137  LIST_FOR_LOCAL_TYPE(Ideology, ideologies, std::vector)
138  LIST_FOR_LOCAL_TYPE(Religion, religions, std::vector)
139  LIST_FOR_LOCAL_TYPE(Technology, technologies, std::vector)
140  LIST_FOR_LOCAL_TYPE(TerrainType, terrain_types, std::vector)
141  CONST_LIST_FOR_LOCAL_TYPE(Province, provinces, std::vector)
142  CONST_LIST_FOR_LOCAL_TYPE(Nation, nations, std::vector)
143  LIST_FOR_LOCAL_TYPE(Event, events, std::vector)
144  LIST_FOR_LOCAL_TYPE(Treaty, treaties, std::vector)
147  Economy::EconomyState economy_state;
148 
149  template<typename T>
150  inline void insert(T& ptr) {
151  auto& list = this->get_list((T*)nullptr);
152  list_mutex.lock();
153  ptr.cached_id = list.size();
154  assert(ptr.cached_id < static_cast<typename T::Id>(-2));
155  list.push_back((T*)&ptr);
156  list_mutex.unlock();
157  }
158 
159  template<typename T>
160  inline void remove(T& ptr) {
161  size_t cached_id = static_cast<size_t>(this->get_id<T>(ptr));
162  auto& list = this->get_list((T*)nullptr);
163  list_mutex.lock();
164  for(size_t i = cached_id + 1; i < list.size(); i++)
165  list[i].cached_id = T::Id(static_cast<size_t>(list[i].cached_id) - 1);
166  // Remove the element itself
167  list.erase(list.begin() + cached_id);
168  list_mutex.unlock();
169  }
170 
178  template<typename T>
179  inline typename T::Id get_id(const T& obj) const {
180  return obj.cached_id;
181  }
182 
186  inline float get_dist_from_equator(float y) const {
187  return std::fabs(std::fabs(y) - (this->width / 2.0));
188  }
189 
190  std::vector<Nation::Relation> relations;
191 
193  assert(a != b);
194  if(b > a) std::swap(a, b);
195  return relations[a + b * nations.size()];
196  }
197 
199  assert(a != b);
200  if(b > a) std::swap(a, b);
201  return relations[a + b * nations.size()];
202  }
203 
204  int get_year(void) const {
205  return this->time / this->ticks_per_month / 12;
206  }
207 
208  int get_month(void) const {
209  return (this->time / this->ticks_per_month) % 12;
210  }
211 
212  int get_day(void) const {
213  return this->time % this->ticks_per_month;
214  }
215 
217 
218  // 2D Array of tiles
219  std::unique_ptr<ProvinceId[]> tiles;
220  size_t width, height;
221  int time;
222 
224  bool needs_to_sync = false;
225  std::mutex world_mutex;
226  std::mutex list_mutex;
227  std::mutex inbox_mutex;
228  std::vector<std::pair<Decision, NationId>> taken_decisions;
229 };
230 template<>
232  template<bool is_const>
234  template<bool is_serialize>
236  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.width);
237  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.height);
238  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.time);
239  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.commodities);
240  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.unit_types);
241  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.religions);
242  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.languages);
243  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.pop_types);
244  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.terrain_types);
245  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.building_types);
246  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.ideologies);
247  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.technologies);
248  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.nations);
249  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.provinces);
250  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.events);
251  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.treaties);
252  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.unit_manager);
253  Eng3D::Deser::deser_dynamic<is_serialize>(ar, obj.relations);
254 
255  // Savefiles do not contain the tiles
257  bool has_tiles = obj.tiles.get() != nullptr;
258  Eng3D::Deser::deser_dynamic<is_serialize>(ar, has_tiles);
259  if(has_tiles) {
260  if constexpr(is_serialize) {
261  // Serialize all tiles
262  ar.expand(obj.width * obj.height * sizeof(ProvinceId));
263  ar.copy_from(obj.tiles.get(), obj.width * obj.height * sizeof(ProvinceId));
264  } else {
265  // In order to avoid post-deserialization relational patcher, we will simply allocate everything with "empty" objects,
266  // then we will fill those spots as we deserialize
267  obj.tiles.reset(new ProvinceId[obj.width * obj.height]);
268  // Deserialize all tiles
269  ar.copy_to(obj.tiles.get(), obj.width * obj.height * sizeof(ProvinceId));
270  }
271  }
272  }
273 };
274 
275 extern World g_world;
A single province, which is used to simulate economy in a "bulk-tiles" way instead of doing economica...
Definition: province.hpp:48
Definition: world.hpp:114
UnitManager unit_manager
Definition: world.hpp:145
void load_mod()
Definition: world.cpp:590
float get_dist_from_equator(float y) const
Get the dist from the equator in respect to Y.
Definition: world.hpp:186
World()=default
bool needs_to_sync
Used to signal the lua scripts of invalid operations (eg. adding a country midgame)
Definition: world.hpp:224
int get_year(void) const
Definition: world.hpp:204
std::mutex inbox_mutex
Definition: world.hpp:227
~World()=default
int get_month(void) const
Definition: world.hpp:208
std::vector< std::pair< Decision, NationId > > taken_decisions
Definition: world.hpp:228
Nation::Relation & get_relation(NationId a, NationId b)
Definition: world.hpp:192
size_t width
Definition: world.hpp:220
void load_initial()
Definition: world.cpp:419
T::Id get_id(const T &obj) const
Get the id of an object, this is a template for all types except for tiles and locally-stored types (...
Definition: world.hpp:179
Economy::EconomyState economy_state
Definition: world.hpp:147
std::vector< Nation::Relation > relations
Definition: world.hpp:190
void fire_special_event(const std::string_view event_ref_name, const std::string_view nation_ref_name, const std::string_view other_nation_ref_name)
Definition: world.cpp:730
void do_tick()
Definition: world.cpp:753
void init_lua()
Definition: world.cpp:79
void insert(T &ptr)
Definition: world.hpp:150
std::mutex world_mutex
Definition: world.hpp:225
int get_day(void) const
Definition: world.hpp:212
World & operator=(const World &)=delete
Eng3D::Profiler profiler
Definition: world.hpp:130
void remove(T &ptr)
Definition: world.hpp:160
ProvinceManager province_manager
Definition: world.hpp:146
static World & get_instance()
Definition: world.hpp:121
std::mutex list_mutex
Definition: world.hpp:226
std::unique_ptr< ProvinceId[]> tiles
Definition: world.hpp:219
int time
Definition: world.hpp:221
constexpr static unsigned int ticks_per_month
Definition: world.hpp:116
size_t height
Definition: world.hpp:220
Eng3D::LuaVM lua
Definition: world.hpp:216
const Nation::Relation & get_relation(NationId a, NationId b) const
Definition: world.hpp:198
Type for military outposts.
Definition: building.hpp:38
A commodity, mostly serves as a "product type".
Definition: product.hpp:35
Base class that serves as archiver, stores (in memory) the data required for serialization/deserializ...
Definition: serializer.hpp:64
void expand(size_t amount)
Definition: serializer.hpp:72
void copy_from(const void *ptr, size_t size)
Definition: serializer.cpp:94
void copy_to(void *ptr, size_t size)
Definition: serializer.cpp:87
static void deser_dynamic(Eng3D::Deser::Archive &ar, type< is_serialize > &obj)
Definition: world.hpp:235
typename Eng3D::Deser::CondConstType< is_const, World >::type type
Definition: world.hpp:233
A serializer (base class) which can be used to serialize objects and create per-object optimized clas...
Definition: serializer.hpp:111
Definition: event.hpp:54
Diplomatic relations between two nations.
Definition: nation.hpp:62
Defines a type of unit, it can be a tank, garrison, infantry, etc this is moddable via a lua script a...
Definition: unit.hpp:44
World g_world
Definition: world.cpp:59
#define CONST_LIST_FOR_LOCAL_TYPE(type, list, list_type)
Definition: world.hpp:71
#define LIST_FOR_LOCAL_TYPE(type, list, list_type)
Definition: world.hpp:87