diff --git a/Source/Core/Common/Analytics.cpp b/Source/Core/Common/Analytics.cpp index ab25cecabd..4441e9a7df 100644 --- a/Source/Core/Common/Analytics.cpp +++ b/Source/Core/Common/Analytics.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Common/Analytics.h" #include "Common/CommonTypes.h" @@ -17,7 +18,7 @@ namespace { // Format version number, used as the first byte of every report sent. // Increment for any change to the wire format. -constexpr u8 WIRE_FORMAT_VERSION = 0; +constexpr u8 WIRE_FORMAT_VERSION = 1; // Identifiers for the value types supported by the analytics reporting wire // format. @@ -28,8 +29,17 @@ enum class TypeId : u8 UINT = 2, SINT = 3, FLOAT = 4, + + // Flags which can be combined with other types. + ARRAY = 0x80, }; +TypeId operator|(TypeId l, TypeId r) +{ + using ut = std::underlying_type_t; + return static_cast(static_cast(l) | static_cast(r)); +} + void AppendBool(std::string* out, bool v) { out->push_back(v ? '\xFF' : '\x00'); @@ -112,6 +122,15 @@ void AnalyticsReportBuilder::AppendSerializedValue(std::string* report, float v) AppendBytes(report, reinterpret_cast(&v), sizeof(v), false); } +void AnalyticsReportBuilder::AppendSerializedValueVector(std::string* report, + const std::vector& v) +{ + AppendType(report, TypeId::UINT | TypeId::ARRAY); + AppendVarInt(report, v.size()); + for (u32 x : v) + AppendVarInt(report, x); +} + AnalyticsReporter::AnalyticsReporter() { m_reporter_thread = std::thread(&AnalyticsReporter::ThreadProc, this); diff --git a/Source/Core/Common/Analytics.h b/Source/Core/Common/Analytics.h index 4516334ae5..4930ef4763 100644 --- a/Source/Core/Common/Analytics.h +++ b/Source/Core/Common/Analytics.h @@ -95,6 +95,15 @@ public: return *this; } + template + AnalyticsReportBuilder& AddData(const std::string& key, const std::vector& value) + { + std::lock_guard lk(m_lock); + AppendSerializedValue(&m_report, key); + AppendSerializedValueVector(&m_report, value); + return *this; + } + std::string Get() const { std::lock_guard lk(m_lock); @@ -118,6 +127,8 @@ protected: static void AppendSerializedValue(std::string* report, s32 v); static void AppendSerializedValue(std::string* report, float v); + static void AppendSerializedValueVector(std::string* report, const std::vector& v); + // Should really be a std::shared_mutex, unfortunately that's C++17 only. mutable std::mutex m_lock; std::string m_report;