diff options
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/util/md32_common.h | 2 | ||||
-rw-r--r-- | src/util/metricsbackend.cpp | 140 | ||||
-rw-r--r-- | src/util/metricsbackend.h | 140 | ||||
-rw-r--r-- | src/util/numeric.h | 10 | ||||
-rw-r--r-- | src/util/serialize.cpp | 17 | ||||
-rw-r--r-- | src/util/serialize.h | 4 | ||||
-rw-r--r-- | src/util/string.cpp | 49 | ||||
-rw-r--r-- | src/util/string.h | 4 |
9 files changed, 346 insertions, 21 deletions
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 199d3aeaa..cd2e468d1 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -5,6 +5,7 @@ set(UTIL_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/directiontables.cpp ${CMAKE_CURRENT_SOURCE_DIR}/enriched_string.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ieee_float.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/metricsbackend.cpp ${CMAKE_CURRENT_SOURCE_DIR}/numeric.cpp ${CMAKE_CURRENT_SOURCE_DIR}/pointedthing.cpp ${CMAKE_CURRENT_SOURCE_DIR}/quicktune.cpp diff --git a/src/util/md32_common.h b/src/util/md32_common.h index 085d1d7a5..a4c2099c9 100644 --- a/src/util/md32_common.h +++ b/src/util/md32_common.h @@ -109,6 +109,8 @@ * <appro@fy.chalmers.se> */ +#pragma once + #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) # error "DATA_ORDER must be defined!" #endif diff --git a/src/util/metricsbackend.cpp b/src/util/metricsbackend.cpp new file mode 100644 index 000000000..4454557a3 --- /dev/null +++ b/src/util/metricsbackend.cpp @@ -0,0 +1,140 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "metricsbackend.h" +#if USE_PROMETHEUS +#include <prometheus/exposer.h> +#include <prometheus/registry.h> +#include <prometheus/counter.h> +#include <prometheus/gauge.h> +#include "log.h" +#include "settings.h" +#endif + +MetricCounterPtr MetricsBackend::addCounter( + const std::string &name, const std::string &help_str) +{ + return std::make_shared<SimpleMetricCounter>(name, help_str); +} + +MetricGaugePtr MetricsBackend::addGauge( + const std::string &name, const std::string &help_str) +{ + return std::make_shared<SimpleMetricGauge>(name, help_str); +} + +#if USE_PROMETHEUS + +class PrometheusMetricCounter : public MetricCounter +{ +public: + PrometheusMetricCounter() = delete; + + PrometheusMetricCounter(const std::string &name, const std::string &help_str, + std::shared_ptr<prometheus::Registry> registry) : + MetricCounter(), + m_family(prometheus::BuildCounter() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_counter(m_family.Add({})) + { + } + + virtual ~PrometheusMetricCounter() {} + + virtual void increment(double number) { m_counter.Increment(number); } + virtual double get() const { return m_counter.Value(); } + +private: + prometheus::Family<prometheus::Counter> &m_family; + prometheus::Counter &m_counter; +}; + +class PrometheusMetricGauge : public MetricGauge +{ +public: + PrometheusMetricGauge() = delete; + + PrometheusMetricGauge(const std::string &name, const std::string &help_str, + std::shared_ptr<prometheus::Registry> registry) : + MetricGauge(), + m_family(prometheus::BuildGauge() + .Name(name) + .Help(help_str) + .Register(*registry)), + m_gauge(m_family.Add({})) + { + } + + virtual ~PrometheusMetricGauge() {} + + virtual void increment(double number) { m_gauge.Increment(number); } + virtual void decrement(double number) { m_gauge.Decrement(number); } + virtual void set(double number) { m_gauge.Set(number); } + virtual double get() const { return m_gauge.Value(); } + +private: + prometheus::Family<prometheus::Gauge> &m_family; + prometheus::Gauge &m_gauge; +}; + +class PrometheusMetricsBackend : public MetricsBackend +{ +public: + PrometheusMetricsBackend(const std::string &addr) : + MetricsBackend(), m_exposer(std::unique_ptr<prometheus::Exposer>( + new prometheus::Exposer(addr))), + m_registry(std::make_shared<prometheus::Registry>()) + { + m_exposer->RegisterCollectable(m_registry); + } + + virtual ~PrometheusMetricsBackend() {} + + virtual MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str); + virtual MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str); + +private: + std::unique_ptr<prometheus::Exposer> m_exposer; + std::shared_ptr<prometheus::Registry> m_registry; +}; + +MetricCounterPtr PrometheusMetricsBackend::addCounter( + const std::string &name, const std::string &help_str) +{ + return std::make_shared<PrometheusMetricCounter>(name, help_str, m_registry); +} + +MetricGaugePtr PrometheusMetricsBackend::addGauge( + const std::string &name, const std::string &help_str) +{ + return std::make_shared<PrometheusMetricGauge>(name, help_str, m_registry); +} + +MetricsBackend *createPrometheusMetricsBackend() +{ + std::string addr; + g_settings->getNoEx("prometheus_listener_address", addr); + return new PrometheusMetricsBackend(addr); +} + +#endif diff --git a/src/util/metricsbackend.h b/src/util/metricsbackend.h new file mode 100644 index 000000000..c37306392 --- /dev/null +++ b/src/util/metricsbackend.h @@ -0,0 +1,140 @@ +/* +Minetest +Copyright (C) 2013-2020 Minetest core developers team + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#pragma once +#include <memory> +#include "config.h" +#include "util/thread.h" + +class MetricCounter +{ +public: + MetricCounter() = default; + + virtual ~MetricCounter() {} + + virtual void increment(double number = 1.0) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr<MetricCounter> MetricCounterPtr; + +class SimpleMetricCounter : public MetricCounter +{ +public: + SimpleMetricCounter() = delete; + + virtual ~SimpleMetricCounter() {} + + SimpleMetricCounter(const std::string &name, const std::string &help_str) : + MetricCounter(), m_name(name), m_help_str(help_str), + m_counter(0.0) + { + } + + virtual void increment(double number) + { + MutexAutoLock lock(m_mutex); + m_counter += number; + } + virtual double get() const + { + MutexAutoLock lock(m_mutex); + return m_counter; + } + +private: + std::string m_name; + std::string m_help_str; + + mutable std::mutex m_mutex; + double m_counter; +}; + +class MetricGauge +{ +public: + MetricGauge() = default; + virtual ~MetricGauge() {} + + virtual void increment(double number = 1.0) = 0; + virtual void decrement(double number = 1.0) = 0; + virtual void set(double number) = 0; + virtual double get() const = 0; +}; + +typedef std::shared_ptr<MetricGauge> MetricGaugePtr; + +class SimpleMetricGauge : public MetricGauge +{ +public: + SimpleMetricGauge() = delete; + + SimpleMetricGauge(const std::string &name, const std::string &help_str) : + MetricGauge(), m_name(name), m_help_str(help_str), m_gauge(0.0) + { + } + + virtual ~SimpleMetricGauge() {} + + virtual void increment(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge += number; + } + virtual void decrement(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge -= number; + } + virtual void set(double number) + { + MutexAutoLock lock(m_mutex); + m_gauge = number; + } + virtual double get() const + { + MutexAutoLock lock(m_mutex); + return m_gauge; + } + +private: + std::string m_name; + std::string m_help_str; + + mutable std::mutex m_mutex; + double m_gauge; +}; + +class MetricsBackend +{ +public: + MetricsBackend() = default; + + virtual ~MetricsBackend() {} + + virtual MetricCounterPtr addCounter( + const std::string &name, const std::string &help_str); + virtual MetricGaugePtr addGauge( + const std::string &name, const std::string &help_str); +}; + +#if USE_PROMETHEUS +MetricsBackend *createPrometheusMetricsBackend(); +#endif diff --git a/src/util/numeric.h b/src/util/numeric.h index 6f82a18c1..864ab7543 100644 --- a/src/util/numeric.h +++ b/src/util/numeric.h @@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irr_v2d.h" #include "irr_v3d.h" #include "irr_aabb3d.h" +#include "SColor.h" #include <matrix4.h> #define rangelim(d, min, max) ((d) < (min) ? (min) : ((d) > (max) ? (max) : (d))) @@ -432,3 +433,12 @@ inline v3f getPitchYawRoll(const core::matrix4 &m) { return getPitchYawRollRad(m) * core::RADTODEG64; } + +// Muliply the RGB value of a color linearly, and clamp to black/white +inline irr::video::SColor multiplyColorValue(const irr::video::SColor &color, float mod) +{ + return irr::video::SColor(color.getAlpha(), + core::clamp<u32>(color.getRed() * mod, 0, 255), + core::clamp<u32>(color.getGreen() * mod, 0, 255), + core::clamp<u32>(color.getBlue() * mod, 0, 255)); +} diff --git a/src/util/serialize.cpp b/src/util/serialize.cpp index f0e177d57..5b276668d 100644 --- a/src/util/serialize.cpp +++ b/src/util/serialize.cpp @@ -110,6 +110,7 @@ std::string serializeString(const std::string &plain) if (plain.size() > STRING_MAX_LEN) throw SerializationError("String too long for serializeString"); + s.reserve(2 + plain.size()); writeU16((u8 *)&buf[0], plain.size()); s.append(buf, 2); @@ -131,13 +132,11 @@ std::string deSerializeString(std::istream &is) if (s_size == 0) return s; - Buffer<char> buf2(s_size); - is.read(&buf2[0], s_size); + s.resize(s_size); + is.read(&s[0], s_size); if (is.gcount() != s_size) throw SerializationError("deSerializeString: couldn't read all chars"); - s.reserve(s_size); - s.append(&buf2[0], s_size); return s; } @@ -152,6 +151,7 @@ std::string serializeWideString(const std::wstring &plain) if (plain.size() > WIDE_STRING_MAX_LEN) throw SerializationError("String too long for serializeWideString"); + s.reserve(2 + 2 * plain.size()); writeU16((u8 *)buf, plain.size()); s.append(buf, 2); @@ -196,13 +196,14 @@ std::wstring deSerializeWideString(std::istream &is) std::string serializeLongString(const std::string &plain) { + std::string s; char buf[4]; if (plain.size() > LONG_STRING_MAX_LEN) throw SerializationError("String too long for serializeLongString"); + s.reserve(4 + plain.size()); writeU32((u8*)&buf[0], plain.size()); - std::string s; s.append(buf, 4); s.append(plain); return s; @@ -227,13 +228,11 @@ std::string deSerializeLongString(std::istream &is) "string too long: " + itos(s_size) + " bytes"); } - Buffer<char> buf2(s_size); - is.read(&buf2[0], s_size); + s.resize(s_size); + is.read(&s[0], s_size); if ((u32)is.gcount() != s_size) throw SerializationError("deSerializeLongString: couldn't read all chars"); - s.reserve(s_size); - s.append(&buf2[0], s_size); return s; } diff --git a/src/util/serialize.h b/src/util/serialize.h index 8ef0ad1c2..a4b5a234a 100644 --- a/src/util/serialize.h +++ b/src/util/serialize.h @@ -52,8 +52,8 @@ with this program; if not, write to the Free Software Foundation, Inc., // not represent the full range, but rather the largest safe range, of values on // all supported architectures. Note: This definition makes assumptions on // platform float-to-int conversion behavior. -#define F1000_MIN ((float)(s32)((-0x7FFFFFFF - 1) / FIXEDPOINT_FACTOR)) -#define F1000_MAX ((float)(s32)((0x7FFFFFFF) / FIXEDPOINT_FACTOR)) +#define F1000_MIN ((float)(s32)((float)(-0x7FFFFFFF - 1) / FIXEDPOINT_FACTOR)) +#define F1000_MAX ((float)(s32)((float)(0x7FFFFFFF) / FIXEDPOINT_FACTOR)) #define STRING_MAX_LEN 0xFFFF #define WIDE_STRING_MAX_LEN 0xFFFF diff --git a/src/util/string.cpp b/src/util/string.cpp index e6c52585d..6e1db798c 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -209,6 +209,9 @@ wchar_t *narrow_to_wide_c(const char *str) } std::wstring narrow_to_wide(const std::string &mbs) { +#ifdef __ANDROID__ + return utf8_to_wide(mbs); +#else size_t wcl = mbs.size(); Buffer<wchar_t> wcs(wcl + 1); size_t len = mbstowcs(*wcs, mbs.c_str(), wcl); @@ -216,11 +219,15 @@ std::wstring narrow_to_wide(const std::string &mbs) { return L"<invalid multibyte string>"; wcs[len] = 0; return *wcs; +#endif } std::string wide_to_narrow(const std::wstring &wcs) { +#ifdef __ANDROID__ + return wide_to_utf8(wcs); +#else size_t mbl = wcs.size() * 4; SharedBuffer<char> mbs(mbl+1); size_t len = wcstombs(*mbs, wcs.c_str(), mbl); @@ -229,6 +236,7 @@ std::string wide_to_narrow(const std::wstring &wcs) mbs[len] = 0; return *mbs; +#endif } @@ -685,10 +693,12 @@ void str_replace(std::string &str, char from, char to) * before filling it again. */ -void translate_all(const std::wstring &s, size_t &i, std::wstring &res); +void translate_all(const std::wstring &s, size_t &i, + Translations *translations, std::wstring &res); -void translate_string(const std::wstring &s, const std::wstring &textdomain, - size_t &i, std::wstring &res) { +void translate_string(const std::wstring &s, Translations *translations, + const std::wstring &textdomain, size_t &i, std::wstring &res) +{ std::wostringstream output; std::vector<std::wstring> args; int arg_number = 1; @@ -742,7 +752,7 @@ void translate_string(const std::wstring &s, const std::wstring &textdomain, if (arg_number >= 10) { errorstream << "Ignoring too many arguments to translation" << std::endl; std::wstring arg; - translate_all(s, i, arg); + translate_all(s, i, translations, arg); args.push_back(arg); continue; } @@ -750,7 +760,7 @@ void translate_string(const std::wstring &s, const std::wstring &textdomain, output << arg_number; ++arg_number; std::wstring arg; - translate_all(s, i, arg); + translate_all(s, i, translations, arg); args.push_back(arg); } else { // This is an escape sequence *inside* the template string to translate itself. @@ -759,8 +769,13 @@ void translate_string(const std::wstring &s, const std::wstring &textdomain, } } + std::wstring toutput; // Translate the template. - std::wstring toutput = g_translations->getTranslation(textdomain, output.str()); + if (translations != nullptr) + toutput = translations->getTranslation( + textdomain, output.str()); + else + toutput = output.str(); // Put back the arguments in the translated template. std::wostringstream result; @@ -794,7 +809,9 @@ void translate_string(const std::wstring &s, const std::wstring &textdomain, res = result.str(); } -void translate_all(const std::wstring &s, size_t &i, std::wstring &res) { +void translate_all(const std::wstring &s, size_t &i, + Translations *translations, std::wstring &res) +{ std::wostringstream output; while (i < s.length()) { // Not an escape sequence: just add the character. @@ -843,7 +860,7 @@ void translate_all(const std::wstring &s, size_t &i, std::wstring &res) { if (parts.size() > 1) textdomain = parts[1]; std::wstring translated; - translate_string(s, textdomain, i, translated); + translate_string(s, translations, textdomain, i, translated); output << translated; } else { // Another escape sequence, such as colors. Preserve it. @@ -854,9 +871,21 @@ void translate_all(const std::wstring &s, size_t &i, std::wstring &res) { res = output.str(); } -std::wstring translate_string(const std::wstring &s) { +// Translate string server side +std::wstring translate_string(const std::wstring &s, Translations *translations) +{ size_t i = 0; std::wstring res; - translate_all(s, i, res); + translate_all(s, i, translations, res); return res; } + +// Translate string client side +std::wstring translate_string(const std::wstring &s) +{ +#ifdef SERVER + return translate_string(s, nullptr); +#else + return translate_string(s, g_client_translations); +#endif +} diff --git a/src/util/string.h b/src/util/string.h index 0d2a6bdb2..185fb55e2 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <cctype> #include <unordered_map> +class Translations; + #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) @@ -650,6 +652,8 @@ std::vector<std::basic_string<T> > split(const std::basic_string<T> &s, T delim) return tokens; } +std::wstring translate_string(const std::wstring &s, Translations *translations); + std::wstring translate_string(const std::wstring &s); inline std::wstring unescape_translate(const std::wstring &s) { |