diff --git a/Include/Aurora/Logging/LogClasses.hpp b/Include/Aurora/Logging/LogClasses.hpp new file mode 100644 index 00000000..0928702e --- /dev/null +++ b/Include/Aurora/Logging/LogClasses.hpp @@ -0,0 +1,28 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: LogClasses.hpp + Date: 2023-3-22 + Author: Reece +***/ +#pragma once + +namespace Aurora::Logging +{ + /** + * @brief Allocates a number between kLogLevelUsr and kLogLevelMax + * @return + */ + AUKN_SYM AuResult LogClassGetNext(); + AUKN_SYM void LogClassRelease(AuUInt8 uIndex); + + AUKN_SYM void LogClassAssociateName(AuUInt8 uIndex, const AuString &str); + + AUKN_SYM AuString LogClassGetNameSafe(AuUInt8 uIndex); + AUKN_SYM const AuString &LogClassGetNameUnsafe(AuUInt8 uIndex); + + AUKN_SYM bool LogClassInUse(AuUInt8 uIndex); + + AUKN_SYM AuUInt8 LogClassTotalInUse(); + AUKN_SYM AuUInt8 LogClassTotalAvailable(); +} \ No newline at end of file diff --git a/Include/Aurora/Logging/Logging.hpp b/Include/Aurora/Logging/Logging.hpp index 2e051f85..c4dd3a28 100644 --- a/Include/Aurora/Logging/Logging.hpp +++ b/Include/Aurora/Logging/Logging.hpp @@ -15,6 +15,7 @@ #include "IBasicSinkRB.hpp" #include "IIPCLogger.hpp" #include "Sinks.hpp" +#include "LogClasses.hpp" namespace Aurora::Debug { diff --git a/Source/Logging/AuLogClasses.cpp b/Source/Logging/AuLogClasses.cpp new file mode 100644 index 00000000..50a3349a --- /dev/null +++ b/Source/Logging/AuLogClasses.cpp @@ -0,0 +1,125 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuLogClasses.cpp + Date: 2023-3-22 + Author: Reece +***/ +#include +#include "AuLogClasses.hpp" + +namespace Aurora::Logging +{ + static const AuUInt8 kAvailableSlots = AuLog::kLogLevelMax - AuLog::kLogLevelUsr; + static AuUInt32 gAtomicInUseCount {}; + static AuUInt32 gInUseMap[kAvailableSlots / 8] {}; + static AuString gStringMap[kAvailableSlots]; + static AuUInt32 gIterator {}; + static AuThreadPrimitives::MutexSOO gMutex; + + AUKN_SYM bool LogClassInUse(AuUInt8 uIndex); + + static bool TryAcquire(AuUInt8 uIdx) + { + if (AuAtomicSet(&gInUseMap[uIdx / (8 * sizeof(*gInUseMap))], uIdx % (8 * sizeof(*gInUseMap)))) + { + return false; + } + + AuAtomicAdd(&gAtomicInUseCount, 1u); + return true; + } + + static void Release(AuUInt8 uIdx) + { + if (AuAtomicUnset(&gInUseMap[uIdx / (8 * sizeof(*gInUseMap))], uIdx % (8 * sizeof(*gInUseMap)))) + { + AuAtomicSub(&gAtomicInUseCount, 1u); + + AU_LOCK_GUARD(gMutex); + + if (!LogClassInUse(uIdx + AuLog::kLogLevelUsr)) + { + gStringMap[uIdx].clear(); + } + } + } + + static void SetString(AuUInt8 uIdx, const AuString &str) + { + AU_LOCK_GUARD(gMutex); + gStringMap[uIdx] = str; + } + + static AuResult TryAcquire() + { + auto uFirstGuess = (AuAtomicAdd(&gIterator, 1u) - 1) % kAvailableSlots; + + if (!TryAcquire(uFirstGuess)) + { + for (AU_ITERATE_N(i, kAvailableSlots)) + { + auto uIndex = (i + uFirstGuess) % kAvailableSlots; + if (TryAcquire(uIndex)) + { + gIterator = uIndex; + return AuUInt8(i); + } + } + + return {}; + } + else + { + return AuUInt8(uFirstGuess); + } + } + + AUKN_SYM void LogClassAssociateName(AuUInt8 uIndex, const AuString &str) + { + SetString(uIndex - AuLog::kLogLevelUsr, str); + } + + AUKN_SYM const AuString &LogClassGetNameUnsafe(AuUInt8 uIndex) + { + return gStringMap[uIndex - AuLog::kLogLevelUsr]; + } + + AUKN_SYM AuString LogClassGetNameSafe(AuUInt8 uIndex) + { + AU_LOCK_GUARD(gMutex); + return gStringMap[uIndex - AuLog::kLogLevelUsr]; + } + + AUKN_SYM void LogClassRelease(AuUInt8 uIndex) + { + Release(uIndex - AuLog::kLogLevelUsr); + } + + AUKN_SYM AuResult LogClassGetNext() + { + auto uRes = TryAcquire(); + if (uRes) + { + return AuUInt8(uRes.value() + AuLog::kLogLevelUsr); + } + + return {}; + } + + AUKN_SYM bool LogClassInUse(AuUInt8 uIndex) + { + uIndex -= AuLog::kLogLevelUsr; + return gInUseMap[uIndex / (8 * sizeof(*gInUseMap))] & (1u << (uIndex % (8 * sizeof(*gInUseMap)))); + } + + AUKN_SYM AuUInt8 LogClassTotalAvailable() + { + return kAvailableSlots; + } + + AUKN_SYM AuUInt8 LogClassTotalInUse() + { + return gAtomicInUseCount; + } +} \ No newline at end of file diff --git a/Source/Logging/AuLogClasses.hpp b/Source/Logging/AuLogClasses.hpp new file mode 100644 index 00000000..b3f1a364 --- /dev/null +++ b/Source/Logging/AuLogClasses.hpp @@ -0,0 +1,14 @@ +/*** + Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. + + File: AuLogClasses.hpp + Date: 2023-3-22 + Author: Reece +***/ +#pragma once + +namespace Aurora::Logging +{ + + +} \ No newline at end of file