summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/common_paths.h6
-rw-r--r--src/common/file_util.cpp68
-rw-r--r--src/common/file_util.h27
-rw-r--r--src/common/logging/backend.cpp25
-rw-r--r--src/common/logging/backend.h7
-rw-r--r--src/common/logging/filter.cpp75
-rw-r--r--src/common/logging/filter.h6
-rw-r--r--src/common/param_package.cpp19
-rw-r--r--src/common/param_package.h2
-rw-r--r--src/common/synchronized_wrapper.h85
11 files changed, 119 insertions, 202 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index f49a31612..d5d4f6f82 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -63,7 +63,6 @@ add_library(common STATIC
63 string_util.cpp 63 string_util.cpp
64 string_util.h 64 string_util.h
65 swap.h 65 swap.h
66 synchronized_wrapper.h
67 telemetry.cpp 66 telemetry.cpp
68 telemetry.h 67 telemetry.h
69 thread.cpp 68 thread.cpp
diff --git a/src/common/common_paths.h b/src/common/common_paths.h
index 9bf3efaf2..6799a357a 100644
--- a/src/common/common_paths.h
+++ b/src/common/common_paths.h
@@ -26,7 +26,7 @@
26#define USA_DIR "USA" 26#define USA_DIR "USA"
27#define JAP_DIR "JAP" 27#define JAP_DIR "JAP"
28 28
29// Subdirs in the User dir returned by GetUserPath(D_USER_IDX) 29// Subdirs in the User dir returned by GetUserPath(UserPath::UserDir)
30#define CONFIG_DIR "config" 30#define CONFIG_DIR "config"
31#define CACHE_DIR "cache" 31#define CACHE_DIR "cache"
32#define SDMC_DIR "sdmc" 32#define SDMC_DIR "sdmc"
@@ -35,11 +35,11 @@
35#define LOG_DIR "log" 35#define LOG_DIR "log"
36 36
37// Filenames 37// Filenames
38// Files in the directory returned by GetUserPath(D_CONFIG_IDX) 38// Files in the directory returned by GetUserPath(UserPath::ConfigDir)
39#define EMU_CONFIG "emu.ini" 39#define EMU_CONFIG "emu.ini"
40#define DEBUGGER_CONFIG "debugger.ini" 40#define DEBUGGER_CONFIG "debugger.ini"
41#define LOGGER_CONFIG "logger.ini" 41#define LOGGER_CONFIG "logger.ini"
42// Files in the directory returned by GetUserPath(D_LOGS_IDX) 42// Files in the directory returned by GetUserPath(UserPath::LogDir)
43#define LOG_FILE "yuzu_log.txt" 43#define LOG_FILE "yuzu_log.txt"
44 44
45// Sys files 45// Sys files
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index c882ab39f..1e28f7cbb 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -3,6 +3,7 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <sstream> 5#include <sstream>
6#include <unordered_map>
6#include "common/assert.h" 7#include "common/assert.h"
7#include "common/common_funcs.h" 8#include "common/common_funcs.h"
8#include "common/common_paths.h" 9#include "common/common_paths.h"
@@ -681,67 +682,68 @@ std::string GetSysDirectory() {
681 682
682// Returns a string with a yuzu data dir or file in the user's home 683// Returns a string with a yuzu data dir or file in the user's home
683// directory. To be used in "multi-user" mode (that is, installed). 684// directory. To be used in "multi-user" mode (that is, installed).
684const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) { 685const std::string& GetUserPath(UserPath path, const std::string& new_path) {
685 static std::string paths[NUM_PATH_INDICES]; 686 static std::unordered_map<UserPath, std::string> paths;
687 auto& user_path = paths[UserPath::UserDir];
686 688
687 // Set up all paths and files on the first run 689 // Set up all paths and files on the first run
688 if (paths[D_USER_IDX].empty()) { 690 if (user_path.empty()) {
689#ifdef _WIN32 691#ifdef _WIN32
690 paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; 692 user_path = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
691 if (!FileUtil::IsDirectory(paths[D_USER_IDX])) { 693 if (!FileUtil::IsDirectory(user_path)) {
692 paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP; 694 user_path = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP;
693 } else { 695 } else {
694 LOG_INFO(Common_Filesystem, "Using the local user directory"); 696 LOG_INFO(Common_Filesystem, "Using the local user directory");
695 } 697 }
696 698
697 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 699 paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
698 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; 700 paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
699#else 701#else
700 if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { 702 if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) {
701 paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; 703 user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP;
702 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 704 paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP);
703 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; 705 paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP);
704 } else { 706 } else {
705 std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); 707 std::string data_dir = GetUserDirectory("XDG_DATA_HOME");
706 std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); 708 std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME");
707 std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); 709 std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME");
708 710
709 paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; 711 user_path = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP;
710 paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; 712 paths.emplace(UserPath::ConfigDir, config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP);
711 paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; 713 paths.emplace(UserPath::CacheDir, cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP);
712 } 714 }
713#endif 715#endif
714 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 716 paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP);
715 paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; 717 paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP);
716 paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; 718 paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP);
717 // TODO: Put the logs in a better location for each OS 719 // TODO: Put the logs in a better location for each OS
718 paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOG_DIR DIR_SEP; 720 paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP);
719 } 721 }
720 722
721 if (!newPath.empty()) { 723 if (!new_path.empty()) {
722 if (!FileUtil::IsDirectory(newPath)) { 724 if (!FileUtil::IsDirectory(new_path)) {
723 LOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath); 725 LOG_ERROR(Common_Filesystem, "Invalid path specified {}", new_path);
724 return paths[DirIDX]; 726 return paths[path];
725 } else { 727 } else {
726 paths[DirIDX] = newPath; 728 paths[path] = new_path;
727 } 729 }
728 730
729 switch (DirIDX) { 731 switch (path) {
730 case D_ROOT_IDX: 732 case UserPath::RootDir:
731 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; 733 user_path = paths[UserPath::RootDir] + DIR_SEP;
732 break; 734 break;
733 735
734 case D_USER_IDX: 736 case UserPath::UserDir:
735 paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; 737 user_path = paths[UserPath::RootDir] + DIR_SEP;
736 paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; 738 paths[UserPath::ConfigDir] = user_path + CONFIG_DIR DIR_SEP;
737 paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; 739 paths[UserPath::CacheDir] = user_path + CACHE_DIR DIR_SEP;
738 paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; 740 paths[UserPath::SDMCDir] = user_path + SDMC_DIR DIR_SEP;
739 paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; 741 paths[UserPath::NANDDir] = user_path + NAND_DIR DIR_SEP;
740 break; 742 break;
741 } 743 }
742 } 744 }
743 745
744 return paths[DirIDX]; 746 return paths[path];
745} 747}
746 748
747size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { 749size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) {
diff --git a/src/common/file_util.h b/src/common/file_util.h
index 1f38b1560..ff01bf0ff 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -16,21 +16,20 @@
16#include "common/string_util.h" 16#include "common/string_util.h"
17#endif 17#endif
18 18
19// User directory indices for GetUserPath
20enum {
21 D_USER_IDX,
22 D_ROOT_IDX,
23 D_CONFIG_IDX,
24 D_CACHE_IDX,
25 D_SDMC_IDX,
26 D_NAND_IDX,
27 D_SYSDATA_IDX,
28 D_LOGS_IDX,
29 NUM_PATH_INDICES
30};
31
32namespace FileUtil { 19namespace FileUtil {
33 20
21// User paths for GetUserPath
22enum class UserPath {
23 CacheDir,
24 ConfigDir,
25 LogDir,
26 NANDDir,
27 RootDir,
28 SDMCDir,
29 SysDataDir,
30 UserDir,
31};
32
34// FileSystem tree node/ 33// FileSystem tree node/
35struct FSTEntry { 34struct FSTEntry {
36 bool isDirectory; 35 bool isDirectory;
@@ -123,7 +122,7 @@ bool SetCurrentDir(const std::string& directory);
123 122
124// Returns a pointer to a string with a yuzu data dir in the user's home 123// Returns a pointer to a string with a yuzu data dir in the user's home
125// directory. To be used in "multi-user" mode (that is, installed). 124// directory. To be used in "multi-user" mode (that is, installed).
126const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath = ""); 125const std::string& GetUserPath(UserPath path, const std::string& new_path = "");
127 126
128// Returns the path to where the sys file are 127// Returns the path to where the sys file are
129std::string GetSysDirectory(); 128std::string GetSysDirectory();
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index ed1e93cc2..59b999935 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -3,19 +3,20 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include <array> 6#include <atomic>
7#include <chrono> 7#include <chrono>
8#include <climits> 8#include <climits>
9#include <condition_variable> 9#include <condition_variable>
10#include <memory> 10#include <memory>
11#include <mutex>
11#include <thread> 12#include <thread>
13#include <vector>
12#ifdef _WIN32 14#ifdef _WIN32
13#include <share.h> // For _SH_DENYWR 15#include <share.h> // For _SH_DENYWR
14#else 16#else
15#define _SH_DENYWR 0 17#define _SH_DENYWR 0
16#endif 18#endif
17#include "common/assert.h" 19#include "common/assert.h"
18#include "common/common_funcs.h" // snprintf compatibility define
19#include "common/logging/backend.h" 20#include "common/logging/backend.h"
20#include "common/logging/log.h" 21#include "common/logging/log.h"
21#include "common/logging/text_formatter.h" 22#include "common/logging/text_formatter.h"
@@ -48,11 +49,11 @@ public:
48 backends.push_back(std::move(backend)); 49 backends.push_back(std::move(backend));
49 } 50 }
50 51
51 void RemoveBackend(const std::string& backend_name) { 52 void RemoveBackend(std::string_view backend_name) {
52 std::lock_guard<std::mutex> lock(writing_mutex); 53 std::lock_guard<std::mutex> lock(writing_mutex);
53 auto it = std::remove_if(backends.begin(), backends.end(), [&backend_name](const auto& i) { 54 const auto it =
54 return !strcmp(i->GetName(), backend_name.c_str()); 55 std::remove_if(backends.begin(), backends.end(),
55 }); 56 [&backend_name](const auto& i) { return backend_name == i->GetName(); });
56 backends.erase(it, backends.end()); 57 backends.erase(it, backends.end());
57 } 58 }
58 59
@@ -64,10 +65,10 @@ public:
64 filter = f; 65 filter = f;
65 } 66 }
66 67
67 Backend* GetBackend(const std::string& backend_name) { 68 Backend* GetBackend(std::string_view backend_name) {
68 auto it = std::find_if(backends.begin(), backends.end(), [&backend_name](const auto& i) { 69 const auto it =
69 return !strcmp(i->GetName(), backend_name.c_str()); 70 std::find_if(backends.begin(), backends.end(),
70 }); 71 [&backend_name](const auto& i) { return backend_name == i->GetName(); });
71 if (it == backends.end()) 72 if (it == backends.end())
72 return nullptr; 73 return nullptr;
73 return it->get(); 74 return it->get();
@@ -265,11 +266,11 @@ void AddBackend(std::unique_ptr<Backend> backend) {
265 Impl::Instance().AddBackend(std::move(backend)); 266 Impl::Instance().AddBackend(std::move(backend));
266} 267}
267 268
268void RemoveBackend(const std::string& backend_name) { 269void RemoveBackend(std::string_view backend_name) {
269 Impl::Instance().RemoveBackend(backend_name); 270 Impl::Instance().RemoveBackend(backend_name);
270} 271}
271 272
272Backend* GetBackend(const std::string& backend_name) { 273Backend* GetBackend(std::string_view backend_name) {
273 return Impl::Instance().GetBackend(backend_name); 274 return Impl::Instance().GetBackend(backend_name);
274} 275}
275 276
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index 57cdf6b2d..b3f4b9cef 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -4,10 +4,9 @@
4#pragma once 4#pragma once
5 5
6#include <chrono> 6#include <chrono>
7#include <cstdarg>
8#include <memory> 7#include <memory>
9#include <string> 8#include <string>
10#include <utility> 9#include <string_view>
11#include "common/file_util.h" 10#include "common/file_util.h"
12#include "common/logging/filter.h" 11#include "common/logging/filter.h"
13#include "common/logging/log.h" 12#include "common/logging/log.h"
@@ -106,9 +105,9 @@ private:
106 105
107void AddBackend(std::unique_ptr<Backend> backend); 106void AddBackend(std::unique_ptr<Backend> backend);
108 107
109void RemoveBackend(const std::string& backend_name); 108void RemoveBackend(std::string_view backend_name);
110 109
111Backend* GetBackend(const std::string& backend_name); 110Backend* GetBackend(std::string_view backend_name);
112 111
113/** 112/**
114 * Returns the name of the passed log class as a C-string. Subclasses are separated by periods 113 * Returns the name of the passed log class as a C-string. Subclasses are separated by periods
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index 6ed087beb..2dd331152 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -8,39 +8,9 @@
8#include "common/string_util.h" 8#include "common/string_util.h"
9 9
10namespace Log { 10namespace Log {
11 11namespace {
12Filter::Filter(Level default_level) {
13 ResetAll(default_level);
14}
15
16void Filter::ResetAll(Level level) {
17 class_levels.fill(level);
18}
19
20void Filter::SetClassLevel(Class log_class, Level level) {
21 class_levels[static_cast<size_t>(log_class)] = level;
22}
23
24void Filter::ParseFilterString(const std::string& filter_str) {
25 auto clause_begin = filter_str.cbegin();
26 while (clause_begin != filter_str.cend()) {
27 auto clause_end = std::find(clause_begin, filter_str.cend(), ' ');
28
29 // If clause isn't empty
30 if (clause_end != clause_begin) {
31 ParseFilterRule(clause_begin, clause_end);
32 }
33
34 if (clause_end != filter_str.cend()) {
35 // Skip over the whitespace
36 ++clause_end;
37 }
38 clause_begin = clause_end;
39 }
40}
41
42template <typename It> 12template <typename It>
43static Level GetLevelByName(const It begin, const It end) { 13Level GetLevelByName(const It begin, const It end) {
44 for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { 14 for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) {
45 const char* level_name = GetLevelName(static_cast<Level>(i)); 15 const char* level_name = GetLevelName(static_cast<Level>(i));
46 if (Common::ComparePartialString(begin, end, level_name)) { 16 if (Common::ComparePartialString(begin, end, level_name)) {
@@ -51,7 +21,7 @@ static Level GetLevelByName(const It begin, const It end) {
51} 21}
52 22
53template <typename It> 23template <typename It>
54static Class GetClassByName(const It begin, const It end) { 24Class GetClassByName(const It begin, const It end) {
55 for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) { 25 for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) {
56 const char* level_name = GetLogClassName(static_cast<Class>(i)); 26 const char* level_name = GetLogClassName(static_cast<Class>(i));
57 if (Common::ComparePartialString(begin, end, level_name)) { 27 if (Common::ComparePartialString(begin, end, level_name)) {
@@ -61,8 +31,8 @@ static Class GetClassByName(const It begin, const It end) {
61 return Class::Count; 31 return Class::Count;
62} 32}
63 33
64bool Filter::ParseFilterRule(const std::string::const_iterator begin, 34template <typename Iterator>
65 const std::string::const_iterator end) { 35bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
66 auto level_separator = std::find(begin, end, ':'); 36 auto level_separator = std::find(begin, end, ':');
67 if (level_separator == end) { 37 if (level_separator == end) {
68 LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}", 38 LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}",
@@ -77,7 +47,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
77 } 47 }
78 48
79 if (Common::ComparePartialString(begin, level_separator, "*")) { 49 if (Common::ComparePartialString(begin, level_separator, "*")) {
80 ResetAll(level); 50 instance.ResetAll(level);
81 return true; 51 return true;
82 } 52 }
83 53
@@ -87,9 +57,40 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
87 return false; 57 return false;
88 } 58 }
89 59
90 SetClassLevel(log_class, level); 60 instance.SetClassLevel(log_class, level);
91 return true; 61 return true;
92} 62}
63} // Anonymous namespace
64
65Filter::Filter(Level default_level) {
66 ResetAll(default_level);
67}
68
69void Filter::ResetAll(Level level) {
70 class_levels.fill(level);
71}
72
73void Filter::SetClassLevel(Class log_class, Level level) {
74 class_levels[static_cast<size_t>(log_class)] = level;
75}
76
77void Filter::ParseFilterString(std::string_view filter_view) {
78 auto clause_begin = filter_view.cbegin();
79 while (clause_begin != filter_view.cend()) {
80 auto clause_end = std::find(clause_begin, filter_view.cend(), ' ');
81
82 // If clause isn't empty
83 if (clause_end != clause_begin) {
84 ParseFilterRule(*this, clause_begin, clause_end);
85 }
86
87 if (clause_end != filter_view.cend()) {
88 // Skip over the whitespace
89 ++clause_end;
90 }
91 clause_begin = clause_end;
92 }
93}
93 94
94bool Filter::CheckMessage(Class log_class, Level level) const { 95bool Filter::CheckMessage(Class log_class, Level level) const {
95 return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); 96 return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);
diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h
index 2a4f7c845..d5ffc5a58 100644
--- a/src/common/logging/filter.h
+++ b/src/common/logging/filter.h
@@ -6,7 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <cstddef> 8#include <cstddef>
9#include <string> 9#include <string_view>
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11 11
12namespace Log { 12namespace Log {
@@ -40,9 +40,7 @@ public:
40 * - `Service:Info` -- Sets the level of Service to Info. 40 * - `Service:Info` -- Sets the level of Service to Info.
41 * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. 41 * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace.
42 */ 42 */
43 void ParseFilterString(const std::string& filter_str); 43 void ParseFilterString(std::string_view filter_view);
44 bool ParseFilterRule(const std::string::const_iterator start,
45 const std::string::const_iterator end);
46 44
47 /// Matches class/level combination against the filter, returning true if it passed. 45 /// Matches class/level combination against the filter, returning true if it passed.
48 bool CheckMessage(Class log_class, Level level) const; 46 bool CheckMessage(Class log_class, Level level) const;
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp
index e0df430ab..9526ca0c6 100644
--- a/src/common/param_package.cpp
+++ b/src/common/param_package.cpp
@@ -3,7 +3,9 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <array> 5#include <array>
6#include <utility>
6#include <vector> 7#include <vector>
8
7#include "common/logging/log.h" 9#include "common/logging/log.h"
8#include "common/param_package.h" 10#include "common/param_package.h"
9#include "common/string_util.h" 11#include "common/string_util.h"
@@ -12,10 +14,11 @@ namespace Common {
12 14
13constexpr char KEY_VALUE_SEPARATOR = ':'; 15constexpr char KEY_VALUE_SEPARATOR = ':';
14constexpr char PARAM_SEPARATOR = ','; 16constexpr char PARAM_SEPARATOR = ',';
17
15constexpr char ESCAPE_CHARACTER = '$'; 18constexpr char ESCAPE_CHARACTER = '$';
16const std::string KEY_VALUE_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '0'}; 19constexpr char KEY_VALUE_SEPARATOR_ESCAPE[] = "$0";
17const std::string PARAM_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '1'}; 20constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1";
18const std::string ESCAPE_CHARACTER_ESCAPE{ESCAPE_CHARACTER, '2'}; 21constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2";
19 22
20ParamPackage::ParamPackage(const std::string& serialized) { 23ParamPackage::ParamPackage(const std::string& serialized) {
21 std::vector<std::string> pairs; 24 std::vector<std::string> pairs;
@@ -35,7 +38,7 @@ ParamPackage::ParamPackage(const std::string& serialized) {
35 part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER}); 38 part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER});
36 } 39 }
37 40
38 Set(key_value[0], key_value[1]); 41 Set(key_value[0], std::move(key_value[1]));
39 } 42 }
40} 43}
41 44
@@ -101,16 +104,16 @@ float ParamPackage::Get(const std::string& key, float default_value) const {
101 } 104 }
102} 105}
103 106
104void ParamPackage::Set(const std::string& key, const std::string& value) { 107void ParamPackage::Set(const std::string& key, std::string value) {
105 data[key] = value; 108 data.insert_or_assign(key, std::move(value));
106} 109}
107 110
108void ParamPackage::Set(const std::string& key, int value) { 111void ParamPackage::Set(const std::string& key, int value) {
109 data[key] = std::to_string(value); 112 data.insert_or_assign(key, std::to_string(value));
110} 113}
111 114
112void ParamPackage::Set(const std::string& key, float value) { 115void ParamPackage::Set(const std::string& key, float value) {
113 data[key] = std::to_string(value); 116 data.insert_or_assign(key, std::to_string(value));
114} 117}
115 118
116bool ParamPackage::Has(const std::string& key) const { 119bool ParamPackage::Has(const std::string& key) const {
diff --git a/src/common/param_package.h b/src/common/param_package.h
index c4c11b221..7842cd4ef 100644
--- a/src/common/param_package.h
+++ b/src/common/param_package.h
@@ -28,7 +28,7 @@ public:
28 std::string Get(const std::string& key, const std::string& default_value) const; 28 std::string Get(const std::string& key, const std::string& default_value) const;
29 int Get(const std::string& key, int default_value) const; 29 int Get(const std::string& key, int default_value) const;
30 float Get(const std::string& key, float default_value) const; 30 float Get(const std::string& key, float default_value) const;
31 void Set(const std::string& key, const std::string& value); 31 void Set(const std::string& key, std::string value);
32 void Set(const std::string& key, int value); 32 void Set(const std::string& key, int value);
33 void Set(const std::string& key, float value); 33 void Set(const std::string& key, float value);
34 bool Has(const std::string& key) const; 34 bool Has(const std::string& key) const;
diff --git a/src/common/synchronized_wrapper.h b/src/common/synchronized_wrapper.h
deleted file mode 100644
index 4a1984c46..000000000
--- a/src/common/synchronized_wrapper.h
+++ /dev/null
@@ -1,85 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <algorithm>
8#include <mutex>
9
10namespace Common {
11
12template <typename T>
13class SynchronizedWrapper;
14
15/**
16 * Synchronized reference, that keeps a SynchronizedWrapper's mutex locked during its lifetime. This
17 * greatly reduces the chance that someone will access the wrapped resource without locking the
18 * mutex.
19 */
20template <typename T>
21class SynchronizedRef {
22public:
23 SynchronizedRef(SynchronizedWrapper<T>& wrapper) : wrapper(&wrapper) {
24 wrapper.mutex.lock();
25 }
26
27 SynchronizedRef(SynchronizedRef&) = delete;
28 SynchronizedRef(SynchronizedRef&& o) : wrapper(o.wrapper) {
29 o.wrapper = nullptr;
30 }
31
32 ~SynchronizedRef() {
33 if (wrapper)
34 wrapper->mutex.unlock();
35 }
36
37 SynchronizedRef& operator=(SynchronizedRef&) = delete;
38 SynchronizedRef& operator=(SynchronizedRef&& o) {
39 std::swap(wrapper, o.wrapper);
40 return *this;
41 }
42
43 T& operator*() {
44 return wrapper->data;
45 }
46 const T& operator*() const {
47 return wrapper->data;
48 }
49
50 T* operator->() {
51 return &wrapper->data;
52 }
53 const T* operator->() const {
54 return &wrapper->data;
55 }
56
57private:
58 SynchronizedWrapper<T>* wrapper;
59};
60
61/**
62 * Wraps an object, only allowing access to it via a locking reference wrapper. Good to ensure no
63 * one forgets to lock a mutex before acessing an object. To access the wrapped object construct a
64 * SyncronizedRef on this wrapper. Inspired by Rust's Mutex type
65 * (http://doc.rust-lang.org/std/sync/struct.Mutex.html).
66 */
67template <typename T>
68class SynchronizedWrapper {
69public:
70 template <typename... Args>
71 SynchronizedWrapper(Args&&... args) : data(std::forward<Args>(args)...) {}
72
73 SynchronizedRef<T> Lock() {
74 return {*this};
75 }
76
77private:
78 template <typename U>
79 friend class SynchronizedRef;
80
81 std::mutex mutex;
82 T data;
83};
84
85} // namespace Common