From 2daf175650cdda7cc8f820b6cb17b1475496e7ac Mon Sep 17 00:00:00 2001 From: Alexander Gavriliuk Date: Wed, 8 May 2024 23:32:58 +0200 Subject: Add GameControl UI for per device settings --- indra/llcommon/llinitparam.h | 13 +++++++--- indra/llcommon/llsd.cpp | 25 ++++++++++++++++++ indra/llcommon/llsd.h | 15 +++++++++++ indra/llcommon/llstring.cpp | 23 +++++++++++----- indra/llcommon/llstring.h | 62 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 11 deletions(-) (limited to 'indra/llcommon') diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h index c6a8dd737e..170a171502 100644 --- a/indra/llcommon/llinitparam.h +++ b/indra/llcommon/llinitparam.h @@ -1771,8 +1771,13 @@ namespace LLInitParam // implicit conversion operator const container_t&() const { return mValues; } + operator container_t&() { return mValues; } // explicit conversion const container_t& operator()() const { return mValues; } + container_t& operator()() { return mValues; } + // direct Nth item access + const typename NAME_VALUE_LOOKUP::type_value_t& operator()(size_t index) const { return mValues[index]; } + typename NAME_VALUE_LOOKUP::type_value_t& operator()(size_t index) { return mValues[index]; } iterator begin() { return mValues.begin(); } iterator end() { return mValues.end(); } @@ -2102,13 +2107,13 @@ namespace LLInitParam class Multiple : public TypedParam { typedef TypedParam super_t; - typedef Multiple self_t; - typedef typename super_t::container_t container_t; + typedef Multiple self_t; + typedef typename super_t::container_t container_t; typedef typename super_t::value_t value_t; public: - typedef typename super_t::iterator iterator; - typedef typename super_t::const_iterator const_iterator; + typedef typename super_t::iterator iterator; + typedef typename super_t::const_iterator const_iterator; using super_t::operator(); using super_t::operator const container_t&; diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 77fe545c3f..1058ab385b 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -974,6 +974,31 @@ void LLSD::clear() { Impl::assignUndefined(impl); } LLSD::Type LLSD::type() const { return safe(impl).type(); } +bool LLSD::isEmpty() const +{ + switch (type()) + { + case TypeUndefined: + return true; // Always empty + case TypeBinary: + return !asBoolean(); // Empty when default + case TypeInteger: + return !asInteger(); // Empty when default + case TypeReal: + return !asReal(); // Empty when default + case TypeString: + case TypeURI: + return asString().empty(); // Empty natively + case TypeArray: + case TypeMap: + return !size(); // Empty natively + default:; + } + // All other value types (TypeDate) don't have default values so can't be empty + return false; +} + + // Scalar Constructors LLSD::LLSD(Boolean v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(Integer v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index d2b3548831..7fa193e035 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -335,6 +335,20 @@ public: { return c ? (*this)[std::string_view(c)] : *this; } + + template + LLSD(const std::map& map, bool exclude_empty = false) + { + assign(emptyMap()); + for (const std::pair& pair : map) + { + LLSD value(pair.second); + if (!exclude_empty || !value.isEmpty()) + { + insert(pair.first, value); + } + } + } //@} /** @name Array Values */ @@ -420,6 +434,7 @@ public: bool isBinary() const { return type() == TypeBinary; } bool isMap() const { return type() == TypeMap; } bool isArray() const { return type() == TypeArray; } + bool isEmpty() const; //@} /** @name Automatic Cast Protection diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 447fa2d9dd..e38622b43b 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -1144,18 +1144,27 @@ void LLStringOps::setupDayFormat(const std::string& data) } -std::string LLStringOps::getDatetimeCode (std::string key) +std::string LLStringOps::getDatetimeCode(std::string key) { - std::map::iterator iter; + std::map::iterator iter = datetimeToCodes.find(key); + return iter == datetimeToCodes.end() ? LLStringUtil::null : iter->second; +} - iter = datetimeToCodes.find (key); - if (iter != datetimeToCodes.end()) +void LLStringOps::splitString(const std::string& text, char delimiter, + std::function handler) +{ + std::size_t from = 0; + for (std::size_t i = 0; i < text.size(); ++i) { - return iter->second; + if (text[i] == delimiter) + { + handler(text.substr(from, i - from)); + from = i + 1; + } } - else + if (from <= text.size()) { - return std::string(""); + handler(text.substr(from)); } } diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index d65fb16f5b..7d0806b22e 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -214,6 +214,9 @@ public: static std::string getDatetimeCode (std::string key); + static void splitString(const std::string& text, char delimiter, + std::function handler); + // Express a value like 1234567 as "1.23M" static std::string getReadableNumber(F64 num); }; @@ -443,6 +446,65 @@ public: static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); } + // Join non-empty strings from values using value itself and delimiter + template + static std::string join(const C& values, T delimiter = ',') + { + std::string result; + for (const std::string& value : values) + { + if (!value.empty()) + { + if (!result.empty()) + { + result += delimiter; + } + result += value; + } + } + return result; + } + + // Join non-empty strings from values using stringify(value) and delimiter + template + static std::string join(const C& values, std::function stringify, T delimiter = ',') + { + std::string result; + for (const V& value : values) + { + std::string string = stringify(value); + if (!string.empty()) + { + if (!result.empty()) + { + result += delimiter; + } + result += string; + } + } + return result; + } + + // Join non-empty strings from values using stringify(index, value) and delimiter + template + static std::string join(const C& values, std::function stringify, T delimiter = ',') + { + std::string result; + for (size_t i = 0; i < values.size(); ++i) + { + std::string string = stringify(i, values[i]); + if (!string.empty()) + { + if (!result.empty()) + { + result += delimiter; + } + result += string; + } + } + return result; + } + #ifdef _DEBUG LL_COMMON_API static void testHarness(); #endif -- cgit v1.2.3