forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.h
183 lines (168 loc) · 6.51 KB
/
init.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#pragma once
#ifndef CATA_SRC_INIT_H
#define CATA_SRC_INIT_H
#include <functional>
#include <iosfwd>
#include <list>
#include <map>
#include <memory>
#include <string> // IWYU pragma: keep
#include <utility>
#include <vector>
#include "memory_fast.h"
class JsonIn;
class JsonObject;
class loading_ui;
struct json_source_location;
/**
* This class is used to load (and unload) the dynamic
* (and moddable) data from json files.
* There exists only one instance of this class, which
* can be accessed with @ref get_instance
*
* Usage is basically this:
* - Let user decide which world to play in.
* - Call @ref unload_data (to unload data from a
* previously loaded world, if any)
* - Call @ref load_data_from_path(...) repeatedly with
* different paths for the core data and all the mods
* of the current world.
* - Call @ref finalize_loaded_data when all mods have been
* loaded.
* - Play.
*
* The object initializes itself upon first usage.
* It also unloads everything when the program ends.
*
*
*
* Porting stuff to json works like this:
* - create a function
* void load_my_object(JsonObject &jo);
* - Add an entry to @ref type_function_map (inside of @ref initialize)
* that calls the new function.
* - Inside that function load the data from the json object.
* You must also provide a reset function and add a call to
* that function in @ref unload_data
* - Optional: create a finalize function and call it from
* @ref finalize_loaded_data
* - Optional: create a function to check the consistency of
* the loaded data and call this function from @ref check_consistency
* - Than create json files.
*/
class DynamicDataLoader
{
public:
using type_string = std::string;
using t_type_function_map =
std::map<type_string, std::function<void( const JsonObject &, const std::string &, const std::string &, const std::string & )>>;
using str_vec = std::vector<std::string>;
/**
* JSON data dependent upon as-yet unparsed definitions
* first: JSON source location, second: source identifier
*/
using deferred_json = std::list<std::pair<json_source_location, std::string>>;
private:
bool finalized = false;
struct cached_streams;
std::unique_ptr<cached_streams> stream_cache;
protected:
/**
* Maps the type string (coming from json) to the
* functor that loads that kind of object from json.
*/
t_type_function_map type_function_map;
void add( const std::string &type, const std::function<void( const JsonObject & )> &f );
void add( const std::string &type,
const std::function<void( const JsonObject &, const std::string & )> &f );
void add( const std::string &type,
const std::function<void( const JsonObject &, const std::string &, const std::string &, const std::string & )>
&f );
/**
* Load all the types from that json data.
* @param jsin Might contain single object,
* or an array of objects. Each object must have a
* "type", that is part of the @ref type_function_map
* @param src String identifier for mod this data comes from
* @param ui Finalization status display.
* @throws std::exception on all kind of errors.
*/
void load_all_from_json( JsonIn &jsin, const std::string &src, loading_ui &ui,
const std::string &base_path, const std::string &full_path );
/**
* Load a single object from a json object.
* @param jo The json object to load the C++-object from.
* @param src String identifier for mod this data comes from
* @throws std::exception on all kind of errors.
*/
void load_object( const JsonObject &jo, const std::string &src,
const std::string &base_path = std::string(),
const std::string &full_path = std::string() );
DynamicDataLoader();
~DynamicDataLoader();
/**
* Initializes @ref type_function_map
*/
void initialize();
/**
* Check the consistency of all the loaded data.
* May print a debugmsg if something seems wrong.
* @param ui Finalization status display.
*/
void check_consistency( loading_ui &ui );
public:
/**
* Returns the single instance of this class.
*/
static DynamicDataLoader &get_instance();
/**
* Load all data from json files located in
* the path (recursive).
* @param path Either a folder (recursively load all
* files with the extension .json), or a file (load only
* that file, don't check extension).
* @param src String identifier for mod this data comes from
* @param ui Finalization status display.
* @throws std::exception on all kind of errors.
*/
/*@{*/
void load_data_from_path( const std::string &path, const std::string &src, loading_ui &ui );
/*@}*/
/**
* Deletes and unloads all the data previously loaded with
* @ref load_data_from_path
*/
void unload_data();
/**
* Called to finalize the loaded data. This should be called
* after all the mods have been loaded.
* It must be called once after loading all data.
* It also checks the consistency of the loaded data with
* @ref check_consistency
* @param ui Finalization status display.
* @throw std::exception if the loaded data is not valid. The
* game should *not* proceed in that case.
*/
/*@{*/
void finalize_loaded_data( loading_ui &ui );
void finalize_loaded_data();
/*@}*/
/**
* Loads and then removes entries from @param data
*/
void load_deferred( deferred_json &data );
/**
* Returns whether the data is finalized and ready to be utilized.
*/
bool is_data_finalized() const {
return finalized;
}
/**
* Get a possibly cached stream for deferred data loading. If the cached
* stream is still in use by outside code, this returns a new stream to
* avoid conflict of stream cursor. The stream cursor is not reset if a
* cached stream is returned.
*/
shared_ptr_fast<std::istream> get_cached_stream( const std::string &path );
};
#endif // CATA_SRC_INIT_H