Skip to content

Commit

Permalink
Merge pull request #5605 from Web-eWorks/lang-string-view
Browse files Browse the repository at this point in the history
Use std::string_view for C++ Lang handling
  • Loading branch information
Webster Sheets authored Aug 25, 2023
2 parents 6a904b6 + b98937d commit 1599de9
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 29 deletions.
39 changes: 21 additions & 18 deletions src/Lang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,27 @@ namespace Lang {
return true;
}

const std::string &Resource::Get(const std::string &token) const
static const std::string _empty = "";
const std::string &Resource::Get(std::string_view token) const
{
std::map<std::string, std::string>::const_iterator i = m_strings.find(token);
if (i == m_strings.end()) {
static const std::string empty;
return empty;
return _empty;
}
return (*i).second;
}

std::vector<std::string> Resource::GetAvailableLanguages(const std::string &resourceName)
std::vector<std::string> Resource::GetAvailableLanguages(std::string_view resourceName)
{
std::vector<std::string> languages;

for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, "lang/" + resourceName); !files.Finished(); files.Next()) {
std::string searchPath = "lang/";
searchPath.append(resourceName);

for (FileSystem::FileEnumerator files(FileSystem::gameDataFiles, searchPath); !files.Finished(); files.Next()) {
assert(files.Current().IsFile());
const std::string &path = files.Current().GetPath();

if (ends_with_ci(path, ".json")) {
const std::string name = files.Current().GetName();
languages.push_back(name.substr(0, name.size() - 5));
Expand Down Expand Up @@ -175,21 +179,21 @@ namespace Lang {

for (token_map::iterator i = s_token_map.begin(); i != s_token_map.end(); ++i) {
const std::string &token = i->first;
std::string text = res.Get(token);
std::string_view text = res.Get(token);

if (text.empty()) {
Log::Info("{}/{}: token '{}' not found\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str());
Log::Info("{}/{}: token '{}' not found\n", res.GetName(), res.GetLangCode(), token);
text = token;
}

if (text.size() > size_t(STRING_RECORD_SIZE)) {
Log::Info("{}/{}: text for token '{}' is too long and will be truncated\n", res.GetName().c_str(), res.GetLangCode().c_str(), token.c_str());
text.resize(STRING_RECORD_SIZE);
Log::Info("{}/{}: text for token '{}' is too long and will be truncated\n", res.GetName(), res.GetLangCode(), token);
text = text.substr(0, STRING_RECORD_SIZE);
}

// const_cast so we can set the string, see above
char *record = const_cast<char *>(i->second);
copy_string(record, text.c_str(), text.size(), STRING_RECORD_SIZE);
copy_string(record, text.data(), text.size(), STRING_RECORD_SIZE);
}

s_coreResource = res;
Expand All @@ -202,9 +206,9 @@ namespace Lang {

static std::map<std::string, Resource> m_cachedResources;

Resource GetResource(const std::string &name, const std::string &langCode)
Resource &GetResource(std::string_view name, std::string_view langCode)
{
auto key = name + ":" + langCode;
std::string key = fmt::format("{}:{}", name, langCode);

auto i = m_cachedResources.find(key);
if (i != m_cachedResources.end())
Expand All @@ -214,19 +218,18 @@ namespace Lang {
bool loaded = res.Load();
if (!loaded) {
if (langCode != "en") {
Log::Warning("couldn't load language resource {}/{}, trying {}/en\n", name.c_str(), langCode.c_str(), name.c_str());
Log::Warning("couldn't load language resource {}/{}, trying {}/en\n", name, langCode, name);
res = Lang::Resource(name, "en");
loaded = res.Load();
key = name + ":" + "en";
key.replace(key.size() - langCode.size(), langCode.size(), "en");
}
if (!loaded)
Log::Warning("couldn't load language resource {}/en\n", name.c_str());
Log::Warning("couldn't load language resource {}/en\n", name);
}

if (loaded)
m_cachedResources.insert(std::make_pair(key, res));
m_cachedResources.insert(std::make_pair(key, std::move(res)));

return res;
return m_cachedResources.at(key);
}

} // namespace Lang
21 changes: 12 additions & 9 deletions src/Lang.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,41 @@
#include <SDL_stdinc.h>
#include <map>
#include <string>
#include <string_view>
#include <vector>

namespace Lang {

class Resource {
public:
Resource(const std::string &name, const std::string &langCode) :
using StringMap = std::map<std::string, std::string, std::less<>>;

Resource(std::string_view name, std::string_view langCode) :
m_name(name),
m_langCode(langCode),
m_loaded(false) {}

const std::string &GetName() const { return m_name; }
const std::string &GetLangCode() const { return m_langCode; }
std::string_view GetName() const { return m_name; }
std::string_view GetLangCode() const { return m_langCode; }

bool Load();

Uint32 GetNumStrings() const { return static_cast<Uint32>(m_strings.size()); }

const std::string &Get(const std::string &token) const;
const std::string &Get(std::string_view token) const;

static std::vector<std::string> GetAvailableLanguages(const std::string &resourceName);
static std::vector<std::string> GetAvailableLanguages(std::string_view resourceName);

IterationProxy<std::map<std::string, std::string>> GetStrings() { return MakeIterationProxy(m_strings); }
const IterationProxy<const std::map<std::string, std::string>> GetStrings() const { return MakeIterationProxy(m_strings); }
IterationProxy<StringMap> GetStrings() { return MakeIterationProxy(m_strings); }
const IterationProxy<const StringMap> GetStrings() const { return MakeIterationProxy(m_strings); }

private:
std::string m_name;
std::string m_langCode;

bool m_loaded;

std::map<std::string, std::string> m_strings;
StringMap m_strings;
};

// declare all strings
Expand All @@ -50,7 +53,7 @@ namespace Lang {
void MakeCore(Resource &res);
const Resource &GetCore();

Resource GetResource(const std::string &name, const std::string &langCode);
Resource &GetResource(std::string_view name, std::string_view langCode);

} // namespace Lang

Expand Down
4 changes: 4 additions & 0 deletions src/LangStrings.inc.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt

#ifndef DECLARE_STRING
#define DECLARE_STRING(_)
#endif

DECLARE_STRING(LANG_NAME)
DECLARE_STRING(SUGGESTED_RESPONSES)
DECLARE_STRING(SHIP)
Expand Down
2 changes: 1 addition & 1 deletion src/Pi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ void Pi::App::Startup()

ModManager::Init();

Lang::Resource res(Lang::GetResource("core", config->String("Lang")));
Lang::Resource &res(Lang::GetResource("core", config->String("Lang")));
Lang::MakeCore(res);

// FIXME: move these out of the Pi namespace
Expand Down
2 changes: 1 addition & 1 deletion src/lua/LuaLang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static int l_lang_get_resource(lua_State *l)
lua_pop(l, 1);

lua_newtable(l);
Lang::Resource res = Lang::GetResource(resourceName, langCode);
Lang::Resource &res = Lang::GetResource(resourceName, langCode);
if (res.Load()) {
for (auto i : res.GetStrings()) {
const std::string token(i.first);
Expand Down

0 comments on commit 1599de9

Please sign in to comment.