Restructured tests and matured Logger a lil bit, now LoggerBase
This commit is contained in:
parent
f8a8813b3e
commit
3b828a34ff
@ -1,6 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(NBEngine VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
message(STATUS "Targeting Release build")
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ./release)
|
||||
@ -33,6 +35,7 @@ set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if(NB_BUILD_TESTS)
|
||||
message(STATUS "Building tests")
|
||||
enable_testing()
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
gtest
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include <ostream>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "Processes.hpp"
|
||||
#include "ThreadSafeQueue.hpp"
|
||||
@ -30,14 +31,23 @@ struct LogEvent{
|
||||
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
||||
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
||||
|
||||
template<typename LoggerName>
|
||||
class Logger {
|
||||
template<typename LoggerName, typename ST=std::ostream>
|
||||
class LoggerBase {
|
||||
public:
|
||||
using Type = LoggerName;
|
||||
using StreamType = ST;
|
||||
|
||||
Logger(std::ostream& stream) : _ostream(&stream) {}
|
||||
LoggerBase(StreamType& stream) : _ostreams({&stream}) {}
|
||||
LoggerBase(const LoggerBase&) = delete;
|
||||
LoggerBase(LoggerBase&&) = delete;
|
||||
|
||||
bool isRunning() const {
|
||||
LoggerBase& operator=(const LoggerBase&) = delete;
|
||||
|
||||
~LoggerBase() {
|
||||
stop();
|
||||
}
|
||||
|
||||
bool isRunning() const noexcept {
|
||||
return _running && bool(_runningThread);
|
||||
}
|
||||
|
||||
@ -46,9 +56,10 @@ public:
|
||||
}
|
||||
|
||||
bool run() {
|
||||
auto this_type = static_cast<Type*>(this);
|
||||
if (!isRunning()) {
|
||||
_running = true;
|
||||
_runningThread = std::make_shared<std::thread>([&]{
|
||||
auto this_type = static_cast<Type*>(this);
|
||||
while(this_type->isRunning()) {
|
||||
this_type->flush();
|
||||
}
|
||||
@ -57,7 +68,7 @@ public:
|
||||
return isRunning();
|
||||
}
|
||||
|
||||
bool stop() {
|
||||
bool stop() noexcept {
|
||||
if (isRunning()) {
|
||||
_running = false;
|
||||
_runningThread->join();
|
||||
@ -74,7 +85,7 @@ public:
|
||||
return *event;
|
||||
}
|
||||
|
||||
void flush() {
|
||||
void flush() noexcept {
|
||||
while(_queue.size()) {
|
||||
pop();
|
||||
}
|
||||
@ -93,33 +104,38 @@ public:
|
||||
lvl,
|
||||
msg,
|
||||
std::this_thread::get_id(),
|
||||
get_pid(),
|
||||
GetPID(),
|
||||
});
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void log(char const(&msg) [N], const uint8_t& lvl) {
|
||||
static_cast<Type*>(this)->log(std::string(msg), lvl);
|
||||
}
|
||||
|
||||
void log(const std::exception& err, const uint8_t& lvl) {
|
||||
_queue.push(LogEvent{
|
||||
std::chrono::system_clock::now(),
|
||||
lvl,
|
||||
err.what(),
|
||||
std::this_thread::get_id(),
|
||||
get_pid(),
|
||||
GetPID(),
|
||||
});
|
||||
}
|
||||
|
||||
void msg(const std::string& msg, const uint8_t& lvl=0x00) {
|
||||
static_cast<Type>(this)->log(msg, lvl);
|
||||
static_cast<Type*>(this)->log(msg, lvl);
|
||||
}
|
||||
|
||||
void warn(const std::string& msg, const uint8_t& lvl=0x01) {
|
||||
static_cast<Type>(this)->log(msg, lvl);
|
||||
static_cast<Type*>(this)->log(msg, lvl);
|
||||
}
|
||||
void warn(const std::exception& err, const uint8_t lvl=0x01) {
|
||||
static_cast<Type>(this)->log(err, lvl);
|
||||
static_cast<Type*>(this)->log(err, lvl);
|
||||
}
|
||||
|
||||
void error(const std::string& msg, const uint8_t lvl=0xFF) {
|
||||
static_cast<Type>(this)->log(msg, lvl);
|
||||
static_cast<Type*>(this)->log(msg, lvl);
|
||||
}
|
||||
void error(const std::exception& err, const uint8_t lvl=0xFF) {
|
||||
static_cast<Type*>(this)->log(err, lvl);
|
||||
@ -129,18 +145,18 @@ protected:
|
||||
void process(const LogEvent&);
|
||||
|
||||
ThreadsafeQueue<LogEvent> _queue;
|
||||
std::ostream* const _ostream;
|
||||
std::vector<StreamType*> const _ostreams;
|
||||
std::atomic<bool> _running;
|
||||
std::shared_ptr<std::thread> _runningThread = nullptr;
|
||||
};
|
||||
|
||||
class BasicLogger : public Logger<BasicLogger> {
|
||||
class BasicLogger : public LoggerBase<BasicLogger> {
|
||||
public:
|
||||
using Base = Logger<BasicLogger>;
|
||||
using Base = LoggerBase<BasicLogger>;
|
||||
BasicLogger(std::ostream& stream) : Base(stream) {}
|
||||
|
||||
virtual void process(const LogEvent& event) {
|
||||
*_ostream << event.msg << "\n";
|
||||
*_ostreams[0] << event.msg << "\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
namespace nb {
|
||||
|
||||
uint64_t get_pid();
|
||||
uint64_t GetPID();
|
||||
|
||||
} // namespace nb
|
||||
|
||||
|
||||
21
engine/NBCore/Types.hpp
Normal file
21
engine/NBCore/Types.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
#ifndef _NB_CORE_TYPES
|
||||
#define _NB_CORE_TYPES
|
||||
|
||||
namespace nb {
|
||||
|
||||
template<typename T>
|
||||
T swapEndian(const T& val) {
|
||||
T ret;
|
||||
const int size = sizeof(T);
|
||||
auto retLoc = static_cast<void*>(&ret);
|
||||
auto valLoc = static_cast<const void*>(&val);
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
memcpy(retLoc+i, valLoc+(size-i-1), 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace nb
|
||||
#endif // _NB_CORE_TYPES
|
||||
@ -7,15 +7,13 @@
|
||||
#endif // _TARGET_LINUX
|
||||
|
||||
#include "Processes.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
namespace nb {
|
||||
|
||||
#ifdef _TARGET_WINDOWS
|
||||
uint64_t get_pid() {
|
||||
const auto pid_w = GetCurrentProcessId();
|
||||
uint64_t ret;
|
||||
memcpy(&ret, &pid_w, sizeof(pid_w));
|
||||
return ret;
|
||||
uint64_t GetPID() {
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
#endif // _TARGET_WINDOWS
|
||||
|
||||
|
||||
@ -1,5 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.26.0)
|
||||
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
add_subdirectory(./ErrorTest)
|
||||
add_subdirectory(./ProcessTest)
|
||||
include(GoogleTest)
|
||||
|
||||
if (NB_BUILD_TESTS)
|
||||
add_executable(TestCore
|
||||
testErrors.cpp
|
||||
testProcesses.cpp
|
||||
)
|
||||
target_link_libraries(TestCore
|
||||
NBCore
|
||||
GTest::gtest_main
|
||||
)
|
||||
gtest_discover_tests(TestCore)
|
||||
endif()
|
||||
@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.26.0)
|
||||
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
add_executable(ErrorTest main.cpp)
|
||||
target_link_libraries(ErrorTest NBCore)
|
||||
@ -1,54 +0,0 @@
|
||||
#define CODE_ERROR_LOCATIONS
|
||||
|
||||
#include "Errors.hpp"
|
||||
#include <iostream>
|
||||
#include "Logger.hpp"
|
||||
|
||||
using namespace nb;
|
||||
|
||||
class TestError : public ErrorBase<TestError> {
|
||||
public:
|
||||
using ErrorBase<TestError>::ErrorBase;
|
||||
|
||||
enum ErrorCodes : unsigned int {
|
||||
A, B, C, D
|
||||
};
|
||||
static const std::string type;
|
||||
static const ErrorCodeMap ErrorMessages;
|
||||
};
|
||||
|
||||
const std::string TestError::type="TestError";
|
||||
const ErrorCodeMap TestError::ErrorMessages{
|
||||
{TestError::ErrorCodes::A, "Hey!"},
|
||||
{TestError::ErrorCodes::B, "How"},
|
||||
{TestError::ErrorCodes::C, "You"},
|
||||
{TestError::ErrorCodes::D, "Doin"}
|
||||
};
|
||||
|
||||
int main() {
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
try {
|
||||
THROW(TestError, TestError::ErrorCodes::D);
|
||||
} catch (const std::exception& e){
|
||||
THROW(TestError, TestError::ErrorCodes::C, e);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
THROW(TestError, TestError::ErrorCodes::B, e);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
THROW(TestError, TestError::ErrorCodes::A, e);
|
||||
}
|
||||
} catch(const std::exception& e) {
|
||||
// THROW(Error, Error::ErrorCodes::UNDEFINED, e);
|
||||
BasicLogger log(std::cout);
|
||||
std::cout << "Logger is starting: " << log.run() << std::endl;
|
||||
std::cout << "Logger is running: " << log.isRunning() << std::endl;
|
||||
log.error(e);
|
||||
log.stop();
|
||||
std::cout << "Logger is running: " << log.isRunning() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.26.0)
|
||||
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
add_executable(ProcessTest main.cpp)
|
||||
target_link_libraries(ProcessTest NBCore)
|
||||
45
engine/NBCore/tests/testErrors.cpp
Normal file
45
engine/NBCore/tests/testErrors.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#define CODE_ERROR_LOCATIONS
|
||||
|
||||
#include "Errors.hpp"
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include "Logger.hpp"
|
||||
|
||||
using namespace nb;
|
||||
|
||||
class TestError : public ErrorBase<TestError> {
|
||||
public:
|
||||
using ErrorBase<TestError>::ErrorBase;
|
||||
|
||||
enum ErrorCodes : unsigned int {
|
||||
A, B, C, D
|
||||
};
|
||||
static const std::string type;
|
||||
static const ErrorCodeMap ErrorMessages;
|
||||
};
|
||||
|
||||
const std::string TestError::type="TestError";
|
||||
const ErrorCodeMap TestError::ErrorMessages{
|
||||
{TestError::ErrorCodes::A, "Hey!"},
|
||||
{TestError::ErrorCodes::B, "How"},
|
||||
{TestError::ErrorCodes::C, "You"},
|
||||
{TestError::ErrorCodes::D, "Doin"}
|
||||
};
|
||||
|
||||
class TestLogger : public nb::LoggerBase<TestLogger> {
|
||||
public:
|
||||
using Base = LoggerBase<TestLogger>;
|
||||
using Base::Base;
|
||||
|
||||
virtual void process(const LogEvent& event) {
|
||||
*_ostreams[0] << event.pid << " : " << event.msg << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ErrorTest, Test) {
|
||||
EXPECT_EQ(1, 1);
|
||||
|
||||
TestLogger log(std::cout);
|
||||
ASSERT_TRUE(log.run());
|
||||
log.msg("Hey!");
|
||||
}
|
||||
@ -1,17 +1,22 @@
|
||||
#define CODE_ERROR_LOCATIONS
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <iostream>
|
||||
#include "Processes.hpp"
|
||||
#include <Windows.h>
|
||||
|
||||
int main() {
|
||||
TEST(ProcessesTest, GetPID) {
|
||||
ASSERT_EQ(nb::GetPID(), GetCurrentProcessId());
|
||||
}
|
||||
|
||||
std::cout << "nb::get_pid() -> " << nb::get_pid() << std::endl;
|
||||
/* int main() {
|
||||
|
||||
std::cout << "nb::GetPID() -> " << nb::GetPID() << std::endl;
|
||||
|
||||
#ifdef _TARGET_WINDOWS
|
||||
std::cout << "GetCurrentProcessId() -> " << GetCurrentProcessId() << std::endl;
|
||||
#endif // _TARGET_WINDOWS
|
||||
|
||||
return 0;
|
||||
}
|
||||
} */
|
||||
Loading…
x
Reference in New Issue
Block a user