PGE + Boilerplate

This commit is contained in:
Ben Kyd
2020-08-29 20:51:39 +00:00
parent 371599c177
commit 320f55ddc9
44 changed files with 50033 additions and 2 deletions

View File

@@ -0,0 +1,126 @@
#include "Logger.hpp"
#if defined(_MSC_VER)
#pragma warning(disable:4996)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include <iomanip>
#include <chrono>
#include <ctime>
Logger::Logger()
{
#if defined(_WINDOWS)
GetConsoleScreenBufferInfo(h, &csbiInfo);
wOldColorAttrs = csbiInfo.wAttributes;
#endif
}
constexpr const char* magic(ELogType::Type e)
{
switch (e)
{
default: return ""; break;
case ELogType::Type::NONE: return ""; break;
case ELogType::Type::INFO: return "INFO"; break;
case ELogType::Type::DEBUG: return "DEBUG"; break;
case ELogType::Type::WARN: return "WARN"; break;
case ELogType::Type::ERR: return "ERROR"; break;
case ELogType::Type::PANIC: return "PANIC"; break;
}
}
void OutputWorker(Logger* _Logger)
{
while (_Logger->_IsRunning)
{
std::unique_lock<std::mutex> lock(_Logger->_QueueLock);
_Logger->_TaskEnqueued.wait(lock, [&] { return !_Logger->_LogQueue.empty(); });
LogEntity* entity = _Logger->_LogQueue.front();
_Logger->_LogQueue.pop();
lock.unlock();
// Get C Time
auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::ostringstream oss;
oss << "[" << std::put_time(&tm, "%d-%m-%Y %H:%M:%S") << "] ";
while (_Logger->_IsLogging) {}
_Logger->_IsLogging = true;
if (entity->Type == ELogType::NONE)
{
oss << entity->Message;
std::cout << oss.str() << std::endl;
_Logger->_IsLogging = false;
if (_Logger->_HasFileHandle) _Logger->_FileOutput << oss.str() << std::endl;
delete entity;
continue;
}
oss << "[";
std::cout << oss.str();
switch (entity->Type)
{
case ELogType::INFO:
Colour::ConsoleColour(EConsoleColour::FG_GREEN);
break;
case ELogType::DEBUG:
Colour::ConsoleColour(EConsoleColour::FG_BLUE);
break;
case ELogType::WARN:
Colour::ConsoleColour(EConsoleColour::FG_YELLOW);
break;
case ELogType::ERR:
Colour::ConsoleColour(EConsoleColour::FG_LIGHT_RED);
break;
case ELogType::PANIC:
Colour::ConsoleColour(EConsoleColour::FG_RED);
break;
}
std::cout << magic(entity->Type);
Colour::ResetColour();
std::cout << "] " << entity->Message << std::endl;
_Logger->_IsLogging = false;
if (_Logger->_HasFileHandle)
_Logger->_FileOutput << oss.str() << magic(entity->Type) << "] " << entity->Message << std::endl;
// TODO: This won't exit, i need it to exit the main thread
//if (entity->Type == ELogType::PANIC) delete entity; exit(0);
delete entity;
}
}
void Logger::InitializeFileLogging(std::filesystem::path path)
{
if (_HasFileHandle) return;
_FileOutput = std::ofstream();
_FileOutput.open(path, std::ios_base::app);
_HasFileHandle = true;
}
void Logger::InitializeLoggingThread()
{
_IsRunning = true;
_OutputWorker = new std::thread(&OutputWorker, this);
}
Logger::~Logger()
{
// Signal to the thread that its time to stop
_IsRunning = false;
_OutputWorker->join();
if (_OutputWorker != nullptr)
delete _OutputWorker;
}

View File

@@ -0,0 +1,309 @@
#ifndef F4MPSERVER_LOGGER_H_
#define F4MPSERVER_LOGGER_H_
#include <filesystem>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <thread>
#include <atomic>
#include <condition_variable>
#include <queue>
#if defined(_WINDOWS)
#include <Windows.h>
namespace EConsoleColour
{
enum Colour
{
FG_BLACK = 0,
FG_BLUE = FOREGROUND_BLUE,
FG_GREEN = FOREGROUND_GREEN,
FG_CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE,
FG_RED = FOREGROUND_RED,
FG_MAGENTA = FOREGROUND_RED | FOREGROUND_BLUE,
FG_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN,
FG_GRAY = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
FG_LIGHT_GRAY = FOREGROUND_INTENSITY,
FG_LIGHT_BLUE = FOREGROUND_INTENSITY | FOREGROUND_BLUE,
FG_LIGHT_GREEN = FOREGROUND_INTENSITY | FOREGROUND_GREEN,
FG_LIGHT_CYAN = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_BLUE,
FG_LIGHT_RED = FOREGROUND_INTENSITY | FOREGROUND_RED,
FG_LIGHT_MAGENTA = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE,
FG_LIGHT_YELLOW = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN,
FG_WHITE = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
FG_DEFAULT = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
BG_DEFAULT = 0
};
}
static HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
static WORD wOldColorAttrs;
static CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
#else
namespace EConsoleColour
{
enum Colour
{
FG_DEFAULT = 39,
FG_BLACK = 30,
FG_RED = 31,
FG_GREEN = 32,
FG_YELLOW = 33,
FG_BLUE = 34,
FG_MAGENTA = 35,
FG_CYAN = 36,
FG_LIGHT_GRAY = 37,
FG_DARK_GRAY = 90,
FG_LIGHT_RED = 91,
FG_LIGHT_GREEN = 92,
FG_LIGHT_YELLOW = 93,
FG_LIGHT_BLUE = 94,
FG_LIGHT_MAGENTA = 95,
FG_LIGHT_CYAN = 96,
FG_WHITE = 97,
BG_RED = 41,
BG_GREEN = 42,
BG_BLUE = 44,
BG_DEFAULT = 49
};
}
#endif
class Colour
{
public:
static inline void ResetColour()
{
#if defined(_WINDOWS)
SetConsoleTextAttribute(h, EConsoleColour::BG_DEFAULT);
SetConsoleTextAttribute(h, EConsoleColour::FG_DEFAULT);
#else
std::cout
<< "\033[" << EConsoleColour::FG_DEFAULT << "m"
<< "\033[" << EConsoleColour::BG_DEFAULT << "m";
#endif
}
template<typename T>
static inline void ConsoleColour(T colour)
{
#if defined(_WINDOWS)
SetConsoleTextAttribute(h, colour);
#else
std::cout << "\033[" << colour << "m";
#endif
}
};
class LogManager
{
};
namespace ELogType
{
enum Type : uint8_t
{
NONE,
INFO,
DEBUG,
WARN,
ERR,
PANIC
};
}
struct LogEntity
{
std::string Message;
ELogType::Type Type;
};
// Config must be loaded first
class Logger
{
public:
Logger();
static Logger& getInstance()
{
static Logger instance;
return instance;
}
void InitializeFileLogging(std::filesystem::path path);
void InitializeLoggingThread();
template<typename T>
void LogElement(T t)
{
if constexpr (std::is_same<char, T>::value)
{
char p = static_cast<char>(t);
if (p == '\n') std::cout << p; return;
}
std::cout << t;
}
// Basic log doesn't use the logthread so
// can be used before the thread is setup
// unless it is already ready
template<typename... Args>
void BasicLog(Args... args)
{
while (_IsLogging) {}
_IsLogging = true;
(LogElement(args), ...);
LogElement('\n');
_IsLogging = false;
}
void FastLog(std::string args)
{
if (!_IsRunning)
{
BasicLog(args);
return;
}
_QueueLock.lock();
_LogQueue.push(new LogEntity{ args, ELogType::NONE });
_QueueLock.unlock();
_TaskEnqueued.notify_one();
}
template<typename... Args>
void Log(Args... args)
{
if (!_IsRunning)
{
BasicLog(args...);
return;
}
std::stringstream s;
_FillStringStream(s, args...);
LogEntity* e = new LogEntity{ s.str(), ELogType::NONE };
_QueueLock.lock();
_LogQueue.push(e);
_QueueLock.unlock();
_TaskEnqueued.notify_one();
}
template<typename... Args>
void Info(Args... args)
{
if (!_IsRunning)
{
BasicLog("INFO: ", args...);
return;
}
_Log(ELogType::INFO, args...);
}
template<typename... Args>
void Debug(Args... args)
{
if (!_IsRunning)
{
BasicLog("DEBUG: ", args...);
return;
}
_Log(ELogType::DEBUG, args...);
}
template<typename... Args>
void Warn(Args... args)
{
if (!_IsRunning)
{
BasicLog("WARN: ", args...);
return;
}
_Log(ELogType::WARN, args...);
}
template<typename... Args>
void Error(Args... args)
{
if (!_IsRunning)
{
BasicLog("ERROR: ", args...);
return;
}
_Log(ELogType::ERR, args...);
}
template<typename... Args>
void Panic(Args... args)
{
if (!_IsRunning)
{
BasicLog("PANIC: ", args...);
exit(0);
return;
}
_Log(ELogType::PANIC, args...);
}
~Logger();
public:
std::atomic<bool> _IsRunning = false;
std::condition_variable _TaskEnqueued;
std::queue<LogEntity*> _LogQueue;
std::mutex _QueueLock;
std::atomic<bool> _IsLogging = false;
std::atomic<bool> _HasFileHandle = false;
std::ofstream _FileOutput;
private:
template <typename T, typename... A>
void _FillStringStream(std::stringstream& s, T head, A... a)
{
s << head;// << ' ';
if constexpr (sizeof...(a))
{
_FillStringStream(s, a...);
}
}
template<typename... Args>
void _Log(ELogType::Type type, Args... args)
{
std::stringstream s;
_FillStringStream(s, args...);
LogEntity* e = new LogEntity{ s.str(), type };
_QueueLock.lock();
_LogQueue.push(e);
_QueueLock.unlock();
_TaskEnqueued.notify_one();
}
std::thread* _OutputWorker;
};
class ScopedLogger
{
};
// times how long the scope took etc
class ProfileLogger : public ScopedLogger
{
};
#endif

View File

@@ -116,6 +116,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -128,8 +129,9 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -139,8 +141,13 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Logger.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Logger.hpp" />
<ClInclude Include="olcPixelGameEngine.hpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@@ -18,5 +18,16 @@
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="olcPixelGameEngine.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Logger.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

45276
The Great Machine/logs.log Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,79 @@
#include "Logger.hpp"
#define OLC_PGE_APPLICATION
#include "olcPixelGameEngine.hpp"
class Game : public olc::PixelGameEngine
{
public:
Logger& _Logger;
public:
Game()
: _Logger(Logger::getInstance())
{
sAppName = "Ben Kyd and The Great Machine";
}
bool OnUserCreate() override
{
return true;
}
void DisplayTitle(float fTime)
{
if (m_TimeAccumilator > 2.0f)
{
m_DeltaFade -= fTime * 200.0f;
if (m_DeltaFade < 0.1f) m_DeltaFade = 0.0f;
}
SetPixelMode(olc::Pixel::ALPHA);
DrawString((ScreenWidth() / 2) - (7 * 7) * (std::string("The Great Machine").length() / 2), ScreenHeight() / 2, "The Great Machine", olc::Pixel(255, 255, 255, static_cast<int>(m_DeltaFade)), 6);
DrawString(5, ScreenHeight() - 15, "Powered by the OLC Pixel Game Engine", olc::Pixel(255, 255, 255, static_cast<int>(m_DeltaFade)));
DrawString(ScreenWidth() - (8 * (std::string("Copyright Benjamin Kyd 2020").length())) - 5, ScreenHeight() - 15, "Copyright Benjamin Kyd 2020", olc::Pixel(255, 255, 255, static_cast<int>(m_DeltaFade)));
}
bool OnUserUpdate(float fTime) override
{
m_TimeAccumilator += fTime;
Clear(olc::BLACK);
_Logger.Debug(m_TimeAccumilator);
if (m_TimeAccumilator < 4.0f)
{
DisplayTitle(fTime);
return true;
}
return true;
}
private:
long float m_TimeAccumilator = 0;
float m_DeltaFade = 255.0f;
};
int main()
{
Logger& _Logger = Logger::getInstance();
_Logger.InitializeFileLogging("./logs.log");
_Logger.InitializeLoggingThread();
Game _Game;
_Game.Construct(1280, 720, 1, 1);
_Logger.Info("Game Constructed");
if (!_Game.Start())
{
_Logger.Panic("PGE Cannot start");
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.28919:TargetPlatformVersion=10.0.18362.0:
Debug|x64|C:\dev\projects\CodeJam2020\The Great Machine\|

Binary file not shown.

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>C:\dev\projects\CodeJam2020\The Great Machine\x64\Debug\The Great Machine.exe</ProjectOutputs>
<ContentFiles></ContentFiles>
<SatelliteDlls></SatelliteDlls>
<NonRecipeFileRefs></NonRecipeFileRefs>
</Project>

Binary file not shown.

View File

@@ -0,0 +1,4 @@
main.cpp
C:\dev\projects\CodeJam2020\The Great Machine\main.cpp(25,1): warning C4267: 'argument': conversion from 'size_t' to 'int32_t', possible loss of data
C:\dev\projects\CodeJam2020\The Great Machine\main.cpp(27,1): warning C4267: 'argument': conversion from 'size_t' to 'int32_t', possible loss of data
The Great Machine.vcxproj -> C:\dev\projects\CodeJam2020\The Great Machine\x64\Debug\The Great Machine.exe

Binary file not shown.

View File

@@ -0,0 +1,2 @@
C:\dev\projects\CodeJam2020\The Great Machine\x64\Debug\The Great Machine.exe
C:\dev\projects\CodeJam2020\The Great Machine\x64\Debug\The Great Machine.pdb

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,2 @@
PlatformToolSet=v142:VCToolArchitecture=Native32Bit:VCToolsVersion=14.27.28919:TargetPlatformVersion=10.0.18362.0:
Release|x64|C:\dev\projects\CodeJam2020\The Great Machine\|

Binary file not shown.

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<ProjectOutputs>C:\dev\projects\CodeJam2020\The Great Machine\x64\Release\The Great Machine.exe</ProjectOutputs>
<ContentFiles></ContentFiles>
<SatelliteDlls></SatelliteDlls>
<NonRecipeFileRefs></NonRecipeFileRefs>
</Project>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,10 @@
main.cpp
C:\dev\projects\CodeJam2020\The Great Machine\main.cpp(59,7): warning C4215: nonstandard extension used: long float
C:\dev\projects\CodeJam2020\The Great Machine\main.cpp(32,1): warning C4267: 'argument': conversion from 'size_t' to 'int32_t', possible loss of data
C:\dev\projects\CodeJam2020\The Great Machine\main.cpp(34,1): warning C4267: 'argument': conversion from 'size_t' to 'int32_t', possible loss of data
Generating code
2 of 1259 functions ( 0.2%) were compiled, the rest were copied from previous compilation.
0 functions were new in current compilation
1 functions had inline decision re-evaluated but remain unchanged
Finished generating code
The Great Machine.vcxproj -> C:\dev\projects\CodeJam2020\The Great Machine\x64\Release\The Great Machine.exe

Binary file not shown.

View File

@@ -0,0 +1 @@
C:\dev\projects\CodeJam2020\The Great Machine\x64\Release\The Great Machine.exe

Binary file not shown.

Binary file not shown.