CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Text/I18n.h
Views: 1401
1
#pragma once
2
3
// I18N = I....18..dots.....N = INTERNATIONALIZATION
4
5
// Super simple I18N library.
6
// Just enough to be useful and usable.
7
// Spits out easy-to-edit utf-8 .INI files.
8
9
// As usual, everything is UTF-8. Nothing else allowed.
10
11
#include <map>
12
#include <mutex>
13
#include <string>
14
#include <string_view>
15
#include <vector>
16
#include <memory>
17
18
#include "Common/Common.h"
19
#include "Common/File/Path.h"
20
21
// Reasonably thread safe.
22
23
class I18NRepo;
24
class IniFile;
25
class Section;
26
27
enum class I18NCat : uint8_t {
28
AUDIO = 0,
29
CONTROLS,
30
CWCHEATS,
31
DESKTOPUI,
32
DEVELOPER,
33
DIALOG,
34
ERRORS, // Can't name it ERROR, clashes with many defines.
35
GAME,
36
GRAPHICS,
37
INSTALLZIP,
38
KEYMAPPING,
39
MAINMENU,
40
MAINSETTINGS,
41
MAPPABLECONTROLS,
42
NETWORKING,
43
PAUSE,
44
POSTSHADERS,
45
PSPCREDITS,
46
MEMSTICK,
47
REMOTEISO,
48
REPORTING,
49
SAVEDATA,
50
SCREEN,
51
SEARCH,
52
STORE,
53
SYSINFO,
54
SYSTEM,
55
TEXTURESHADERS,
56
THEMES,
57
UI_ELEMENTS,
58
UPGRADE,
59
VR,
60
ACHIEVEMENTS,
61
PSPSETTINGS,
62
CATEGORY_COUNT,
63
NONE = CATEGORY_COUNT,
64
};
65
66
struct I18NEntry {
67
I18NEntry(std::string_view t) : text(t), readFlag(false) {}
68
I18NEntry() : readFlag(false) {}
69
std::string text;
70
bool readFlag;
71
};
72
73
class I18NCategory {
74
public:
75
I18NCategory() {}
76
explicit I18NCategory(const Section &section);
77
78
// Faster since the string lengths don't need to be recomputed.
79
std::string_view T(std::string_view key, std::string_view def = "");
80
81
// Try to avoid this. Still useful in snprintf.
82
const char *T_cstr(const char *key, const char *def = nullptr);
83
84
std::map<std::string, std::string> Missed() const;
85
86
const std::map<std::string, I18NEntry, std::less<>> &GetMap() { return map_; }
87
void ClearMissed() { missedKeyLog_.clear(); }
88
void Clear();
89
90
private:
91
I18NCategory(I18NRepo *repo, const char *name) {}
92
void SetMap(const std::map<std::string, std::string> &m);
93
94
// std::less<> is needed to be able to look up string_views in a string-keyed map.
95
std::map<std::string, I18NEntry, std::less<>> map_;
96
mutable std::mutex missedKeyLock_;
97
std::map<std::string, std::string> missedKeyLog_;
98
99
// Noone else can create these.
100
friend class I18NRepo;
101
};
102
103
class I18NRepo {
104
public:
105
I18NRepo();
106
bool IniExists(const std::string &languageID) const;
107
bool LoadIni(const std::string &languageID, const Path &overridePath = Path()); // NOT the filename!
108
109
std::string LanguageID();
110
111
std::shared_ptr<I18NCategory> GetCategory(I18NCat category);
112
113
// Translate the string, by looking up "key" in the file, and falling back to either def or key, in that order, if the lookup fails.
114
// def can (and usually is) set to nullptr.
115
std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
116
if (category == I18NCat::NONE)
117
return !def.empty() ? def : key;
118
return cats_[(size_t)category]->T(key, def);
119
}
120
const char *T_cstr(I18NCat category, const char *key, const char *def = nullptr) {
121
if (category == I18NCat::NONE)
122
return def ? def : key;
123
return cats_[(size_t)category]->T_cstr(key, def);
124
}
125
void LogMissingKeys() const;
126
127
private:
128
Path GetIniPath(const std::string &languageID) const;
129
void Clear();
130
131
mutable std::mutex catsLock_;
132
std::shared_ptr<I18NCategory> cats_[(size_t)I18NCat::CATEGORY_COUNT];
133
std::string languageID_;
134
};
135
136
extern I18NRepo g_i18nrepo;
137
138
// These are simply talking to the one global instance of I18NRepo.
139
140
std::shared_ptr<I18NCategory> GetI18NCategory(I18NCat cat);
141
142
inline std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
143
return g_i18nrepo.T(category, key, def);
144
}
145
146
inline const char *T_cstr(I18NCat category, const char *key, const char *def = "") {
147
return g_i18nrepo.T_cstr(category, key, def);
148
}
149
150