Skip to content

Commit

Permalink
Merge pull request #18858 from hrydgard/translation-string-view
Browse files Browse the repository at this point in the history
Make the i18n T function use std::string_view
  • Loading branch information
hrydgard committed Feb 12, 2024
2 parents 9322b4c + c579176 commit f3635c4
Show file tree
Hide file tree
Showing 135 changed files with 435 additions and 485 deletions.
22 changes: 17 additions & 5 deletions Common/Data/Text/I18n.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,32 @@ void I18NCategory::Clear() {
missedKeyLog_.clear();
}

const char *I18NCategory::T(const char *key, const char *def) {
if (!key) {
return "ERROR";
std::string_view I18NCategory::T(std::string_view key, std::string_view def) {
auto iter = map_.find(key);
if (iter != map_.end()) {
return iter->second.text.c_str();
} else {
std::lock_guard<std::mutex> guard(missedKeyLock_);
std::string missedKey(key);
if (!def.empty())
missedKeyLog_[missedKey] = def;
else
missedKeyLog_[missedKey] = std::string(key);
return !def.empty() ? def : key;
}
}

const char *I18NCategory::T_cstr(const char *key, const char *def) {
auto iter = map_.find(key);
if (iter != map_.end()) {
return iter->second.text.c_str();
} else {
std::lock_guard<std::mutex> guard(missedKeyLock_);
std::string missedKey(key);
if (def)
missedKeyLog_[key] = def;
missedKeyLog_[missedKey] = def;
else
missedKeyLog_[key] = key;
missedKeyLog_[missedKey] = std::string(key);
return def ? def : key;
}
}
Expand Down
27 changes: 19 additions & 8 deletions Common/Data/Text/I18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <map>
#include <mutex>
#include <string>
#include <string_view>
#include <vector>
#include <memory>

Expand Down Expand Up @@ -81,10 +82,11 @@ class I18NCategory {
I18NCategory() {}
explicit I18NCategory(const Section &section);

const char *T(const char *key, const char *def = nullptr);
const char *T(const std::string &key) {
return T(key.c_str(), nullptr);
}
// Faster since the string lengths don't need to be recomputed.
std::string_view T(std::string_view key, std::string_view def = "");

// Try to avoid this. Still useful in snprintf.
const char *T_cstr(const char *key, const char *def = nullptr);

const std::map<std::string, std::string> Missed() const {
std::lock_guard<std::mutex> guard(missedKeyLock_);
Expand All @@ -99,6 +101,7 @@ class I18NCategory {
I18NCategory(I18NRepo *repo, const char *name) {}
void SetMap(const std::map<std::string, std::string> &m);

// std::less<> is needed to be able to look up string_views in a string-keyed map.
std::map<std::string, I18NEntry, std::less<>> map_;
mutable std::mutex missedKeyLock_;
std::map<std::string, std::string> missedKeyLog_;
Expand All @@ -119,12 +122,16 @@ class I18NRepo {

// 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.
// def can (and usually is) set to nullptr.
const char *T(I18NCat category, const char *key, const char *def = nullptr) {
std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
if (category == I18NCat::NONE)
return def ? def : key;
return !def.empty() ? def : key;
return cats_[(size_t)category]->T(key, def);
}

const char *T_cstr(I18NCat category, const char *key, const char *def = nullptr) {
if (category == I18NCat::NONE)
return def ? def : key;
return cats_[(size_t)category]->T_cstr(key, def);
}
void LogMissingKeys() const;

private:
Expand All @@ -142,6 +149,10 @@ extern I18NRepo g_i18nrepo;

std::shared_ptr<I18NCategory> GetI18NCategory(I18NCat cat);

inline const char *T(I18NCat category, const char *key, const char *def = nullptr) {
inline std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
return g_i18nrepo.T(category, key, def);
}

inline const char *T_cstr(I18NCat category, const char *key, const char *def = "") {
return g_i18nrepo.T_cstr(category, key, def);
}
4 changes: 2 additions & 2 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,12 @@ class VKContext : public DrawContext {
}
return list;
}
std::vector<std::string> GetPresentModeList(const char *currentMarkerString) const override {
std::vector<std::string> GetPresentModeList(std::string_view currentMarkerString) const override {
std::vector<std::string> list;
for (auto mode : vulkan_->GetAvailablePresentModes()) {
std::string str = VulkanPresentModeToString(mode);
if (mode == vulkan_->GetPresentMode()) {
str += std::string(" (") + currentMarkerString + ")";
str += std::string(" (") + std::string(currentMarkerString) + ")";
}
list.push_back(str);
}
Expand Down
2 changes: 1 addition & 1 deletion Common/GPU/thin3d.h
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ class DrawContext {
virtual std::vector<std::string> GetFeatureList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetExtensionList(bool device, bool enabledOnly) const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetDeviceList() const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetPresentModeList(const char *currentMarkerString) const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetPresentModeList(std::string_view currentMarkerString) const { return std::vector<std::string>(); }
virtual std::vector<std::string> GetSurfaceFormatList() const { return std::vector<std::string>(); }

// Describes the primary shader language that this implementation prefers.
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/HTTPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ int Client::ReadResponseEntity(net::Buffer *readbuf, const std::vector<std::stri
return 0;
}

HTTPRequest::HTTPRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, const std::string &name)
HTTPRequest::HTTPRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, std::string_view name)
: Request(method, url, name, &cancelled_, progressBarMode), postData_(postData), postMime_(postMime), outfile_(outfile) {
}

Expand Down
2 changes: 1 addition & 1 deletion Common/Net/HTTPClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class Client : public net::Connection {
// Really an asynchronous request.
class HTTPRequest : public Request {
public:
HTTPRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = "");
HTTPRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, std::string_view name = "");
~HTTPRequest();

void Start() override;
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/HTTPNaettRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

namespace http {

HTTPSRequest::HTTPSRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, const std::string &name)
HTTPSRequest::HTTPSRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode, std::string_view name)
: Request(method, url, name, &cancelled_, progressBarMode), method_(method), postData_(postData), postMime_(postMime), outfile_(outfile) {
}

Expand Down
3 changes: 2 additions & 1 deletion Common/Net/HTTPNaettRequest.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <thread>
#include <string_view>

#include "Common/Net/HTTPRequest.h"

Expand All @@ -13,7 +14,7 @@ namespace http {
// Really an asynchronous request.
class HTTPSRequest : public Request {
public:
HTTPSRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, const std::string &name = "");
HTTPSRequest(RequestMethod method, const std::string &url, const std::string &postData, const std::string &postMime, const Path &outfile, ProgressBarMode progressBarMode = ProgressBarMode::DELAYED, std::string_view name = "");
~HTTPSRequest();

void Start() override;
Expand Down
8 changes: 4 additions & 4 deletions Common/Net/HTTPRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

namespace http {

Request::Request(RequestMethod method, const std::string &url, const std::string &name, bool *cancelled, ProgressBarMode mode) : method_(method), url_(url), name_(name), progress_(cancelled), progressBarMode_(mode) {
INFO_LOG(HTTP, "HTTP %s request: %s (%s)", RequestMethodToString(method), url.c_str(), name.c_str());
Request::Request(RequestMethod method, const std::string &url, std::string_view name, bool *cancelled, ProgressBarMode mode) : method_(method), url_(url), name_(name), progress_(cancelled), progressBarMode_(mode) {
INFO_LOG(HTTP, "HTTP %s request: %s (%.*s)", RequestMethodToString(method), url.c_str(), (int)name.size(), name.data());

progress_.callback = [=](int64_t bytes, int64_t contentLength, bool done) {
std::string message;
Expand Down Expand Up @@ -64,7 +64,7 @@ std::shared_ptr<Request> RequestManager::StartDownloadWithCallback(
const Path &outfile,
ProgressBarMode mode,
std::function<void(Request &)> callback,
const std::string &name,
std::string_view name,
const char *acceptMime) {
std::shared_ptr<Request> dl;
if (IsHttpsUrl(url) && System_GetPropertyBool(SYSPROP_SUPPORTS_HTTPS)) {
Expand Down Expand Up @@ -92,7 +92,7 @@ std::shared_ptr<Request> RequestManager::AsyncPostWithCallback(
const std::string &postMime,
ProgressBarMode mode,
std::function<void(Request &)> callback,
const std::string &name) {
std::string_view name) {
std::shared_ptr<Request> dl;
if (IsHttpsUrl(url) && System_GetPropertyBool(SYSPROP_SUPPORTS_HTTPS)) {
#ifndef HTTPS_NOT_AVAILABLE
Expand Down
6 changes: 3 additions & 3 deletions Common/Net/HTTPRequest.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ enum class ProgressBarMode {
// Abstract request.
class Request {
public:
Request(RequestMethod method, const std::string &url, const std::string &name, bool *cancelled, ProgressBarMode mode);
Request(RequestMethod method, const std::string &url, std::string_view name, bool *cancelled, ProgressBarMode mode);
virtual ~Request() {}

void SetAccept(const char *mime) {
Expand Down Expand Up @@ -93,7 +93,7 @@ class RequestManager {
const Path &outfile,
ProgressBarMode mode,
std::function<void(Request &)> callback,
const std::string &name = "",
std::string_view name = "",
const char *acceptMime = nullptr);

std::shared_ptr<Request> AsyncPostWithCallback(
Expand All @@ -102,7 +102,7 @@ class RequestManager {
const std::string &postMime, // Use postMime = "application/x-www-form-urlencoded" for standard form-style posts, such as used by retroachievements. For encoding form data manually we have MultipartFormDataEncoder.
ProgressBarMode mode,
std::function<void(Request &)> callback,
const std::string &name = "");
std::string_view name = "");

// Drops finished downloads from the list.
void Update();
Expand Down
24 changes: 18 additions & 6 deletions Common/StringUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ size_t truncate_cpy(char *dest, size_t destSize, const char *src) {
return len;
}

size_t truncate_cpy(char *dest, size_t destSize, std::string_view src) {
if (src.size() > destSize - 1) {
memcpy(dest, src.data(), destSize - 1);
dest[destSize - 1] = 0;
return destSize - 1;
} else {
memcpy(dest, src.data(), src.size());
dest[src.size()] = 0;
return src.size();
}
}

const char* safe_string(const char* s) {
return s ? s : "(null)";
}
Expand Down Expand Up @@ -376,8 +388,8 @@ std::string ReplaceAll(std::string_view input, std::string_view src, std::string
return result;
}

std::string UnescapeMenuString(const char *input, char *shortcutChar) {
size_t len = strlen(input);
std::string UnescapeMenuString(std::string_view input, char *shortcutChar) {
size_t len = input.length();
std::string output;
output.reserve(len);
bool escaping = false;
Expand All @@ -402,8 +414,8 @@ std::string UnescapeMenuString(const char *input, char *shortcutChar) {
return output;
}

std::string ApplySafeSubstitutions(const char *format, std::string_view string1, std::string_view string2, std::string_view string3, std::string_view string4) {
size_t formatLen = strlen(format);
std::string ApplySafeSubstitutions(std::string_view format, std::string_view string1, std::string_view string2, std::string_view string3, std::string_view string4) {
size_t formatLen = format.length();
std::string output;
output.reserve(formatLen + 20);
for (size_t i = 0; i < formatLen; i++) {
Expand Down Expand Up @@ -433,8 +445,8 @@ std::string ApplySafeSubstitutions(const char *format, std::string_view string1,
return output;
}

std::string ApplySafeSubstitutions(const char *format, int i1, int i2, int i3, int i4) {
size_t formatLen = strlen(format);
std::string ApplySafeSubstitutions(std::string_view format, int i1, int i2, int i3, int i4) {
size_t formatLen = format.length();
std::string output;
output.reserve(formatLen + 20);
for (size_t i = 0; i < formatLen; i++) {
Expand Down
7 changes: 4 additions & 3 deletions Common/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ std::string ReplaceAll(std::string_view input, std::string_view src, std::string

// Takes something like R&eplace and returns Replace, plus writes 'e' to *shortcutChar
// if not nullptr. Useful for Windows menu strings.
std::string UnescapeMenuString(const char *input, char *shortcutChar);
std::string UnescapeMenuString(std::string_view input, char *shortcutChar);

void SkipSpace(const char **ptr);

Expand All @@ -101,6 +101,7 @@ template<size_t Count>
inline size_t truncate_cpy(char(&out)[Count], const char *src) {
return truncate_cpy(out, Count, src);
}
size_t truncate_cpy(char *dest, size_t destSize, std::string_view src);

const char* safe_string(const char* s);

Expand All @@ -125,5 +126,5 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
// Replaces %1, %2, %3 in format with arg1, arg2, arg3.
// Much safer than snprintf and friends.
// For mixes of strings and ints, manually convert the ints to strings.
std::string ApplySafeSubstitutions(const char *format, std::string_view string1, std::string_view string2 = "", std::string_view string3 = "", std::string_view string4 = "");
std::string ApplySafeSubstitutions(const char *format, int i1, int i2 = 0, int i3 = 0, int i4 = 0);
std::string ApplySafeSubstitutions(std::string_view format, std::string_view string1, std::string_view string2 = "", std::string_view string3 = "", std::string_view string4 = "");
std::string ApplySafeSubstitutions(std::string_view format, int i1, int i2 = 0, int i3 = 0, int i4 = 0);
4 changes: 2 additions & 2 deletions Common/System/OSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ void OnScreenDisplay::ShowLeaderboardSubmitted(const std::string &title, const s
g_OSD.Show(OSDType::LEADERBOARD_SUBMITTED, title, value, 3.0f);
}

void OnScreenDisplay::SetProgressBar(const std::string &id, std::string &&message, float minValue, float maxValue, float progress, float delay) {
void OnScreenDisplay::SetProgressBar(std::string_view id, std::string_view message, float minValue, float maxValue, float progress, float delay) {
_dbg_assert_(!my_isnanorinf(progress));
_dbg_assert_(!my_isnanorinf(minValue));
_dbg_assert_(!my_isnanorinf(maxValue));
Expand All @@ -250,7 +250,7 @@ void OnScreenDisplay::SetProgressBar(const std::string &id, std::string &&messag
Entry bar;
bar.id = id;
bar.type = OSDType::PROGRESS_BAR;
bar.text = std::move(message);
bar.text = message;
bar.minValue = minValue;
bar.maxValue = maxValue;
bar.progress = progress;
Expand Down
2 changes: 1 addition & 1 deletion Common/System/OSD.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class OnScreenDisplay {
// Progress bar controls
// Set is both create and update. If you set maxValue <= minValue, you'll create an "indeterminate" progress
// bar that doesn't show a specific amount of progress.
void SetProgressBar(const std::string &id, std::string &&message, float minValue, float maxValue, float progress, float delay_s);
void SetProgressBar(std::string_view id, std::string_view message, float minValue, float maxValue, float progress, float delay_s);
void RemoveProgressBar(const std::string &id, bool success, float delay_s);

// Call every frame to keep the sidebar visible. Otherwise it'll fade out.
Expand Down
11 changes: 7 additions & 4 deletions Common/System/Request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const char *RequestTypeAsString(SystemRequestType type) {
}
}

bool RequestManager::MakeSystemRequest(SystemRequestType type, RequesterToken token, RequestCallback callback, RequestFailedCallback failedCallback, const std::string &param1, const std::string &param2, int param3) {
bool RequestManager::MakeSystemRequest(SystemRequestType type, RequesterToken token, RequestCallback callback, RequestFailedCallback failedCallback, std::string_view param1, std::string_view param2, int param3) {
if (token == NO_REQUESTER_TOKEN) {
_dbg_assert_(!callback);
_dbg_assert_(!failedCallback);
Expand All @@ -49,7 +49,10 @@ bool RequestManager::MakeSystemRequest(SystemRequestType type, RequesterToken to
}

VERBOSE_LOG(SYSTEM, "Making system request %s: id %d", RequestTypeAsString(type), requestId);
if (!System_MakeRequest(type, requestId, param1, param2, param3)) {
std::string p1(param1);
std::string p2(param2);
// TODO: Convert to string_view
if (!System_MakeRequest(type, requestId, p1, p2, param3)) {
if (callback || failedCallback) {
std::lock_guard<std::mutex> guard(callbackMutex_);
callbackMap_.erase(requestId);
Expand Down Expand Up @@ -130,7 +133,7 @@ void RequestManager::Clear() {
callbackMap_.clear();
}

void System_CreateGameShortcut(const Path &path, const std::string &title) {
void System_CreateGameShortcut(const Path &path, std::string_view title) {
g_requestManager.MakeSystemRequest(SystemRequestType::CREATE_GAME_SHORTCUT, NO_REQUESTER_TOKEN, nullptr, nullptr, path.ToString(), title, 0);
}

Expand All @@ -139,6 +142,6 @@ void System_ShowFileInFolder(const Path &path) {
g_requestManager.MakeSystemRequest(SystemRequestType::SHOW_FILE_IN_FOLDER, NO_REQUESTER_TOKEN, nullptr, nullptr, path.ToString(), "", 0);
}

void System_BrowseForFolder(RequesterToken token, const std::string &title, const Path &initialPath, RequestCallback callback, RequestFailedCallback failedCallback) {
void System_BrowseForFolder(RequesterToken token, std::string_view title, const Path &initialPath, RequestCallback callback, RequestFailedCallback failedCallback) {
g_requestManager.MakeSystemRequest(SystemRequestType::BROWSE_FOR_FOLDER, token, callback, failedCallback, title, initialPath.ToCString(), 0);
}
Loading

0 comments on commit f3635c4

Please sign in to comment.