/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: Hooks.cpp Date: 2021-6-12 Author: Reece ***/ #include #include "Hooks.hpp" namespace Aurora::Console::Hooks { static AuThreadPrimitives::Mutex gMutex; static AuList gLineFunctionalCallbacks; static AuList> gLineSubscribers; AUKN_SYM void AddSubscription(const AuSPtr &subscriber) { AU_LOCK_GUARD(gMutex); AuTryInsert(gLineSubscribers, subscriber); } AUKN_SYM void RemoveSubscription(const AuSPtr &subscriber) { AU_LOCK_GUARD(gMutex); AuTryRemove(gLineSubscribers, subscriber); } AUKN_SYM void AddFunctionalHook(LineHook_cb hook) { AU_LOCK_GUARD(gMutex); AuTryInsert(gLineFunctionalCallbacks, hook); } AUKN_SYM void SetCallbackAndDisableCmdProcessing(const AuSPtr &subscriber) { gExternalLineProcessor = subscriber; } void WriteLoggerFailedWarning() { static AuString kLoggerError = "Something went from while dispatching a log line\n"; Console::WriteStdOut(kLoggerError.data(), (AuUInt32)kLoggerError.size()); #if defined(AURORA_IS_MODERNNT_DERIVED) OutputDebugStringA(kLoggerError.c_str()); #endif } static void TryWrite(const ConsoleMessage &msg) { for (const auto &callback : gLineFunctionalCallbacks) { try { callback(msg); } catch (...) { WriteLoggerFailedWarning(); } } for (const auto &sub : gLineSubscribers) { try { sub->OnMessage(msg); } catch (...) { WriteLoggerFailedWarning(); } } } void WriteLine(const ConsoleMessage &msg) { if (!gMutex) return; AU_LOCK_GUARD(gMutex); try { if (msg.line.find('\n') == AuString::npos) [[likely]] { TryWrite(msg); } else [[unlikely]] { Parse::SplitNewlines(msg.line, [&](const AuROString &line) { ConsoleMessage dup = msg; dup.line = line; TryWrite(dup); }); } } catch (...) { // Loggers experiencing something fucky is a liablity WriteLoggerFailedWarning(); } } void Init() { } void Deinit() { gLineFunctionalCallbacks.clear(); gLineSubscribers.clear(); } }