mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 11:52:40 +01:00
Add new Logger system.
- Supports multiple log recievers. - Onscreen log needs to be re-written. - Replaces GameWorld::logX().
This commit is contained in:
parent
25f28dbb42
commit
536b3f9f0c
63
rwengine/include/core/Logger.hpp
Normal file
63
rwengine/include/core/Logger.hpp
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Handles and stores messages from different components
|
||||
*
|
||||
* Dispatches recieved messages to logger outputs.
|
||||
*/
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
enum MessageSeverity
|
||||
{
|
||||
Verbose,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
|
||||
struct LogMessage
|
||||
{
|
||||
/// The component that produced the message
|
||||
std::string component;
|
||||
/// Severity of the message.
|
||||
MessageSeverity severity;
|
||||
/// Logged message
|
||||
std::string message;
|
||||
|
||||
LogMessage(const std::string& cc,
|
||||
MessageSeverity ss,
|
||||
const std::string& mm)
|
||||
: component(cc), severity(ss), message(mm) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for handling logged messages.
|
||||
*
|
||||
* The Logger class will not clean up allocated MessageRecievers.
|
||||
*/
|
||||
struct MessageReciever
|
||||
{
|
||||
virtual void messageRecieved(const LogMessage&) = 0;
|
||||
};
|
||||
|
||||
void addReciever(MessageReciever* out);
|
||||
void removeReciever(MessageReciever* out);
|
||||
|
||||
void log(const std::string& component, Logger::MessageSeverity severity, const std::string& message);
|
||||
|
||||
void verbose(const std::string& component, const std::string& message);
|
||||
void info(const std::string& component, const std::string& message);
|
||||
void warning(const std::string& component, const std::string& message);
|
||||
void error(const std::string& component, const std::string& message);
|
||||
private:
|
||||
std::vector<MessageReciever*> recievers;
|
||||
};
|
||||
|
||||
class StdOutReciever : public Logger::MessageReciever
|
||||
{
|
||||
virtual void messageRecieved(const Logger::LogMessage&);
|
||||
};
|
@ -2,6 +2,8 @@
|
||||
#ifndef _GAMEWORLD_HPP_
|
||||
#define _GAMEWORLD_HPP_
|
||||
|
||||
#include <core/Logger.hpp>
|
||||
|
||||
#include <engine/GameData.hpp>
|
||||
#include <engine/GameState.hpp>
|
||||
#include <render/GameRenderer.hpp>
|
||||
@ -77,22 +79,7 @@ public:
|
||||
std::string message;
|
||||
};
|
||||
|
||||
std::deque<LogEntry> log;
|
||||
|
||||
/**
|
||||
* Displays an informative message
|
||||
*/
|
||||
void logInfo(const std::string& info);
|
||||
|
||||
/**
|
||||
* Displays an alarming error
|
||||
*/
|
||||
void logError(const std::string& error);
|
||||
|
||||
/**
|
||||
* Displays a comforting warning
|
||||
*/
|
||||
void logWarning(const std::string& warning);
|
||||
Logger logger;
|
||||
|
||||
/**
|
||||
* Loads an IDE into the game
|
||||
|
59
rwengine/src/core/Logger.cpp
Normal file
59
rwengine/src/core/Logger.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include <core/Logger.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
void Logger::log(const std::string& component, Logger::MessageSeverity severity, const std::string& message)
|
||||
{
|
||||
LogMessage m { component, severity, message };
|
||||
|
||||
for(MessageReciever* r : recievers)
|
||||
{
|
||||
r->messageRecieved( m );
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::addReciever(Logger::MessageReciever* out)
|
||||
{
|
||||
recievers.push_back(out);
|
||||
}
|
||||
|
||||
void Logger::removeReciever(Logger::MessageReciever* out)
|
||||
{
|
||||
recievers.erase(std::remove(recievers.begin(), recievers.end(), out), recievers.end());
|
||||
}
|
||||
|
||||
void Logger::error(const std::string& component, const std::string& message)
|
||||
{
|
||||
log(component, Logger::Error, message);
|
||||
}
|
||||
|
||||
void Logger::info(const std::string& component, const std::string& message)
|
||||
{
|
||||
log(component, Logger::Info, message);
|
||||
}
|
||||
|
||||
void Logger::warning(const std::string& component, const std::string& message)
|
||||
{
|
||||
log(component, Logger::Warning, message);
|
||||
}
|
||||
|
||||
void Logger::verbose(const std::string& component, const std::string& message)
|
||||
{
|
||||
log(component, Logger::Verbose, message);
|
||||
}
|
||||
|
||||
std::map<Logger::MessageSeverity, char> severityStr {
|
||||
{Logger::Error, 'E'},
|
||||
{Logger::Warning, 'W'},
|
||||
{Logger::Info, 'I'},
|
||||
{Logger::Verbose, 'V'}
|
||||
};
|
||||
|
||||
void StdOutReciever::messageRecieved(const Logger::LogMessage& message)
|
||||
{
|
||||
std::cout << severityStr[message.severity] << " [" << message.component << "] " << message.message << std::endl;
|
||||
}
|
||||
|
||||
|
@ -600,10 +600,7 @@ char* GameData::openFile(const std::string& name)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream err;
|
||||
err << "Unable to locate file " << name;
|
||||
engine->logError(err.str());
|
||||
std::cerr << err.str() << std::endl;
|
||||
engine->logger.error("Data", "Unable to locate file: " + name);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -654,10 +651,7 @@ FileHandle GameData::openFile2(const std::string &name)
|
||||
}
|
||||
else
|
||||
{
|
||||
std::stringstream err;
|
||||
err << "Unable to locate file " << name;
|
||||
engine->logError(err.str());
|
||||
std::cerr << err.str() << std::endl;
|
||||
engine->logger.error("Data", "Unable to locate file: " + name);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -117,22 +117,6 @@ bool GameWorld::load()
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameWorld::logInfo(const std::string& info)
|
||||
{
|
||||
log.push_back({LogEntry::Info, gameTime, info});
|
||||
std::cout << info << std::endl;
|
||||
}
|
||||
|
||||
void GameWorld::logError(const std::string& error)
|
||||
{
|
||||
log.push_back({LogEntry::Error, gameTime, error});
|
||||
}
|
||||
|
||||
void GameWorld::logWarning(const std::string& warning)
|
||||
{
|
||||
log.push_back({LogEntry::Warning, gameTime, warning});
|
||||
}
|
||||
|
||||
bool GameWorld::defineItems(const std::string& name)
|
||||
{
|
||||
auto i = gameData.ideLocations.find(name);
|
||||
@ -185,7 +169,7 @@ void GameWorld::runScript(const std::string &name)
|
||||
script = new ScriptMachine(this, f, opcodes);
|
||||
}
|
||||
else {
|
||||
logError("Failed to load SCM: " + name);
|
||||
logger.error("World", "Failed to load SCM: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,7 +251,7 @@ InstanceObject *GameWorld::createInstance(const uint16_t id, const glm::vec3& po
|
||||
}
|
||||
|
||||
if( modelname.empty() ) {
|
||||
logWarning("Instance with missing model: " + std::to_string(id));
|
||||
logger.warning("World", "Instance with missing model: " + std::to_string(id));
|
||||
}
|
||||
|
||||
auto instance = new InstanceObject(
|
||||
@ -428,7 +412,7 @@ VehicleObject *GameWorld::createVehicle(const uint16_t id, const glm::vec3& pos,
|
||||
sec = gameData.vehicleColours[palit->second[set].second];
|
||||
}
|
||||
else {
|
||||
logWarning("No colour palette for vehicle " + vti->modelName);
|
||||
logger.warning("World", "No colour palette for vehicle " + vti->modelName);
|
||||
}
|
||||
|
||||
auto wi = findObjectType<ObjectData>(vti->wheelModelID);
|
||||
|
@ -82,7 +82,7 @@ GameRenderer::GameRenderer(GameWorld* engine)
|
||||
: engine(engine), renderer(new OpenGLRenderer), _renderAlpha(0.f),
|
||||
map(engine, renderer), text(engine, this)
|
||||
{
|
||||
engine->logInfo("[DRAW] " + renderer->getIDString());
|
||||
engine->logger.info("Renderer", renderer->getIDString());
|
||||
|
||||
worldProg = renderer->createShader(
|
||||
GameShaders::WorldObject::VertexShader,
|
||||
|
38
rwengine/tests/test_Logger.cpp
Normal file
38
rwengine/tests/test_Logger.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <core/Logger.hpp>
|
||||
#include <test_globals.hpp>
|
||||
|
||||
class CallbackReceiver : public Logger::MessageReciever
|
||||
{
|
||||
public:
|
||||
std::function<void(const Logger::LogMessage&)> func;
|
||||
|
||||
CallbackReceiver(std::function<void(const Logger::LogMessage&)> func)
|
||||
: func(func) { }
|
||||
|
||||
virtual void messageRecieved(const Logger::LogMessage& message)
|
||||
{
|
||||
func(message);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(LoggerTests)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_reciever)
|
||||
{
|
||||
Logger log;
|
||||
|
||||
Logger::LogMessage lastMessage("", Logger::Error, "");
|
||||
|
||||
CallbackReceiver reciever([&](const Logger::LogMessage& m) { lastMessage = m; });
|
||||
|
||||
log.addReciever(&reciever);
|
||||
|
||||
log.info("Tests", "Test");
|
||||
|
||||
BOOST_CHECK_EQUAL( lastMessage.component, "Tests" );
|
||||
BOOST_CHECK_EQUAL( lastMessage.severity, Logger::Info );
|
||||
BOOST_CHECK_EQUAL( lastMessage.message, "Test" );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
@ -17,6 +17,8 @@
|
||||
|
||||
DebugDraw* debug;
|
||||
|
||||
StdOutReciever logPrinter;
|
||||
|
||||
RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
|
||||
: engine(nullptr), inFocus(true), showDebugStats(false),
|
||||
accum(0.f), timescale(1.f)
|
||||
@ -57,6 +59,7 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
|
||||
glewInit();
|
||||
|
||||
engine = new GameWorld(gamepath);
|
||||
engine->logger.addReciever(&logPrinter);
|
||||
|
||||
// Initalize all the archives.
|
||||
engine->gameData.loadIMG("/models/gta3");
|
||||
@ -88,7 +91,7 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[])
|
||||
|
||||
StateManager::get().enter(new LoadingState(this));
|
||||
|
||||
engine->logInfo("Started");
|
||||
engine->logger.info("Game", "Started");
|
||||
}
|
||||
|
||||
RWGame::~RWGame()
|
||||
@ -202,7 +205,7 @@ void RWGame::tick(float dt)
|
||||
}
|
||||
catch( SCMException& ex ) {
|
||||
std::cerr << ex.what() << std::endl;
|
||||
engine->logError( ex.what() );
|
||||
engine->logger.error( "Script", ex.what() );
|
||||
throw;
|
||||
}
|
||||
}
|
||||
@ -354,7 +357,7 @@ void RWGame::renderDebugStats(float time)
|
||||
ti.size = 15.f;
|
||||
engine->renderer.text.renderText(ti);
|
||||
|
||||
while( engine->log.size() > 0 && engine->log.front().time + 10.f < engine->gameTime ) {
|
||||
/*while( engine->log.size() > 0 && engine->log.front().time + 10.f < engine->gameTime ) {
|
||||
engine->log.pop_front();
|
||||
}
|
||||
|
||||
@ -380,7 +383,7 @@ void RWGame::renderDebugStats(float time)
|
||||
|
||||
engine->renderer.text.renderText(ti);
|
||||
ti.screenPosition.y -= ti.size;
|
||||
}
|
||||
}*/
|
||||
|
||||
for( int i = 0; i < engine->state.text.size(); )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user