mirror of
https://github.com/enduro2d/enduro2d.git
synced 2025-12-16 14:08:59 +07:00
Merge branch 'master' into feature/render
This commit is contained in:
@@ -18,7 +18,6 @@ namespace e2d
|
|||||||
error,
|
error,
|
||||||
fatal
|
fatal
|
||||||
};
|
};
|
||||||
|
|
||||||
class sink : private e2d::noncopyable {
|
class sink : private e2d::noncopyable {
|
||||||
public:
|
public:
|
||||||
virtual ~sink() noexcept = default;
|
virtual ~sink() noexcept = default;
|
||||||
@@ -27,37 +26,38 @@ namespace e2d
|
|||||||
using sink_uptr = std::unique_ptr<sink>;
|
using sink_uptr = std::unique_ptr<sink>;
|
||||||
public:
|
public:
|
||||||
debug();
|
debug();
|
||||||
~debug();
|
~debug() noexcept;
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& add_sink(Args&&... args);
|
T& register_sink(Args&&... args);
|
||||||
sink& add_sink(sink_uptr sink);
|
sink& register_sink(sink_uptr sink);
|
||||||
|
void unregister_sink(const sink& sink);
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& add_sink_ex(level min_lvl, Args&&... args);
|
T& register_sink_ex(level min_lvl, Args&&... args);
|
||||||
sink& add_sink_ex(level min_lvl, sink_uptr sink);
|
sink& register_sink_ex(level min_lvl, sink_uptr sink);
|
||||||
|
|
||||||
void set_min_level(level lvl) noexcept;
|
void set_min_level(level lvl) noexcept;
|
||||||
level min_level() const noexcept;
|
level min_level() const noexcept;
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& log(level lvl, str_view fmt, Args&&... args);
|
debug& log(level lvl, str_view fmt, Args&&... args) noexcept;
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& trace(str_view fmt, Args&&... args);
|
debug& trace(str_view fmt, Args&&... args) noexcept;
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& warning(str_view fmt, Args&&... args);
|
debug& warning(str_view fmt, Args&&... args) noexcept;
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& error(str_view fmt, Args&&... args);
|
debug& error(str_view fmt, Args&&... args) noexcept;
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& fatal(str_view fmt, Args&&... args);
|
debug& fatal(str_view fmt, Args&&... args) noexcept;
|
||||||
private:
|
private:
|
||||||
mutable std::mutex mutex_;
|
mutable std::mutex mutex_;
|
||||||
level min_level_ = level::trace;
|
|
||||||
vector<std::pair<level, sink_uptr>> sinks_;
|
vector<std::pair<level, sink_uptr>> sinks_;
|
||||||
|
level min_level_ = level::trace;
|
||||||
};
|
};
|
||||||
|
|
||||||
class debug_file_sink final : public debug::sink {
|
class debug_file_sink final : public debug::sink {
|
||||||
@@ -77,36 +77,36 @@ namespace e2d
|
|||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& debug::add_sink(Args&&... args) {
|
T& debug::register_sink(Args&&... args) {
|
||||||
return add_sink_ex<T>(level::trace, std::forward<Args>(args)...);
|
return register_sink_ex<T>(
|
||||||
}
|
level::trace,
|
||||||
|
std::forward<Args>(args)...);
|
||||||
inline debug::sink& debug::add_sink(sink_uptr sink) {
|
|
||||||
return add_sink_ex(level::trace, std::move(sink));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename T, typename... Args >
|
template < typename T, typename... Args >
|
||||||
T& debug::add_sink_ex(level min_lvl, Args&&... args) {
|
T& debug::register_sink_ex(level min_lvl, Args&&... args) {
|
||||||
return static_cast<T&>(add_sink_ex(
|
return static_cast<T&>(register_sink_ex(
|
||||||
min_lvl,
|
min_lvl,
|
||||||
std::make_unique<T>(std::forward<Args>(args)...)));
|
std::make_unique<T>(std::forward<Args>(args)...)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline debug::sink& debug::add_sink_ex(level min_lvl, sink_uptr sink) {
|
|
||||||
E2D_ASSERT(sink);
|
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
|
||||||
sinks_.push_back(std::make_pair(min_lvl, std::move(sink)));
|
|
||||||
return *sinks_.back().second;
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& debug::log(level lvl, str_view fmt, Args&&... args) {
|
debug& debug::log(level lvl, str_view fmt, Args&&... args) noexcept {
|
||||||
std::lock_guard<std::mutex> guard(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
if ( lvl >= min_level_ && !sinks_.empty() ) {
|
if ( lvl >= min_level_ && !sinks_.empty() ) {
|
||||||
str text = strings::rformat(fmt, std::forward<Args>(args)...);
|
str formatted_text;
|
||||||
|
try {
|
||||||
|
formatted_text = strings::rformat(
|
||||||
|
fmt, std::forward<Args>(args)...);
|
||||||
|
} catch (...) {
|
||||||
|
E2D_ASSERT_MSG(false, "DEBUG: ignored log formatting exception");
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
for ( const auto& pair : sinks_ ) {
|
for ( const auto& pair : sinks_ ) {
|
||||||
if ( lvl >= pair.first && pair.second ) {
|
if ( lvl >= pair.first && pair.second ) {
|
||||||
pair.second->on_message(lvl, text);
|
bool success = pair.second->on_message(lvl, formatted_text);
|
||||||
|
E2D_UNUSED(success);
|
||||||
|
E2D_ASSERT_MSG(success, "DEBUG: ignored failed log sink call");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -114,22 +114,22 @@ namespace e2d
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& debug::trace(str_view fmt, Args&&... args) {
|
debug& debug::trace(str_view fmt, Args&&... args) noexcept {
|
||||||
return log(level::trace, fmt, std::forward<Args>(args)...);
|
return log(level::trace, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& debug::warning(str_view fmt, Args&&... args) {
|
debug& debug::warning(str_view fmt, Args&&... args) noexcept {
|
||||||
return log(level::warning, fmt, std::forward<Args>(args)...);
|
return log(level::warning, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& debug::error(str_view fmt, Args&&... args) {
|
debug& debug::error(str_view fmt, Args&&... args) noexcept {
|
||||||
return log(level::error, fmt, std::forward<Args>(args)...);
|
return log(level::error, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename... Args >
|
template < typename... Args >
|
||||||
debug& debug::fatal(str_view fmt, Args&&... args) {
|
debug& debug::fatal(str_view fmt, Args&&... args) noexcept {
|
||||||
return log(level::fatal, fmt, std::forward<Args>(args)...);
|
return log(level::fatal, fmt, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,23 +341,25 @@ namespace e2d { namespace strings
|
|||||||
template <>
|
template <>
|
||||||
class format_arg<str> {
|
class format_arg<str> {
|
||||||
str value_;
|
str value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
template < typename U >
|
template < typename U >
|
||||||
explicit format_arg(U&& value)
|
explicit format_arg(U&& value, u8 width = 0)
|
||||||
noexcept(noexcept(std::is_nothrow_constructible<str, U>::value))
|
noexcept(noexcept(std::is_nothrow_constructible<str, U>::value))
|
||||||
: value_(std::forward<U>(value)) {}
|
: value_(std::forward<U>(value)), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||||
return math::numeric_cast<std::ptrdiff_t>(
|
return math::numeric_cast<std::ptrdiff_t>(
|
||||||
format(dst, size, "%0", value_.c_str()));
|
format(dst, size, "%0",
|
||||||
|
make_format_arg(value_.c_str(), width_)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class format_arg<str_view> : public format_arg<str> {
|
class format_arg<str_view> : public format_arg<str> {
|
||||||
public:
|
public:
|
||||||
explicit format_arg(str_view sv)
|
explicit format_arg(str_view sv, u8 width = 0)
|
||||||
: format_arg<str>(sv) {}
|
: format_arg<str>(sv, width) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -367,23 +369,25 @@ namespace e2d { namespace strings
|
|||||||
template <>
|
template <>
|
||||||
class format_arg<wstr> {
|
class format_arg<wstr> {
|
||||||
wstr value_;
|
wstr value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
template < typename U >
|
template < typename U >
|
||||||
explicit format_arg(U&& value)
|
explicit format_arg(U&& value, u8 width = 0)
|
||||||
noexcept(noexcept(std::is_nothrow_constructible<wstr, U>::value))
|
noexcept(noexcept(std::is_nothrow_constructible<wstr, U>::value))
|
||||||
: value_(std::forward<U>(value)) {}
|
: value_(std::forward<U>(value)), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||||
return math::numeric_cast<std::ptrdiff_t>(
|
return math::numeric_cast<std::ptrdiff_t>(
|
||||||
format(dst, size, "%0", make_utf8(value_.c_str())));
|
format(dst, size, "%0",
|
||||||
|
make_format_arg(make_utf8(value_), width_)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class format_arg<wstr_view> : public format_arg<wstr> {
|
class format_arg<wstr_view> : public format_arg<wstr> {
|
||||||
public:
|
public:
|
||||||
explicit format_arg(wstr_view sv)
|
explicit format_arg(wstr_view sv, u8 width = 0)
|
||||||
: format_arg<wstr>(sv) {}
|
: format_arg<wstr>(sv, width) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -393,23 +397,25 @@ namespace e2d { namespace strings
|
|||||||
template <>
|
template <>
|
||||||
class format_arg<str16> {
|
class format_arg<str16> {
|
||||||
str16 value_;
|
str16 value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
template < typename U >
|
template < typename U >
|
||||||
explicit format_arg(U&& value)
|
explicit format_arg(U&& value, u8 width = 0)
|
||||||
noexcept(noexcept(std::is_nothrow_constructible<str16, U>::value))
|
noexcept(noexcept(std::is_nothrow_constructible<str16, U>::value))
|
||||||
: value_(std::forward<U>(value)) {}
|
: value_(std::forward<U>(value)), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||||
return math::numeric_cast<std::ptrdiff_t>(
|
return math::numeric_cast<std::ptrdiff_t>(
|
||||||
format(dst, size, "%0", make_utf8(value_.c_str())));
|
format(dst, size, "%0",
|
||||||
|
make_format_arg(make_utf8(value_), width_)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class format_arg<str16_view> : public format_arg<str16> {
|
class format_arg<str16_view> : public format_arg<str16> {
|
||||||
public:
|
public:
|
||||||
explicit format_arg(str16_view sv)
|
explicit format_arg(str16_view sv, u8 width = 0)
|
||||||
: format_arg<str16>(sv) {}
|
: format_arg<str16>(sv, width) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -419,23 +425,25 @@ namespace e2d { namespace strings
|
|||||||
template <>
|
template <>
|
||||||
class format_arg<str32> {
|
class format_arg<str32> {
|
||||||
str32 value_;
|
str32 value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
template < typename U >
|
template < typename U >
|
||||||
explicit format_arg(U&& value)
|
explicit format_arg(U&& value, u8 width = 0)
|
||||||
noexcept(noexcept(std::is_nothrow_constructible<str32, U>::value))
|
noexcept(noexcept(std::is_nothrow_constructible<str32, U>::value))
|
||||||
: value_(std::forward<U>(value)) {}
|
: value_(std::forward<U>(value)), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const {
|
std::ptrdiff_t write(char* dst, size_t size) const {
|
||||||
return math::numeric_cast<std::ptrdiff_t>(
|
return math::numeric_cast<std::ptrdiff_t>(
|
||||||
format(dst, size, "%0", make_utf8(value_.c_str())));
|
format(dst, size, "%0",
|
||||||
|
make_format_arg(make_utf8(value_), width_)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class format_arg<str32_view> : public format_arg<str32> {
|
class format_arg<str32_view> : public format_arg<str32> {
|
||||||
public:
|
public:
|
||||||
explicit format_arg(str32_view sv)
|
explicit format_arg(str32_view sv, u8 width = 0)
|
||||||
: format_arg<str32>(sv) {}
|
: format_arg<str32>(sv, width) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ namespace e2d { namespace strings
|
|||||||
: value_(value), width_(width), precision_(precision) {}
|
: value_(value), width_(width), precision_(precision) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
||||||
char format[10] = {0};
|
char format[11] = {0};
|
||||||
char* b_format = format;
|
char* b_format = format;
|
||||||
*b_format++ = '%';
|
*b_format++ = '%';
|
||||||
b_format = impl::u8toa(width_, b_format);
|
b_format = impl::u8toa(width_, b_format);
|
||||||
@@ -178,24 +178,40 @@ namespace e2d { namespace strings
|
|||||||
template <>
|
template <>
|
||||||
class format_arg<char*> {
|
class format_arg<char*> {
|
||||||
const char* value_;
|
const char* value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
explicit format_arg(const char* value) noexcept
|
explicit format_arg(const char* value, u8 width = 0) noexcept
|
||||||
: value_(value) {}
|
: value_(value), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
||||||
return std::snprintf(dst, size, "%s", value_);
|
char format[6] = {0};
|
||||||
|
char* b_format = format;
|
||||||
|
*b_format++ = '%';
|
||||||
|
b_format = impl::u8toa(width_, b_format);
|
||||||
|
*b_format++ = 's';
|
||||||
|
E2D_ASSERT(b_format < format + sizeof(format));
|
||||||
|
return std::snprintf(
|
||||||
|
dst, size, format, value_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
class format_arg<const char*> {
|
class format_arg<const char*> {
|
||||||
const char* value_;
|
const char* value_;
|
||||||
|
u8 width_;
|
||||||
public:
|
public:
|
||||||
explicit format_arg(const char* value) noexcept
|
explicit format_arg(const char* value, u8 width = 0) noexcept
|
||||||
: value_(value) {}
|
: value_(value), width_(width) {}
|
||||||
|
|
||||||
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
std::ptrdiff_t write(char* dst, size_t size) const noexcept {
|
||||||
return std::snprintf(dst, size, "%s", value_);
|
char format[6] = {0};
|
||||||
|
char* b_format = format;
|
||||||
|
*b_format++ = '%';
|
||||||
|
b_format = impl::u8toa(width_, b_format);
|
||||||
|
*b_format++ = 's';
|
||||||
|
E2D_ASSERT(b_format < format + sizeof(format));
|
||||||
|
return std::snprintf(
|
||||||
|
dst, size, format, value_);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ int e2d_main() {
|
|||||||
modules::initialize<render>(the<debug>());
|
modules::initialize<render>(the<debug>());
|
||||||
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false);
|
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false);
|
||||||
|
|
||||||
the<debug>().add_sink<debug_console_sink>();
|
the<debug>().register_sink<debug_console_sink>();
|
||||||
the<window>().register_event_listener<window_input_source>(the<input>());
|
the<window>().register_event_listener<window_input_source>(the<input>());
|
||||||
|
|
||||||
const keyboard& k = the<input>().keyboard();
|
const keyboard& k = the<input>().keyboard();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ int e2d_main() {
|
|||||||
modules::initialize<input>();
|
modules::initialize<input>();
|
||||||
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false);
|
modules::initialize<window>(v2u{640, 480}, "Enduro2D", false);
|
||||||
|
|
||||||
the<debug>().add_sink<debug_console_sink>();
|
the<debug>().register_sink<debug_console_sink>();
|
||||||
the<window>().register_event_listener<window_input_source>(the<input>());
|
the<window>().register_event_listener<window_input_source>(the<input>());
|
||||||
the<window>().register_event_listener<window_trace_event_listener>(the<debug>());
|
the<window>().register_event_listener<window_trace_event_listener>(the<debug>());
|
||||||
|
|
||||||
|
|||||||
@@ -10,35 +10,50 @@ namespace
|
|||||||
{
|
{
|
||||||
using namespace e2d;
|
using namespace e2d;
|
||||||
|
|
||||||
const char* level_to_str(debug::level lvl) noexcept {
|
const char* level_to_cstr(debug::level l) noexcept {
|
||||||
switch ( lvl ) {
|
#define DEFINE_CASE(x) case debug::level::x: return #x
|
||||||
case debug::level::trace: return "trace";
|
switch ( l ) {
|
||||||
case debug::level::warning: return "warning";
|
DEFINE_CASE(trace);
|
||||||
case debug::level::error: return "error";
|
DEFINE_CASE(warning);
|
||||||
case debug::level::fatal: return "fatal";
|
DEFINE_CASE(error);
|
||||||
|
DEFINE_CASE(fatal);
|
||||||
default:
|
default:
|
||||||
E2D_ASSERT(false);
|
E2D_ASSERT_MSG(false, "unexpected level");
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
#undef DEFINE_CASE
|
||||||
}
|
}
|
||||||
|
|
||||||
str log_text_format(debug::level lvl, str_view text) {
|
str log_text_format(debug::level lvl, str_view text) {
|
||||||
return strings::rformat(
|
return strings::rformat(
|
||||||
"[%0](%1) -> %2\n",
|
"[%0](%1) -> %2\n",
|
||||||
level_to_str(lvl), time::now_ms(), text);
|
level_to_cstr(lvl), time::now_ms(), text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace e2d
|
namespace e2d
|
||||||
{
|
{
|
||||||
//
|
debug::debug() = default;
|
||||||
// debug
|
debug::~debug() noexcept = default;
|
||||||
//
|
|
||||||
|
|
||||||
debug::debug() {
|
debug::sink& debug::register_sink(sink_uptr sink) {
|
||||||
|
return register_sink_ex(level::trace, std::move(sink));
|
||||||
}
|
}
|
||||||
|
|
||||||
debug::~debug() {
|
void debug::unregister_sink(const sink& sink) {
|
||||||
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
sinks_.erase(std::remove_if(
|
||||||
|
sinks_.begin(), sinks_.end(),
|
||||||
|
[&sink](const std::pair<level, sink_uptr>& p){
|
||||||
|
return p.second.get() == &sink;
|
||||||
|
}), sinks_.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
debug::sink& debug::register_sink_ex(level min_lvl, sink_uptr sink) {
|
||||||
|
E2D_ASSERT(sink);
|
||||||
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
sinks_.push_back(std::make_pair(min_lvl, std::move(sink)));
|
||||||
|
return *sinks_.back().second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug::set_min_level(level lvl) noexcept {
|
void debug::set_min_level(level lvl) noexcept {
|
||||||
@@ -57,15 +72,16 @@ namespace e2d
|
|||||||
|
|
||||||
debug_file_sink::debug_file_sink(str_view path)
|
debug_file_sink::debug_file_sink(str_view path)
|
||||||
: path_(path) {
|
: path_(path) {
|
||||||
make_write_file(path, false);
|
const auto file = make_write_file(path, false);
|
||||||
|
E2D_UNUSED(file);
|
||||||
|
E2D_ASSERT_MSG(file, "DEBUG: ignored failed sink file cleaning");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool debug_file_sink::on_message(debug::level lvl, str_view text) noexcept {
|
bool debug_file_sink::on_message(debug::level lvl, str_view text) noexcept {
|
||||||
try {
|
try {
|
||||||
auto file = make_write_file(path_, true);
|
const auto file = make_write_file(path_, true);
|
||||||
str log_text = log_text_format(lvl, text);
|
|
||||||
return file && output_sequence(*file)
|
return file && output_sequence(*file)
|
||||||
.write(log_text.c_str(), log_text.length())
|
.write_all(log_text_format(lvl, text))
|
||||||
.success();
|
.success();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return false;
|
return false;
|
||||||
@@ -78,7 +94,7 @@ namespace e2d
|
|||||||
|
|
||||||
bool debug_console_sink::on_message(debug::level lvl, str_view text) noexcept {
|
bool debug_console_sink::on_message(debug::level lvl, str_view text) noexcept {
|
||||||
try {
|
try {
|
||||||
str log_text = log_text_format(lvl, text);
|
const str log_text = log_text_format(lvl, text);
|
||||||
const std::ptrdiff_t rprintf = std::printf("%s", log_text.c_str());
|
const std::ptrdiff_t rprintf = std::printf("%s", log_text.c_str());
|
||||||
return rprintf >= 0
|
return rprintf >= 0
|
||||||
&& math::numeric_cast<std::size_t>(rprintf) == log_text.length();
|
&& math::numeric_cast<std::size_t>(rprintf) == log_text.length();
|
||||||
|
|||||||
@@ -14,36 +14,42 @@ namespace
|
|||||||
class test_sink final : public debug::sink {
|
class test_sink final : public debug::sink {
|
||||||
public:
|
public:
|
||||||
str on_message_acc;
|
str on_message_acc;
|
||||||
|
static str s_on_message_acc;
|
||||||
|
|
||||||
bool on_message(debug::level lvl, str_view text) noexcept final {
|
bool on_message(debug::level lvl, str_view text) noexcept final {
|
||||||
E2D_UNUSED(lvl);
|
E2D_UNUSED(lvl);
|
||||||
on_message_acc.append(text.cbegin(), text.cend());
|
on_message_acc.append(text.cbegin(), text.cend());
|
||||||
|
s_on_message_acc.append(text.cbegin(), text.cend());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
str test_sink::s_on_message_acc;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("debug"){
|
TEST_CASE("debug"){
|
||||||
{
|
{
|
||||||
debug d;
|
debug d;
|
||||||
test_sink& s = d.add_sink<test_sink>();
|
test_sink& s = d.register_sink<test_sink>();
|
||||||
REQUIRE(s.on_message_acc.empty());
|
REQUIRE(test_sink::s_on_message_acc.empty());
|
||||||
d.trace("h");
|
d.trace("h");
|
||||||
d.warning("e");
|
d.warning("e");
|
||||||
REQUIRE(s.on_message_acc == "he");
|
REQUIRE(test_sink::s_on_message_acc == "he");
|
||||||
d.set_min_level(debug::level::error);
|
d.set_min_level(debug::level::error);
|
||||||
d.trace("el");
|
d.trace("el");
|
||||||
d.warning("lo");
|
d.warning("lo");
|
||||||
REQUIRE(s.on_message_acc == "he");
|
REQUIRE(test_sink::s_on_message_acc == "he");
|
||||||
d.error("ll");
|
d.error("ll");
|
||||||
REQUIRE(s.on_message_acc == "hell");
|
REQUIRE(test_sink::s_on_message_acc == "hell");
|
||||||
d.fatal("o");
|
d.fatal("o");
|
||||||
REQUIRE(s.on_message_acc == "hello");
|
REQUIRE(test_sink::s_on_message_acc == "hello");
|
||||||
|
d.unregister_sink(s);
|
||||||
|
d.fatal("!!!");
|
||||||
|
REQUIRE(test_sink::s_on_message_acc == "hello");
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
modules::initialize<debug>();
|
modules::initialize<debug>();
|
||||||
test_sink& s1 = the<debug>().add_sink_ex<test_sink>(debug::level::warning);
|
test_sink& s1 = the<debug>().register_sink_ex<test_sink>(debug::level::warning);
|
||||||
test_sink& s2 = the<debug>().add_sink_ex<test_sink>(debug::level::error);
|
test_sink& s2 = the<debug>().register_sink_ex<test_sink>(debug::level::error);
|
||||||
REQUIRE(s1.on_message_acc.empty());
|
REQUIRE(s1.on_message_acc.empty());
|
||||||
REQUIRE(s2.on_message_acc.empty());
|
REQUIRE(s2.on_message_acc.empty());
|
||||||
the<debug>().trace("w");
|
the<debug>().trace("w");
|
||||||
|
|||||||
@@ -344,6 +344,36 @@ TEST_CASE("strings") {
|
|||||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9) ==
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9) ==
|
||||||
str("0 2 1 4 3 6 7 5 8 9"));
|
str("0 2 1 4 3 6 7 5 8 9"));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg("ab", u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg("ab", u8(3))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg("ab", u8(2))) == "ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg("ab", u8(1))) == "ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg("ab", u8(0))) == "ab");
|
||||||
|
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str("ab"), u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str("ab"), u8(3))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str("ab"), u8(2))) == "ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str("ab"), u8(1))) == "ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str("ab"), u8(0))) == "ab");
|
||||||
|
|
||||||
|
{
|
||||||
|
auto s1 = make_utf8("ab");
|
||||||
|
auto s2 = make_wide("ab");
|
||||||
|
auto s3 = make_utf16("ab");
|
||||||
|
auto s4 = make_utf32("ab");
|
||||||
|
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(s1, u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(s2, u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(s3, u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(s4, u8(4))) == " ab");
|
||||||
|
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str_view(s1), u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(wstr_view(s2), u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str16_view(s3), u8(4))) == " ab");
|
||||||
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(str32_view(s4), u8(4))) == " ab");
|
||||||
|
}
|
||||||
|
}
|
||||||
{
|
{
|
||||||
REQUIRE(strings::rformat("%0", strings::make_format_arg(-5, u8(3))) == " -5");
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(-5, u8(3))) == " -5");
|
||||||
REQUIRE(strings::rformat("%0", strings::make_format_arg(-5, u8(4))) == " -5");
|
REQUIRE(strings::rformat("%0", strings::make_format_arg(-5, u8(4))) == " -5");
|
||||||
|
|||||||
Reference in New Issue
Block a user