mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-26 18:44:17 +01:00
Introduce Boost as a submodule + Minor Fixes
Utilize Boost Container's `small_vector` for optimizing allocations, fix certain implicit casting issues and make `ILogger` not output an additional newline in the log when the application supplies one at the end of the log
This commit is contained in:
parent
190fde110f
commit
8cba1edf6d
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -34,3 +34,6 @@
|
|||||||
[submodule "app/libraries/opus"]
|
[submodule "app/libraries/opus"]
|
||||||
path = app/libraries/opus
|
path = app/libraries/opus
|
||||||
url = https://github.com/xiph/opus
|
url = https://github.com/xiph/opus
|
||||||
|
[submodule "app/libraries/boost"]
|
||||||
|
path = app/libraries/boost
|
||||||
|
url = https://github.com/boostorg/boost.git
|
||||||
|
3
.idea/inspectionProfiles/Project_Default.xml
generated
3
.idea/inspectionProfiles/Project_Default.xml
generated
@ -171,7 +171,7 @@
|
|||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="CheckedExceptionClass" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="ClangTidy" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-lambda-function-name,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-reserved-identifier,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err52-cpp,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cert-str34-c,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-headers,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-convert-member-functions-to-static,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof" />
|
<option name="clangTidyChecks" value="-*,bugprone-argument-comment,bugprone-assert-side-effect,bugprone-bad-signal-to-kill-thread,bugprone-branch-clone,bugprone-copy-constructor-init,bugprone-dangling-handle,bugprone-dynamic-static-initializers,bugprone-fold-init-type,bugprone-forward-declaration-namespace,bugprone-forwarding-reference-overload,bugprone-inaccurate-erase,bugprone-incorrect-roundings,bugprone-integer-division,bugprone-lambda-function-name,bugprone-macro-parentheses,bugprone-macro-repeated-side-effects,bugprone-misplaced-operator-in-strlen-in-alloc,bugprone-misplaced-pointer-arithmetic-in-alloc,bugprone-misplaced-widening-cast,bugprone-move-forwarding-reference,bugprone-multiple-statement-macro,bugprone-no-escape,bugprone-not-null-terminated-result,bugprone-parent-virtual-call,bugprone-posix-return,bugprone-reserved-identifier,bugprone-sizeof-container,bugprone-sizeof-expression,bugprone-spuriously-wake-up-functions,bugprone-string-constructor,bugprone-string-integer-assignment,bugprone-string-literal-with-embedded-nul,bugprone-suspicious-enum-usage,bugprone-suspicious-include,bugprone-suspicious-memset-usage,bugprone-suspicious-missing-comma,bugprone-suspicious-semicolon,bugprone-suspicious-string-compare,bugprone-swapped-arguments,bugprone-terminating-continue,bugprone-throw-keyword-missing,bugprone-too-small-loop-variable,bugprone-undefined-memory-manipulation,bugprone-undelegated-constructor,bugprone-unhandled-self-assignment,bugprone-unused-raii,bugprone-unused-return-value,bugprone-use-after-move,bugprone-virtual-near-miss,cert-dcl21-cpp,cert-dcl58-cpp,cert-err34-c,cert-err52-cpp,cert-err58-cpp,cert-err60-cpp,cert-flp30-c,cert-msc50-cpp,cert-msc51-cpp,cert-str34-c,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-pro-type-member-init,cppcoreguidelines-pro-type-static-cast-downcast,cppcoreguidelines-slicing,google-default-arguments,google-explicit-constructor,google-runtime-operator,hicpp-exception-baseclass,hicpp-multiway-paths-covered,misc-misplaced-const,misc-new-delete-overloads,misc-no-recursion,misc-non-copyable-objects,misc-throw-by-value-catch-by-reference,misc-unconventional-assign-operator,misc-uniqueptr-reset-release,modernize-avoid-bind,modernize-concat-nested-namespaces,modernize-deprecated-ios-base-aliases,modernize-loop-convert,modernize-make-shared,modernize-make-unique,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-auto-ptr,modernize-replace-disallow-copy-and-assign-macro,modernize-replace-random-shuffle,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-emplace,modernize-use-equals-default,modernize-use-equals-delete,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,mpi-buffer-deref,mpi-type-mismatch,openmp-use-default-none,performance-faster-string-find,performance-for-range-copy,performance-implicit-conversion-in-loop,performance-inefficient-algorithm,performance-inefficient-string-concatenation,performance-inefficient-vector-operation,performance-move-const-arg,performance-move-constructor-init,performance-no-automatic-move,performance-noexcept-move-constructor,performance-trivially-destructible,performance-type-promotion-in-math-fn,performance-unnecessary-copy-initialization,performance-unnecessary-value-param,portability-simd-intrinsics,readability-avoid-const-params-in-decls,readability-const-return-type,readability-container-size-empty,readability-convert-member-functions-to-static,readability-delete-null-pointer,readability-deleted-default,readability-inconsistent-declaration-parameter-name,readability-misleading-indentation,readability-misplaced-array-index,readability-non-const-parameter,readability-redundant-control-flow,readability-redundant-declaration,readability-redundant-function-ptr-dereference,readability-redundant-smartptr-get,readability-redundant-string-cstr,readability-redundant-string-init,readability-simplify-subscript-expr,readability-static-accessed-through-instance,readability-static-definition-in-anonymous-namespace,readability-string-compare,readability-uniqueptr-delete-release,readability-use-anyofallof" />
|
||||||
</inspection_tool>
|
</inspection_tool>
|
||||||
<inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="ClassComplexity" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
<option name="m_limit" value="80" />
|
<option name="m_limit" value="80" />
|
||||||
@ -1097,7 +1097,6 @@
|
|||||||
<inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnnecessarySuperConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnnecessarySuperQualifier" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnnecessarySuperQualifier" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnnecessaryThis" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnnecessaryThis" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnnecessaryToStringCall" enabled="true" level="WARNING" enabled_by_default="true" />
|
|
||||||
<inspection_tool class="UnnecessaryUnaryMinus" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnnecessaryUnaryMinus" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnnecessaryUnicodeEscape" enabled="true" level="WARNING" enabled_by_default="true" />
|
<inspection_tool class="UnnecessaryUnicodeEscape" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
<inspection_tool class="UnqualifiedInnerClassAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
<inspection_tool class="UnqualifiedInnerClassAccess" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -60,7 +60,7 @@
|
|||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
@ -68,8 +68,12 @@ include_directories(libraries/perfetto/sdk)
|
|||||||
add_library(perfetto STATIC libraries/perfetto/sdk/perfetto.cc)
|
add_library(perfetto STATIC libraries/perfetto/sdk/perfetto.cc)
|
||||||
target_compile_options(perfetto PRIVATE -Wno-everything)
|
target_compile_options(perfetto PRIVATE -Wno-everything)
|
||||||
|
|
||||||
include_directories(${source_DIR}/skyline)
|
# Boost
|
||||||
|
set(Boost_USE_STATIC_LIBS ON)
|
||||||
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
|
add_subdirectory("libraries/boost")
|
||||||
|
|
||||||
|
# Skyline
|
||||||
add_library(skyline SHARED
|
add_library(skyline SHARED
|
||||||
${source_DIR}/emu_jni.cpp
|
${source_DIR}/emu_jni.cpp
|
||||||
${source_DIR}/loader_jni.cpp
|
${source_DIR}/loader_jni.cpp
|
||||||
@ -224,6 +228,7 @@ add_library(skyline SHARED
|
|||||||
${source_DIR}/skyline/services/prepo/IPrepoService.cpp
|
${source_DIR}/skyline/services/prepo/IPrepoService.cpp
|
||||||
${source_DIR}/skyline/services/mmnv/IRequest.cpp
|
${source_DIR}/skyline/services/mmnv/IRequest.cpp
|
||||||
)
|
)
|
||||||
|
target_include_directories(skyline PRIVATE ${source_DIR}/skyline)
|
||||||
# target_precompile_headers(skyline PRIVATE ${source_DIR}/skyline/common.h) # PCH will currently break Intellisense
|
# target_precompile_headers(skyline PRIVATE ${source_DIR}/skyline/common.h) # PCH will currently break Intellisense
|
||||||
target_link_libraries(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus)
|
target_link_libraries(skyline android perfetto fmt lz4_static tzcode oboe vkma mbedcrypto opus Boost::container)
|
||||||
target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field)
|
target_compile_options(skyline PRIVATE -Wall -Wno-unknown-attributes -Wno-c++20-extensions -Wno-c++17-extensions -Wno-c99-designator -Wno-reorder -Wno-missing-braces -Wno-unused-variable -Wno-unused-private-field -Wno-dangling-else)
|
||||||
|
1
app/libraries/boost
Submodule
1
app/libraries/boost
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 4237966924d69ea5c875d5c2072fc0804f15b4b5
|
@ -17,7 +17,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <compare>
|
#include <compare>
|
||||||
@ -27,6 +26,7 @@
|
|||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <frozen/unordered_map.h>
|
#include <frozen/unordered_map.h>
|
||||||
#include <frozen/string.h>
|
#include <frozen/string.h>
|
||||||
|
#include <boost/container/small_vector.hpp>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#define FORCE_INLINE __attribute__((always_inline)) // NOLINT(cppcoreguidelines-macro-usage)
|
#define FORCE_INLINE __attribute__((always_inline)) // NOLINT(cppcoreguidelines-macro-usage)
|
||||||
|
@ -279,7 +279,7 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
if (frameTimestamp) {
|
if (frameTimestamp) {
|
||||||
i64 now{static_cast<i64>(util::GetTimeNs())};
|
i64 now{static_cast<i64>(util::GetTimeNs())};
|
||||||
auto sampleWeight{swapInterval ? constant::NsInSecond / (refreshCycleDuration * swapInterval) : 10}; //!< The weight of each sample in calculating the average, we arbitrarily average 10 samples for unlocked FPS
|
i64 sampleWeight{static_cast<i64>(swapInterval ? constant::NsInSecond / (refreshCycleDuration * swapInterval) : 10)}; //!< The weight of each sample in calculating the average, we arbitrarily average 10 samples for unlocked FPS
|
||||||
|
|
||||||
auto weightedAverage{[](auto weight, auto previousAverage, auto current) {
|
auto weightedAverage{[](auto weight, auto previousAverage, auto current) {
|
||||||
return (((weight - 1) * previousAverage) + current) / weight;
|
return (((weight - 1) * previousAverage) + current) / weight;
|
||||||
@ -293,13 +293,13 @@ namespace skyline::gpu {
|
|||||||
averageFrametimeDeviationNs = weightedAverage(sampleWeight, averageFrametimeDeviationNs, currentFrametimeDeviation);
|
averageFrametimeDeviationNs = weightedAverage(sampleWeight, averageFrametimeDeviationNs, currentFrametimeDeviation);
|
||||||
AverageFrametimeDeviationMs = static_cast<jfloat>(averageFrametimeDeviationNs) / constant::NsInMillisecond;
|
AverageFrametimeDeviationMs = static_cast<jfloat>(averageFrametimeDeviationNs) / constant::NsInMillisecond;
|
||||||
|
|
||||||
Fps = std::round(static_cast<float>(constant::NsInSecond) / averageFrametimeNs);
|
Fps = static_cast<jint>(std::round(static_cast<float>(constant::NsInSecond) / static_cast<float>(averageFrametimeNs)));
|
||||||
|
|
||||||
TRACE_EVENT_INSTANT("gpu", "Present", presentationTrack, "FrameTimeNs", now - frameTimestamp, "Fps", Fps);
|
TRACE_EVENT_INSTANT("gpu", "Present", presentationTrack, "FrameTimeNs", now - frameTimestamp, "Fps", Fps);
|
||||||
|
|
||||||
frameTimestamp = now;
|
frameTimestamp = now;
|
||||||
} else {
|
} else {
|
||||||
frameTimestamp = util::GetTimeNs();
|
frameTimestamp = static_cast<i64>(util::GetTimeNs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,11 +198,11 @@ namespace skyline {
|
|||||||
PayloadHeader *payload{};
|
PayloadHeader *payload{};
|
||||||
u8 *cmdArg{}; //!< A pointer to the data payload
|
u8 *cmdArg{}; //!< A pointer to the data payload
|
||||||
u64 cmdArgSz{}; //!< The size of the data payload
|
u64 cmdArgSz{}; //!< The size of the data payload
|
||||||
std::vector<KHandle> copyHandles; //!< The handles that should be copied from the server to the client process (The difference is just to match application expectations, there is no real difference b/w copying and moving handles)
|
boost::container::small_vector<KHandle, 2> copyHandles; //!< The handles that should be copied from the server to the client process (The difference is just to match application expectations, there is no real difference b/w copying and moving handles)
|
||||||
std::vector<KHandle> moveHandles; //!< The handles that should be moved from the server to the client process rather than copied
|
boost::container::small_vector<KHandle, 2> moveHandles; //!< The handles that should be moved from the server to the client process rather than copied
|
||||||
std::vector<KHandle> domainObjects;
|
boost::container::small_vector<KHandle, 2> domainObjects;
|
||||||
std::vector<span<u8>> inputBuf;
|
boost::container::small_vector<span<u8>, 3> inputBuf;
|
||||||
std::vector<span<u8>> outputBuf;
|
boost::container::small_vector<span<u8>, 3> outputBuf;
|
||||||
|
|
||||||
IpcRequest(bool isDomain, const DeviceState &state);
|
IpcRequest(bool isDomain, const DeviceState &state);
|
||||||
|
|
||||||
@ -251,9 +251,9 @@ namespace skyline {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Result errorCode{}; //!< The error code to respond with, it's 0 (Success) by default
|
Result errorCode{}; //!< The error code to respond with, it's 0 (Success) by default
|
||||||
std::vector<KHandle> copyHandles;
|
boost::container::small_vector<KHandle, 2> copyHandles;
|
||||||
std::vector<KHandle> moveHandles;
|
boost::container::small_vector<KHandle, 2> moveHandles;
|
||||||
std::vector<KHandle> domainObjects;
|
boost::container::small_vector<KHandle, 2> domainObjects;
|
||||||
|
|
||||||
IpcResponse(const DeviceState &state);
|
IpcResponse(const DeviceState &state);
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ namespace skyline::service::hosbinder {
|
|||||||
|
|
||||||
std::scoped_lock lock(mutex);
|
std::scoped_lock lock(mutex);
|
||||||
// We don't need a loop here since the consumer is blocking and instantly frees all buffers
|
// We don't need a loop here since the consumer is blocking and instantly frees all buffers
|
||||||
// If a valid slot is not found on the first iteration then it would be stuck in an infloop
|
// If a valid slot is not found on the first iteration then it would be stuck in an infinite loop
|
||||||
// As a result of this, we simply warn and return InvalidOperation to the guest
|
// As a result of this, we simply warn and return InvalidOperation to the guest
|
||||||
auto buffer{queue.end()};
|
auto buffer{queue.end()};
|
||||||
size_t dequeuedSlotCount{};
|
size_t dequeuedSlotCount{};
|
||||||
@ -114,7 +114,7 @@ namespace skyline::service::hosbinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buffer != queue.end()) {
|
if (buffer != queue.end()) {
|
||||||
slot = std::distance(queue.begin(), buffer);
|
slot = static_cast<i32>(std::distance(queue.begin(), buffer));
|
||||||
} else if (async) {
|
} else if (async) {
|
||||||
return AndroidStatus::WouldBlock;
|
return AndroidStatus::WouldBlock;
|
||||||
} else if (dequeuedSlotCount == queue.size()) {
|
} else if (dequeuedSlotCount == queue.size()) {
|
||||||
|
@ -112,8 +112,11 @@ namespace skyline::service::lm {
|
|||||||
message << logMessage.thread << ':';
|
message << logMessage.thread << ':';
|
||||||
if (logMessage.time)
|
if (logMessage.time)
|
||||||
message << logMessage.time << "s:";
|
message << logMessage.time << "s:";
|
||||||
if (!logMessage.message.empty())
|
if (!logMessage.message.empty()) {
|
||||||
|
if (logMessage.message.ends_with('\n'))
|
||||||
|
logMessage.message.remove_suffix(1);
|
||||||
message << ' ' << logMessage.message;
|
message << ' ' << logMessage.message;
|
||||||
|
}
|
||||||
if (logMessage.dropCount)
|
if (logMessage.dropCount)
|
||||||
message << " (Dropped Messages: " << logMessage.time << ')';
|
message << " (Dropped Messages: " << logMessage.time << ')';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user