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)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(NBEngine VERSION 0.1.0 LANGUAGES C CXX)
|
project(NBEngine VERSION 0.1.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
|
cmake_policy(SET CMP0135 NEW)
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
message(STATUS "Targeting Release build")
|
message(STATUS "Targeting Release build")
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ./release)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ./release)
|
||||||
@ -33,6 +35,7 @@ set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
|
|||||||
|
|
||||||
if(NB_BUILD_TESTS)
|
if(NB_BUILD_TESTS)
|
||||||
message(STATUS "Building tests")
|
message(STATUS "Building tests")
|
||||||
|
enable_testing()
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
gtest
|
gtest
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Processes.hpp"
|
#include "Processes.hpp"
|
||||||
#include "ThreadSafeQueue.hpp"
|
#include "ThreadSafeQueue.hpp"
|
||||||
@ -30,14 +31,23 @@ struct LogEvent{
|
|||||||
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
typedef std::string (*LogProcessFunction)(const LoggerTimePoint&, const std::string&);
|
||||||
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
typedef std::unordered_map<uint8_t, LogProcessFunction> LogProcessFunctionMap;
|
||||||
|
|
||||||
template<typename LoggerName>
|
template<typename LoggerName, typename ST=std::ostream>
|
||||||
class Logger {
|
class LoggerBase {
|
||||||
public:
|
public:
|
||||||
using Type = LoggerName;
|
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);
|
return _running && bool(_runningThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,9 +56,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool run() {
|
bool run() {
|
||||||
auto this_type = static_cast<Type*>(this);
|
|
||||||
if (!isRunning()) {
|
if (!isRunning()) {
|
||||||
|
_running = true;
|
||||||
_runningThread = std::make_shared<std::thread>([&]{
|
_runningThread = std::make_shared<std::thread>([&]{
|
||||||
|
auto this_type = static_cast<Type*>(this);
|
||||||
while(this_type->isRunning()) {
|
while(this_type->isRunning()) {
|
||||||
this_type->flush();
|
this_type->flush();
|
||||||
}
|
}
|
||||||
@ -57,7 +68,7 @@ public:
|
|||||||
return isRunning();
|
return isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop() {
|
bool stop() noexcept {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
_running = false;
|
_running = false;
|
||||||
_runningThread->join();
|
_runningThread->join();
|
||||||
@ -74,7 +85,7 @@ public:
|
|||||||
return *event;
|
return *event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void flush() {
|
void flush() noexcept {
|
||||||
while(_queue.size()) {
|
while(_queue.size()) {
|
||||||
pop();
|
pop();
|
||||||
}
|
}
|
||||||
@ -93,33 +104,38 @@ public:
|
|||||||
lvl,
|
lvl,
|
||||||
msg,
|
msg,
|
||||||
std::this_thread::get_id(),
|
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) {
|
void log(const std::exception& err, const uint8_t& lvl) {
|
||||||
_queue.push(LogEvent{
|
_queue.push(LogEvent{
|
||||||
std::chrono::system_clock::now(),
|
std::chrono::system_clock::now(),
|
||||||
lvl,
|
lvl,
|
||||||
err.what(),
|
err.what(),
|
||||||
std::this_thread::get_id(),
|
std::this_thread::get_id(),
|
||||||
get_pid(),
|
GetPID(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void msg(const std::string& msg, const uint8_t& lvl=0x00) {
|
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) {
|
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) {
|
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) {
|
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) {
|
void error(const std::exception& err, const uint8_t lvl=0xFF) {
|
||||||
static_cast<Type*>(this)->log(err, lvl);
|
static_cast<Type*>(this)->log(err, lvl);
|
||||||
@ -129,18 +145,18 @@ protected:
|
|||||||
void process(const LogEvent&);
|
void process(const LogEvent&);
|
||||||
|
|
||||||
ThreadsafeQueue<LogEvent> _queue;
|
ThreadsafeQueue<LogEvent> _queue;
|
||||||
std::ostream* const _ostream;
|
std::vector<StreamType*> const _ostreams;
|
||||||
std::atomic<bool> _running;
|
std::atomic<bool> _running;
|
||||||
std::shared_ptr<std::thread> _runningThread = nullptr;
|
std::shared_ptr<std::thread> _runningThread = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BasicLogger : public Logger<BasicLogger> {
|
class BasicLogger : public LoggerBase<BasicLogger> {
|
||||||
public:
|
public:
|
||||||
using Base = Logger<BasicLogger>;
|
using Base = LoggerBase<BasicLogger>;
|
||||||
BasicLogger(std::ostream& stream) : Base(stream) {}
|
BasicLogger(std::ostream& stream) : Base(stream) {}
|
||||||
|
|
||||||
virtual void process(const LogEvent& event) {
|
virtual void process(const LogEvent& event) {
|
||||||
*_ostream << event.msg << "\n";
|
*_ostreams[0] << event.msg << "\n";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
namespace nb {
|
namespace nb {
|
||||||
|
|
||||||
uint64_t get_pid();
|
uint64_t GetPID();
|
||||||
|
|
||||||
} // namespace nb
|
} // 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
|
#endif // _TARGET_LINUX
|
||||||
|
|
||||||
#include "Processes.hpp"
|
#include "Processes.hpp"
|
||||||
|
#include "Types.hpp"
|
||||||
|
|
||||||
namespace nb {
|
namespace nb {
|
||||||
|
|
||||||
#ifdef _TARGET_WINDOWS
|
#ifdef _TARGET_WINDOWS
|
||||||
uint64_t get_pid() {
|
uint64_t GetPID() {
|
||||||
const auto pid_w = GetCurrentProcessId();
|
return GetCurrentProcessId();
|
||||||
uint64_t ret;
|
|
||||||
memcpy(&ret, &pid_w, sizeof(pid_w));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#endif // _TARGET_WINDOWS
|
#endif // _TARGET_WINDOWS
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,16 @@
|
|||||||
cmake_minimum_required(VERSION 3.26.0)
|
cmake_minimum_required(VERSION 3.26.0)
|
||||||
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
|
project(gtest_Graphics VERSION 0.1.0 LANGUAGES C CXX)
|
||||||
|
|
||||||
add_subdirectory(./ErrorTest)
|
include(GoogleTest)
|
||||||
add_subdirectory(./ProcessTest)
|
|
||||||
|
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
|
#define CODE_ERROR_LOCATIONS
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Processes.hpp"
|
#include "Processes.hpp"
|
||||||
#include <Windows.h>
|
#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
|
#ifdef _TARGET_WINDOWS
|
||||||
std::cout << "GetCurrentProcessId() -> " << GetCurrentProcessId() << std::endl;
|
std::cout << "GetCurrentProcessId() -> " << GetCurrentProcessId() << std::endl;
|
||||||
#endif // _TARGET_WINDOWS
|
#endif // _TARGET_WINDOWS
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} */
|
||||||
Loading…
x
Reference in New Issue
Block a user