Rename Logger class to DefaultLogger and create abstract Logger class

This commit is contained in:
Daniel Chappuis 2020-04-26 18:41:59 +02:00
parent dcd71ef103
commit e03ee08462
14 changed files with 632 additions and 485 deletions

View File

@ -59,6 +59,8 @@
- The RigidBody::recomputeMassInformation() method has been renamed to RigidBody::updateMassPropertiesFromColliders.
- Now, you need to manually call the RigidBody::recomputeMassInformation() method after adding colliders to a rigid body to recompute its inertia tensor, center of mass and mass
- The rendering in the testbed application has been improved
- The old Logger class has been renamed to DefaultLogger
- The Logger class is now an abstract class that you can inherit from in order to receive log events from the library
### Removed

View File

@ -180,6 +180,7 @@ SET (REACTPHYSICS3D_HEADERS
"include/reactphysics3d/containers/Deque.h"
"include/reactphysics3d/utils/Profiler.h"
"include/reactphysics3d/utils/Logger.h"
"include/reactphysics3d/utils/DefaultLogger.h"
)
# Source files
@ -269,7 +270,7 @@ SET (REACTPHYSICS3D_SOURCES
"src/memory/HeapAllocator.cpp"
"src/memory/MemoryManager.cpp"
"src/utils/Profiler.cpp"
"src/utils/Logger.cpp"
"src/utils/DefaultLogger.cpp"
)
# Create the library

View File

@ -256,7 +256,7 @@ inline void Collider::setMaterial(const Material& material) {
#ifdef IS_LOGGING_ACTIVE
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider " + std::to_string(mEntity.id) + ": Set Material" + mMaterial.to_string());
"Collider " + std::to_string(mEntity.id) + ": Set Material" + mMaterial.to_string(), __FILE__, __LINE__);
#endif
}

View File

@ -44,6 +44,15 @@ class EventListener : public CollisionCallback {
public :
enum class ErrorType {
Warning,
InvalidParameter,
InvalidOperation,
InternalError
};
// ---------- Methods ---------- //
/// Constructor
EventListener() = default;
@ -52,15 +61,15 @@ class EventListener : public CollisionCallback {
/// Called when some contacts occur
/**
* @param collisionInfo Information about the contacts
* @param callbackData Contains information about all the contacts
*/
virtual void onContact(const CollisionCallback::CallbackData& callbackData) override {}
/// Called when some trigger events occur
/**
* @param callbackData Contains information about all the triggers that are colliding
*/
virtual void onTrigger(const OverlapCallback::CallbackData& callbackData) {}
/// Called to report rigid bodies that started to sleep or has woken up in the previous frame
virtual void onSleep() {}
};
}

View File

@ -36,6 +36,7 @@
#include <reactphysics3d/collision/shapes/ConvexMeshShape.h>
#include <reactphysics3d/collision/shapes/ConcaveMeshShape.h>
#include <reactphysics3d/collision/TriangleMesh.h>
#include <reactphysics3d/utils/DefaultLogger.h>
/// ReactPhysics3D namespace
namespace reactphysics3d {
@ -82,8 +83,12 @@ class PhysicsCommon {
/// Set of triangle meshes
Set<TriangleMesh*> mTriangleMeshes;
#ifdef IS_LOGGING_ACTIVE
/// Set of loggers
Set<Logger*> mLoggers;
Set<DefaultLogger*> mLoggers;
#endif
/// Set of loggers
Set<Profiler*> mProfilers;
@ -170,11 +175,11 @@ class PhysicsCommon {
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
/// Create and return a new logger
Logger* createLogger();
/// Create and return a new default logger
DefaultLogger* createDefaultLogger();
/// Destroy a logger
void destroyLogger(Logger* logger);
/// Destroy a default logger
void destroyDefaultLogger(DefaultLogger* logger);
#endif

View File

@ -618,10 +618,11 @@ inline uint PhysicsWorld::getNbIterationsVelocitySolver() const {
* @param nbIterations Number of iterations for the velocity solver
*/
inline void PhysicsWorld::setNbIterationsVelocitySolver(uint nbIterations) {
mNbVelocitySolverIterations = nbIterations;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Set nb iterations velocity solver to " + std::to_string(nbIterations));
"Physics World: Set nb iterations velocity solver to " + std::to_string(nbIterations), __FILE__, __LINE__);
}
// Get the number of iterations for the position constraint solver
@ -637,10 +638,11 @@ inline uint PhysicsWorld::getNbIterationsPositionSolver() const {
* @param nbIterations Number of iterations for the position solver
*/
inline void PhysicsWorld::setNbIterationsPositionSolver(uint nbIterations) {
mNbPositionSolverIterations = nbIterations;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Set nb iterations position solver to " + std::to_string(nbIterations));
"Physics World: Set nb iterations position solver to " + std::to_string(nbIterations), __FILE__, __LINE__);
}
// Set the position correction technique used for contacts
@ -688,7 +690,7 @@ inline void PhysicsWorld::setGravity(Vector3& gravity) {
mConfig.gravity = gravity;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Set gravity vector to " + gravity.to_string());
"Physics World: Set gravity vector to " + gravity.to_string(), __FILE__, __LINE__);
}
// Return if the gravity is enaled
@ -708,7 +710,7 @@ inline void PhysicsWorld::setIsGratityEnabled(bool isGravityEnabled) {
mIsGravityEnabled = isGravityEnabled;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false")));
"Physics World: isGravityEnabled= " + (isGravityEnabled ? std::string("true") : std::string("false")), __FILE__, __LINE__);
}
// Return true if the sleeping technique is enabled
@ -739,7 +741,7 @@ inline void PhysicsWorld::setSleepLinearVelocity(decimal sleepLinearVelocity) {
mSleepLinearVelocity = sleepLinearVelocity;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity));
"Physics World: sleepLinearVelocity= " + std::to_string(sleepLinearVelocity), __FILE__, __LINE__);
}
// Return the current sleep angular velocity
@ -762,7 +764,7 @@ inline void PhysicsWorld::setSleepAngularVelocity(decimal sleepAngularVelocity)
mSleepAngularVelocity = sleepAngularVelocity;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity));
"Physics World: sleepAngularVelocity= " + std::to_string(sleepAngularVelocity), __FILE__, __LINE__);
}
// Return the time a body is required to stay still before sleeping
@ -782,7 +784,7 @@ inline void PhysicsWorld::setTimeBeforeSleep(decimal timeBeforeSleep) {
mTimeBeforeSleep = timeBeforeSleep;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep));
"Physics World: timeBeforeSleep= " + std::to_string(timeBeforeSleep), __FILE__, __LINE__);
}
// Set an event listener object to receive events callbacks.

View File

@ -0,0 +1,495 @@
/********************************************************************************
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
* Copyright (c) 2010-2019 Daniel Chappuis *
*********************************************************************************
* *
* This software is provided 'as-is', without any express or implied warranty. *
* In no event will the authors be held liable for any damages arising from the *
* use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute it *
* freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must not claim *
* that you wrote the original software. If you use this software in a *
* product, an acknowledgment in the product documentation would be *
* appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must not be *
* misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source distribution. *
* *
********************************************************************************/
#ifndef REACTPHYSICS3D_DEFAULT_LOGGER_H
#define REACTPHYSICS3D_DEFAULT_LOGGER_H
// If logging is enabled
#ifdef IS_LOGGING_ACTIVE
// Libraries
#include <reactphysics3d/utils/Logger.h>
#include <reactphysics3d/containers/List.h>
#include <reactphysics3d/containers/Map.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <mutex>
/// ReactPhysics3D namespace
namespace reactphysics3d {
// Class Logger
/**
* This class is the default logger class used to log information, warnings
* or errors during the execution of the library code for easier debugging.
*/
class DefaultLogger : public Logger {
public:
/// Log verbosity level
enum class Format {Text, HTML};
/// Log formatter
class Formatter {
public:
/// Constructor
Formatter() {
}
/// Destructor
virtual ~Formatter() {
}
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const {
return "";
}
/// Return the tail to write at the end of the stream
virtual std::string getTail() const {
return "";
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message, Level level, Category category,
const char* filename, int lineNumber) = 0;
};
class TextFormatter : public Formatter {
public:
/// Constructor
TextFormatter() {
}
/// Destructor
virtual ~TextFormatter() override {
}
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const override {
// Get current date
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << "ReactPhysics3D Logs" << std::endl;
ss << "ReactPhysics3D Version: " << RP3D_VERSION << std::endl;
ss << "Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << std::endl;
ss << "---------------------------------------------------------" << std::endl;
return ss.str();
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message,
Level level, Category category, const char* filename, int lineNumber) override {
std::stringstream ss;
// Time
ss << std::put_time(std::localtime(&time), "%X") << " ";
// Level
ss << getLevelName(level) << " ";
// Category
ss << getCategoryName(category) << " ";
// Message
ss << message << std::endl;
// Filename
ss << " (in file " << std::string(filename);
// Line number
ss << " at line " << std::to_string(lineNumber) << ")";
return ss.str();
}
};
class HtmlFormatter : public Formatter {
private:
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const override {
// Get current date
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << "<!DOCTYPE HTML>" << std::endl;
ss << "<html>" << std::endl;
ss << "<head>" << std::endl;
ss << "<title>ReactPhysics3D Logs</title>" << std::endl;
ss << "<style>" << generateCSS() << "</style>" << std::endl;
ss << "</head>" << std::endl;
ss << "<body>" << std::endl;
ss << "<h1>ReactPhysics3D Logs</h1>" << std::endl;
ss << "<div class='general_info'>" << std::endl;
ss << "<p>ReactPhysics3D version: " << RP3D_VERSION << "</p>" << std::endl;
ss << "<p>Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << "</p>" << std::endl;
ss << "</div>" << std::endl;
ss << "<hr>";
return ss.str();
}
/// Return the tail to write at the end of the stream
virtual std::string getTail() const override {
std::stringstream ss;
ss << "</body>" << std::endl;
ss << "</html>" << std::endl;
return ss.str();
}
std::string generateCSS() const {
return "body {"
" background-color: #e6e6e6;"
" font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; "
"} "
"body > div { clear:both; } "
"body > div > div { float: left; } "
"h1 {"
" margin: 5px 5px 5px 5px;"
"} "
".general_info > p {"
"margin: 5px;"
"font-weight: bold;"
"} "
".line { "
"font-size: 13px; "
"color: #212529; "
"margin: 5px 5px 5px 5px; "
"padding: 5px 0px 5px 0px; "
"} "
".time { "
"margin-right: 20px; "
"width: 10%; "
"} "
".level { "
"margin-right: 20px; "
"width: 10%; "
"}"
".category { "
"margin-right: 20px; "
"width: 10%; "
"font-weight: bold; "
"}"
".message { "
"margin-right: 20px; "
"color: #2e2e2e; "
"word-wrap: break-word; "
"width: 40%; "
"} "
".file { "
"margin-right: 20px; "
"word-wrap: break-word; "
"width: 20%; "
"}"
".body > .category, .body > .message { "
"color: #00994d;"
"} "
".world > .category, .world > .message { "
"color: #3477DB; "
"} "
".joint .category, .joint > .message { "
"color: #bf8040; "
"} "
".collider .category, .collider > .message { "
"color: #9933ff; "
"} "
".warning { "
"color: #ff9900 !important; "
"} "
".error { "
"color: red !important; "
"} ";
}
/// Convert a string to lower case
std::string toLowerCase(const std::string& text) {
std::string textLower = text;
std::transform(textLower.begin(), textLower.end(), textLower.begin(), ::tolower);
return textLower;
}
public:
/// Constructor
HtmlFormatter() {
}
/// Destructor
virtual ~HtmlFormatter() override {
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message, Level level,
Category category, const char* filename, int lineNumber) override {
std::stringstream ss;
ss << "<div class='line " + toLowerCase(getCategoryName(category)) + " " + toLowerCase(getLevelName(level)) + "'>";
// Time
ss << "<div class='time'>";
ss << std::put_time(std::localtime(&time), "%X");
ss << "</div>";
// Level
ss << "<div class='level'>";
ss << getLevelName(level);
ss << "</div>";
// Category
ss << "<div class='category'>";
ss << getCategoryName(category);
ss << "</div>";
// Message
ss << "<div class='message " << toLowerCase(getCategoryName(category)) <<
" " + toLowerCase(getLevelName(level)) << "'>" << std::endl;
ss << message;
ss << "</div>";
// Filename + line number
ss << "<div class='file'> (in file " << std::string(filename) <<
" at line " << std::to_string(lineNumber) << ")" << std::endl;
ss << "</div>";
ss << "</div>";
return ss.str();
}
};
/// Log destination
class Destination {
public:
/// Maximum Log level flag for this destination
uint maxLevelFlag;
/// Pointer to the formatter
Formatter* formatter;
/// Constructor
Destination(uint maxLevelFlag, Formatter* logFormatter)
: maxLevelFlag(maxLevelFlag), formatter(logFormatter) {
}
/// Destructor
virtual ~Destination() {
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category, const char* filename, int lineNumber) = 0;
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const=0;
};
class FileDestination : public Destination {
private:
std::string mFilePath;
/// Output file stream
std::ofstream mFileStream;
public:
/// Constructor
FileDestination(const std::string& filePath, uint maxLevelFlag, Formatter* formatter)
:Destination(maxLevelFlag, formatter), mFilePath(filePath),
mFileStream(filePath, std::ios::binary) {
if(!mFileStream.is_open()) {
throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath));
}
// Writer the head
mFileStream << formatter->getHeader() << std::endl;
}
/// Destructor
virtual ~FileDestination() override {
// Writer the tail
mFileStream << formatter->getTail() << std::endl;
if (mFileStream.is_open()) {
// Close the stream
mFileStream.close();
}
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category,
const char* filename, int lineNumber) override {
if (static_cast<int>(level) <= static_cast<int>(maxLevelFlag)) {
mFileStream << formatter->format(time, message, level, category, filename, lineNumber) << std::endl << std::flush;
}
}
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const override {
return sizeof(FileDestination);
}
};
/// Stream destination to output the logs into a stream
class StreamDestination : public Destination {
private:
/// Output stream
std::ostream& mOutputStream;
public:
/// Constructor
StreamDestination(std::ostream& outputStream, uint maxlevelFlag, Formatter* formatter)
:Destination(maxlevelFlag, formatter), mOutputStream(outputStream) {
// Writer the head
mOutputStream << formatter->getHeader() << std::endl;
}
/// Destructor
virtual ~StreamDestination() override {
// Writer the tail
mOutputStream << formatter->getTail() << std::endl;
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category,
const char* filename, int lineNumber) override {
if (static_cast<int>(level) <= static_cast<int>(maxLevelFlag)) {
mOutputStream << formatter->format(time, message, level, category, filename, lineNumber) << std::endl << std::flush;
}
}
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const override {
return sizeof(StreamDestination);
}
};
protected:
// -------------------- Attributes -------------------- //
/// Memory allocator
MemoryAllocator& mAllocator;
/// All the log destinations
List<Destination*> mDestinations;
/// Map a log format to the given formatter object
Map<Format, Formatter*> mFormatters;
/// Mutex
std::mutex mMutex;
// -------------------- Methods -------------------- //
/// Return the corresponding formatter
Formatter* getFormatter(Format format) const;
/// Constructor
DefaultLogger(MemoryAllocator& allocator);
/// Destructor
virtual ~DefaultLogger() override;
public :
// -------------------- Methods -------------------- //
/// Add a file destination to the logger
void addFileDestination(const std::string& filePath, uint logLevelFlag, Format format);
/// Add a stream destination to the logger
void addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format);
/// Remove all logs destination previously set
void removeAllDestinations();
/// Log something
virtual void log(Level level, Category category, const std::string& message, const char* filename, int lineNumber) override;
// ---------- Friendship ---------- //
friend class PhysicsCommon;
};
}
// Hash function for struct VerticesPair
namespace std {
template<> struct hash<reactphysics3d::DefaultLogger::Format> {
size_t operator()(const reactphysics3d::DefaultLogger::Format format) const {
return static_cast<size_t>(format);
}
};
}
#endif
#endif

View File

@ -34,17 +34,13 @@
#include <reactphysics3d/containers/Map.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <mutex>
/// ReactPhysics3D namespace
namespace reactphysics3d {
// Class Logger
/**
* This class is used to log information, warnings or errors during the execution of the
* This abstract class is the base class used to log information, warnings or errors during the execution of the
* library code for easier debugging.
*/
class Logger {
@ -57,9 +53,6 @@ class Logger {
/// Log categories
enum class Category {World, Body, Joint, Collider};
/// Log verbosity level
enum class Format {Text, HTML};
/// Return the name of a category
static std::string getCategoryName(Category category) {
@ -87,394 +80,18 @@ class Logger {
return "";
}
/// Log formatter
class Formatter {
public:
/// Constructor
Formatter() {
}
/// Destructor
virtual ~Formatter() {
}
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const {
return "";
}
/// Return the tail to write at the end of the stream
virtual std::string getTail() const {
return "";
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message, Level level, Category category) = 0;
};
class TextFormatter : public Formatter {
public:
/// Constructor
TextFormatter() {
}
/// Destructor
virtual ~TextFormatter() override {
}
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const override {
// Get current date
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << "ReactPhysics3D Logs" << std::endl;
ss << "ReactPhysics3D Version: " << RP3D_VERSION << std::endl;
ss << "Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << std::endl;
ss << "---------------------------------------------------------" << std::endl;
return ss.str();
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message,
Level level, Category category) override {
std::stringstream ss;
// Time
ss << std::put_time(std::localtime(&time), "%X") << " ";
// Level
ss << getLevelName(level) << " ";
// Category
ss << getCategoryName(category) << " ";
// Message
ss << message << std::endl;
return ss.str();
}
};
class HtmlFormatter : public Formatter {
private:
/// Return the header to write at the beginning of the stream
virtual std::string getHeader() const override {
// Get current date
auto now = std::chrono::system_clock::now();
auto time = std::chrono::system_clock::to_time_t(now);
std::stringstream ss;
ss << "<!DOCTYPE HTML>" << std::endl;
ss << "<html>" << std::endl;
ss << "<head>" << std::endl;
ss << "<title>ReactPhysics3D Logs</title>" << std::endl;
ss << "<style>" << generateCSS() << "</style>" << std::endl;
ss << "</head>" << std::endl;
ss << "<body>" << std::endl;
ss << "<h1>ReactPhysics3D Logs</h1>" << std::endl;
ss << "<div class='general_info'>" << std::endl;
ss << "<p>ReactPhysics3D version: " << RP3D_VERSION << "</p>" << std::endl;
ss << "<p>Date: " << std::put_time(std::localtime(&time), "%Y-%m-%d") << "</p>" << std::endl;
ss << "</div>" << std::endl;
ss << "<hr>";
return ss.str();
}
/// Return the tail to write at the end of the stream
virtual std::string getTail() const override {
std::stringstream ss;
ss << "</body>" << std::endl;
ss << "</html>" << std::endl;
return ss.str();
}
std::string generateCSS() const {
return "body {"
" background-color: #e6e6e6;"
" font-family: SFMono-Regular,Menlo,Monaco,Consolas,'Liberation Mono','Courier New',monospace; "
"} "
"body > div { clear:both; } "
"body > div > div { float: left; } "
"h1 {"
" margin: 5px 5px 5px 5px;"
"} "
".general_info > p {"
"margin: 5px;"
"font-weight: bold;"
"} "
".line { "
"font-size: 13px; "
"color: #212529; "
"margin: 0px 5px 2px 5px; "
"} "
".time { "
"margin-right: 20px; "
"width:80px; "
"} "
".level { "
"margin-right: 20px; "
"width: 90px; "
"}"
".category { "
"margin-right: 20px; "
"width: 100px; "
"font-weight: bold; "
"}"
".message { "
"color: #2e2e2e; "
"word-wrap: break-word; "
"max-width: 800px; "
"} "
".body > .category, .body > .message { "
"color: #00994d;"
"} "
".world > .category, .world > .message { "
"color: #3477DB; "
"} "
".joint .category, .joint > .message { "
"color: #bf8040; "
"} "
".collider .category, .collider > .message { "
"color: #9933ff; "
"} "
".warning { "
"color: #ff9900 !important; "
"} "
".error { "
"color: red !important; "
"} ";
}
/// Convert a string to lower case
std::string toLowerCase(const std::string& text) {
std::string textLower = text;
std::transform(textLower.begin(), textLower.end(), textLower.begin(), ::tolower);
return textLower;
}
public:
/// Constructor
HtmlFormatter() {
}
/// Destructor
virtual ~HtmlFormatter() override {
}
/// Format a log message
virtual std::string format(const time_t& time, const std::string& message,
Level level, Category category) override {
std::stringstream ss;
ss << "<div class='line " + toLowerCase(getCategoryName(category)) + " " + toLowerCase(getLevelName(level)) + "'>";
// Time
ss << "<div class='time'>";
ss << std::put_time(std::localtime(&time), "%X");
ss << "</div>";
// Level
ss << "<div class='level'>";
ss << getLevelName(level);
ss << "</div>";
// Category
ss << "<div class='category'>";
ss << getCategoryName(category);
ss << "</div>";
// Message
ss << "<div class='message " << toLowerCase(getCategoryName(category)) <<
" " + toLowerCase(getLevelName(level)) << "'>" << std::endl;
ss << message;
ss << "</div>";
ss << "</div>";
return ss.str();
}
};
/// Log destination
class Destination {
public:
/// Log level flag for this destination
uint levelFlag;
/// Pointer to the formatter
Formatter* formatter;
/// Constructor
Destination(uint levelFlag, Formatter* logFormatter)
: levelFlag(levelFlag), formatter(logFormatter) {
}
/// Destructor
virtual ~Destination() {
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category) = 0;
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const=0;
};
class FileDestination : public Destination {
private:
std::string mFilePath;
/// Output file stream
std::ofstream mFileStream;
public:
/// Constructor
FileDestination(const std::string& filePath, uint levelFlag, Formatter* formatter)
:Destination(levelFlag, formatter), mFilePath(filePath),
mFileStream(filePath, std::ios::binary) {
if(!mFileStream.is_open()) {
throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath));
}
// Writer the head
mFileStream << formatter->getHeader() << std::endl;
}
/// Destructor
virtual ~FileDestination() override {
// Writer the tail
mFileStream << formatter->getTail() << std::endl;
if (mFileStream.is_open()) {
// Close the stream
mFileStream.close();
}
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
mFileStream << formatter->format(time, message, level, category) << std::endl << std::flush;
}
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const override {
return sizeof(FileDestination);
}
};
/// Stream destination to output the logs into a stream
class StreamDestination : public Destination {
private:
/// Output stream
std::ostream& mOutputStream;
public:
/// Constructor
StreamDestination(std::ostream& outputStream, uint levelFlag, Formatter* formatter)
:Destination(levelFlag, formatter), mOutputStream(outputStream) {
// Writer the head
mOutputStream << formatter->getHeader() << std::endl;
}
/// Destructor
virtual ~StreamDestination() override {
// Writer the tail
mOutputStream << formatter->getTail() << std::endl;
}
/// Write a message into the output stream
virtual void write(const time_t& time, const std::string& message, Level level, Category category) override {
mOutputStream << formatter->format(time, message, level, category) << std::endl << std::flush;
}
/// Return the size in bytes of the type
virtual size_t getSizeBytes() const override {
return sizeof(StreamDestination);
}
};
private:
// -------------------- Attributes -------------------- //
/// Memory allocator
MemoryAllocator& mAllocator;
/// All the log destinations
List<Destination*> mDestinations;
/// Map a log format to the given formatter object
Map<Format, Formatter*> mFormatters;
/// Mutex
std::mutex mMutex;
// -------------------- Methods -------------------- //
/// Return the corresponding formatter
Formatter* getFormatter(Format format) const;
/// Constructor
Logger(MemoryAllocator& allocator);
/// Destructor
~Logger();
public :
// -------------------- Methods -------------------- //
/// Add a file destination to the logger
void addFileDestination(const std::string& filePath, uint logLevelFlag, Format format);
/// Constructor
Logger() = default;
/// Add a stream destination to the logger
void addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format);
/// Remove all logs destination previously set
void removeAllDestinations();
/// Destructor
virtual ~Logger() = default;
/// Log something
void log(Level level, Category category, const std::string& message);
virtual void log(Level level, Category category, const std::string& message, const char* filename, int lineNumber)=0;
// ---------- Friendship ---------- //
@ -483,26 +100,14 @@ class Logger {
}
// Hash function for struct VerticesPair
namespace std {
template<> struct hash<reactphysics3d::Logger::Format> {
size_t operator()(const reactphysics3d::Logger::Format format) const {
return static_cast<size_t>(format);
}
};
}
// Use this macro to log something
#define RP3D_LOG(logger, level, category, message) logger->log(level, category, message)
#define RP3D_LOG(logger, level, category, message, filename, lineNumber) logger->log(level, category, message, filename, lineNumber)
// If the logging is not enabled
#else
// Empty macro in case logs are not enabled
#define RP3D_LOG(logger, level, category, message)
#define RP3D_LOG(logger, level, category, message, filename, lineNumber)
#endif

View File

@ -117,11 +117,11 @@ Collider* CollisionBody::addCollider(CollisionShape* collisionShape, const Trans
mWorld.mCollisionDetection.addCollider(collider, aabb);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body");
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body", __FILE__, __LINE__);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider " + std::to_string(collider->getBroadPhaseId()) + ": collisionShape=" +
collider->getCollisionShape()->to_string());
collider->getCollisionShape()->to_string(), __FILE__, __LINE__);
// Return a pointer to the collision shape
return collider;
@ -171,7 +171,7 @@ Collider* CollisionBody::getCollider(uint colliderIndex) {
void CollisionBody::removeCollider(Collider* collider) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " removed from body");
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " removed from body", __FILE__, __LINE__);
// Remove the collider from the broad-phase
if (collider->getBroadPhaseId() != -1) {
@ -283,7 +283,7 @@ void CollisionBody::setIsActive(bool isActive) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isActive=" +
(isActive ? "true" : "false"));
(isActive ? "true" : "false"), __FILE__, __LINE__);
}
// Ask the broad-phase to test again the collision shapes of the body for collision
@ -399,7 +399,7 @@ void CollisionBody::setTransform(const Transform& transform) {
updateBroadPhaseState(0);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set transform=" + transform.to_string());
"Body " + std::to_string(mEntity.id) + ": Set transform=" + transform.to_string(), __FILE__, __LINE__);
}
// Return true if the body is active

View File

@ -116,7 +116,7 @@ void RigidBody::setType(BodyType type) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set type=" +
(type == BodyType::STATIC ? "Static" : (type == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")));
(type == BodyType::STATIC ? "Static" : (type == BodyType::DYNAMIC ? "Dynamic" : "Kinematic")), __FILE__, __LINE__);
}
// Method that return the mass of the body
@ -181,7 +181,7 @@ void RigidBody::setLocalInertiaTensor(const Vector3& inertiaTensorLocal) {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
}
// Apply an external force to the body at its center of mass.
@ -244,7 +244,7 @@ void RigidBody::setLocalCenterOfMass(const Vector3& centerOfMass) {
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMass.to_string());
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMass.to_string(), __FILE__, __LINE__);
}
// Return the center of mass of the body (in local-space coordinates)
@ -277,7 +277,7 @@ void RigidBody::updateLocalCenterOfMassFromColliders() {
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string());
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string(), __FILE__, __LINE__);
}
// Compute and return the local-space center of mass of the body using its colliders
@ -384,7 +384,7 @@ void RigidBody::updateLocalInertiaTensorFromColliders() {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
}
// Compute and set the mass of the body using its colliders
@ -420,7 +420,7 @@ void RigidBody::updateMassFromColliders() {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass));
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass), __FILE__, __LINE__);
}
// Compute and set the center of mass, the mass and the local-space inertia tensor of the body using its colliders
@ -450,7 +450,7 @@ void RigidBody::updateMassPropertiesFromColliders() {
mWorld.mRigidBodyComponents.setLinearVelocity(mEntity, linearVelocity);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string());
"Body " + std::to_string(mEntity.id) + ": Set centerOfMassLocal=" + centerOfMassLocal.to_string(), __FILE__, __LINE__);
// Compute the mass and local-space inertia tensor
Vector3 inertiaTensorLocal;
@ -466,7 +466,7 @@ void RigidBody::updateMassPropertiesFromColliders() {
mWorld.mRigidBodyComponents.setInverseInertiaTensorLocal(mEntity, inverseInertiaTensorLocal);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string());
"Body " + std::to_string(mEntity.id) + ": Set inertiaTensorLocal=" + inertiaTensorLocal.to_string(), __FILE__, __LINE__);
// Set the mass
mWorld.mRigidBodyComponents.setMass(mEntity, totalMass);
@ -480,7 +480,7 @@ void RigidBody::updateMassPropertiesFromColliders() {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass));
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(totalMass), __FILE__, __LINE__);
}
// Set the mass of the rigid body
@ -499,10 +499,16 @@ void RigidBody::setMass(decimal mass) {
}
else {
mWorld.mRigidBodyComponents.setMassInverse(mEntity, decimal(0.0));
if (mWorld.mRigidBodyComponents.getMass(mEntity) < decimal(0.0)) {
RP3D_LOG(mLogger, Logger::Level::Error, Logger::Category::Body,
"Error when setting mass of body " + std::to_string(mEntity.id) + ": mass cannot be negative", __FILE__, __LINE__);
}
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(mass));
"Body " + std::to_string(mEntity.id) + ": Set mass=" + std::to_string(mass), __FILE__, __LINE__);
}
@ -565,11 +571,11 @@ Collider* RigidBody::addCollider(CollisionShape* collisionShape, const Transform
mWorld.mCollisionDetection.addCollider(collider, aabb);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body");
"Body " + std::to_string(mEntity.id) + ": Collider " + std::to_string(collider->getBroadPhaseId()) + " added to body", __FILE__, __LINE__);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider " + std::to_string(collider->getBroadPhaseId()) + ": collisionShape=" +
collider->getCollisionShape()->to_string());
collider->getCollisionShape()->to_string(), __FILE__, __LINE__);
// Return a pointer to the collider
return collider;
@ -595,7 +601,7 @@ void RigidBody::enableGravity(bool isEnabled) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isGravityEnabled=" +
(isEnabled ? "true" : "false"));
(isEnabled ? "true" : "false"), __FILE__, __LINE__);
}
// Set the linear damping factor. This is the ratio of the linear velocity
@ -605,10 +611,19 @@ void RigidBody::enableGravity(bool isEnabled) {
*/
void RigidBody::setLinearDamping(decimal linearDamping) {
assert(linearDamping >= decimal(0.0));
mWorld.mRigidBodyComponents.setLinearDamping(mEntity, linearDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set linearDamping=" + std::to_string(linearDamping));
if (linearDamping >= decimal(0.0)) {
mWorld.mRigidBodyComponents.setLinearDamping(mEntity, linearDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set linearDamping=" + std::to_string(linearDamping), __FILE__, __LINE__);
}
else {
RP3D_LOG(mLogger, Logger::Level::Error, Logger::Category::Body,
"Error when setting the linear damping of body " + std::to_string(mEntity.id) + ": linear damping cannot be negative", __FILE__, __LINE__);
}
}
// Set the angular damping factor. This is the ratio of the angular velocity
@ -618,10 +633,18 @@ void RigidBody::setLinearDamping(decimal linearDamping) {
*/
void RigidBody::setAngularDamping(decimal angularDamping) {
assert(angularDamping >= decimal(0.0));
mWorld.mRigidBodyComponents.setAngularDamping(mEntity, angularDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set angularDamping=" + std::to_string(angularDamping));
if (angularDamping >= decimal(0.0)) {
mWorld.mRigidBodyComponents.setAngularDamping(mEntity, angularDamping);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set angularDamping=" + std::to_string(angularDamping), __FILE__, __LINE__);
}
else {
RP3D_LOG(mLogger, Logger::Level::Error, Logger::Category::Body,
"Error when setting the angular damping of body " + std::to_string(mEntity.id) + ": angular damping cannot be negative", __FILE__, __LINE__);
}
}
// Set the linear velocity of the rigid body.
@ -642,7 +665,7 @@ void RigidBody::setLinearVelocity(const Vector3& linearVelocity) {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set linearVelocity=" + linearVelocity.to_string());
"Body " + std::to_string(mEntity.id) + ": Set linearVelocity=" + linearVelocity.to_string(), __FILE__, __LINE__);
}
// Set the angular velocity.
@ -663,7 +686,7 @@ void RigidBody::setAngularVelocity(const Vector3& angularVelocity) {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set angularVelocity=" + angularVelocity.to_string());
"Body " + std::to_string(mEntity.id) + ": Set angularVelocity=" + angularVelocity.to_string(), __FILE__, __LINE__);
}
// Set the current position and orientation
@ -779,7 +802,7 @@ void RigidBody::setIsSleeping(bool isSleeping) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isSleeping=" +
(isSleeping ? "true" : "false"));
(isSleeping ? "true" : "false"), __FILE__, __LINE__);
}
// Update whether the current overlapping pairs where this body is involed are active or not
@ -823,7 +846,7 @@ void RigidBody::setIsAllowedToSleep(bool isAllowedToSleep) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(mEntity.id) + ": Set isAllowedToSleep=" +
(isAllowedToSleep ? "true" : "false"));
(isAllowedToSleep ? "true" : "false"), __FILE__, __LINE__);
}
// Return whether or not the body is allowed to sleep

View File

@ -80,7 +80,7 @@ void Collider::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" +
std::to_string(collisionCategoryBits));
std::to_string(collisionCategoryBits), __FILE__, __LINE__);
}
// Set the collision bits mask
@ -99,7 +99,7 @@ void Collider::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider" + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" +
std::to_string(collideWithMaskBits));
std::to_string(collideWithMaskBits), __FILE__, __LINE__);
}
// Set the local to parent body transform
@ -120,7 +120,7 @@ void Collider::setLocalToBodyTransform(const Transform& transform) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Collider,
"Collider " + std::to_string(getBroadPhaseId()) + ": Set localToBodyTransform=" +
transform.to_string());
transform.to_string(), __FILE__, __LINE__);
}
// Return the AABB of the collider in world-space

View File

@ -35,7 +35,10 @@ PhysicsCommon::PhysicsCommon(MemoryAllocator* baseMemoryAllocator)
mBoxShapes(mMemoryManager.getHeapAllocator()), mCapsuleShapes(mMemoryManager.getHeapAllocator()),
mConvexMeshShapes(mMemoryManager.getHeapAllocator()), mConcaveMeshShapes(mMemoryManager.getHeapAllocator()),
mHeightFieldShapes(mMemoryManager.getHeapAllocator()), mPolyhedronMeshes(mMemoryManager.getHeapAllocator()),
mTriangleMeshes(mMemoryManager.getHeapAllocator()), mLoggers(mMemoryManager.getHeapAllocator()),
mTriangleMeshes(mMemoryManager.getHeapAllocator()),
#ifdef IS_LOGGING_ACTIVE
mLoggers(mMemoryManager.getHeapAllocator()),
#endif
mProfilers(mMemoryManager.getHeapAllocator()) {
}
@ -100,7 +103,7 @@ void PhysicsCommon::release() {
// Destroy the loggers
for (auto it = mLoggers.begin(); it != mLoggers.end(); ++it) {
destroyLogger(*it);
destroyDefaultLogger(*it);
}
#endif
@ -138,12 +141,14 @@ PhysicsWorld* PhysicsCommon::createPhysicsWorld(const PhysicsWorld::WorldSetting
// If the user has not provided its own logger, we create one
if (logger == nullptr) {
logger = createLogger();
DefaultLogger* defaultLogger = createDefaultLogger();
// Add a log destination file
uint logLevel = static_cast<uint>(Logger::Level::Information) | static_cast<uint>(Logger::Level::Warning) |
static_cast<uint>(Logger::Level::Error);
logger->addFileDestination("rp3d_log_" + worldSettings.worldName + ".html", logLevel, Logger::Format::HTML);
defaultLogger->addFileDestination("rp3d_log_" + worldSettings.worldName + ".html", logLevel, DefaultLogger::Format::HTML);
logger = defaultLogger;
}
#endif
@ -373,9 +378,9 @@ void PhysicsCommon::destroyTriangleMesh(TriangleMesh* triangleMesh) {
#ifdef IS_LOGGING_ACTIVE
// Create and return a new logger
Logger* PhysicsCommon::createLogger() {
DefaultLogger* PhysicsCommon::createDefaultLogger() {
Logger* logger = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(Logger))) Logger(mMemoryManager.getHeapAllocator());
DefaultLogger* logger = new (mMemoryManager.allocate(MemoryManager::AllocationType::Pool, sizeof(DefaultLogger))) DefaultLogger(mMemoryManager.getHeapAllocator());
mLoggers.add(logger);
@ -383,13 +388,13 @@ Logger* PhysicsCommon::createLogger() {
}
// Destroy a logger
void PhysicsCommon::destroyLogger(Logger* logger) {
void PhysicsCommon::destroyDefaultLogger(DefaultLogger* logger) {
// Call the destructor of the logger
logger->~Logger();
logger->~DefaultLogger();
// Release allocated memory
mMemoryManager.release(MemoryManager::AllocationType::Pool, logger, sizeof(Logger));
mMemoryManager.release(MemoryManager::AllocationType::Pool, logger, sizeof(DefaultLogger));
mLoggers.remove(logger);
}

View File

@ -108,12 +108,12 @@ PhysicsWorld::PhysicsWorld(MemoryManager& memoryManager, const WorldSettings& wo
mNbWorlds++;
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Physics world " + mName + " has been created");
"Physics World: Physics world " + mName + " has been created", __FILE__, __LINE__);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Initial world settings: " + worldSettings.to_string());
"Physics World: Initial world settings: " + worldSettings.to_string(), __FILE__, __LINE__);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Physics world " + mName + " has been created");
"Physics World: Physics world " + mName + " has been created", __FILE__, __LINE__);
}
@ -121,7 +121,7 @@ PhysicsWorld::PhysicsWorld(MemoryManager& memoryManager, const WorldSettings& wo
PhysicsWorld::~PhysicsWorld() {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Physics world " + mName + " has been destroyed");
"Physics World: Physics world " + mName + " has been destroyed", __FILE__, __LINE__);
// Destroy all the collision bodies that have not been removed
for (int i=mCollisionBodies.size() - 1 ; i >= 0; i--) {
@ -153,7 +153,7 @@ PhysicsWorld::~PhysicsWorld() {
assert(mRigidBodies.size() == 0);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: Physics world " + mName + " has been destroyed");
"Physics World: Physics world " + mName + " has been destroyed", __FILE__, __LINE__);
}
// Create a collision body and add it to the world
@ -193,7 +193,7 @@ CollisionBody* PhysicsWorld::createCollisionBody(const Transform& transform) {
#endif
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(entity.id) + ": New collision body created");
"Body " + std::to_string(entity.id) + ": New collision body created", __FILE__, __LINE__);
// Return the pointer to the rigid body
return collisionBody;
@ -206,7 +206,7 @@ CollisionBody* PhysicsWorld::createCollisionBody(const Transform& transform) {
void PhysicsWorld::destroyCollisionBody(CollisionBody* collisionBody) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(collisionBody->getEntity().id) + ": collision body destroyed");
"Body " + std::to_string(collisionBody->getEntity().id) + ": collision body destroyed", __FILE__, __LINE__);
// Remove all the collision shapes of the body
collisionBody->removeAllColliders();
@ -472,7 +472,7 @@ RigidBody* PhysicsWorld::createRigidBody(const Transform& transform) {
#endif
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(entity.id) + ": New collision body created");
"Body " + std::to_string(entity.id) + ": New collision body created", __FILE__, __LINE__);
// Return the pointer to the rigid body
return rigidBody;
@ -485,7 +485,7 @@ RigidBody* PhysicsWorld::createRigidBody(const Transform& transform) {
void PhysicsWorld::destroyRigidBody(RigidBody* rigidBody) {
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(rigidBody->getEntity().id) + ": rigid body destroyed");
"Body " + std::to_string(rigidBody->getEntity().id) + ": rigid body destroyed", __FILE__, __LINE__);
// Remove all the collision shapes of the body
rigidBody->removeAllColliders();
@ -625,9 +625,9 @@ Joint* PhysicsWorld::createJoint(const JointInfo& jointInfo) {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
"Joint " + std::to_string(newJoint->getEntity().id) + ": New joint created");
"Joint " + std::to_string(newJoint->getEntity().id) + ": New joint created", __FILE__, __LINE__);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
"Joint " + std::to_string(newJoint->getEntity().id) + ": " + newJoint->to_string());
"Joint " + std::to_string(newJoint->getEntity().id) + ": " + newJoint->to_string(), __FILE__, __LINE__);
// Add the joint into the joint list of the bodies involved in the joint
addJointToBodies(jointInfo.body1->getEntity(), jointInfo.body2->getEntity(), entity);
@ -645,7 +645,7 @@ void PhysicsWorld::destroyJoint(Joint* joint) {
assert(joint != nullptr);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Joint,
"Joint " + std::to_string(joint->getEntity().id) + ": joint destroyed");
"Joint " + std::to_string(joint->getEntity().id) + ": joint destroyed", __FILE__, __LINE__);
// If the collision between the two bodies of the constraint was disabled
if (!joint->isCollisionEnabled()) {
@ -698,12 +698,12 @@ void PhysicsWorld::addJointToBodies(Entity body1, Entity body2, Entity joint) {
mRigidBodyComponents.addJointToBody(body1, joint);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(body1.id) + ": Joint " + std::to_string(joint.id) + " added to body");
"Body " + std::to_string(body1.id) + ": Joint " + std::to_string(joint.id) + " added to body", __FILE__, __LINE__);
mRigidBodyComponents.addJointToBody(body2, joint);
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::Body,
"Body " + std::to_string(body2.id) + ": Joint " + std::to_string(joint.id) + " added to body");
"Body " + std::to_string(body2.id) + ": Joint " + std::to_string(joint.id) + " added to body", __FILE__, __LINE__);
}
// Compute the islands using potential contacts and joints
@ -930,5 +930,5 @@ void PhysicsWorld::enableSleeping(bool isSleepingEnabled) {
}
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::World,
"Physics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) );
"Physics World: isSleepingEnabled=" + (isSleepingEnabled ? std::string("true") : std::string("false")) , __FILE__, __LINE__);
}

View File

@ -26,13 +26,13 @@
#ifdef IS_LOGGING_ACTIVE
// Libraries
#include <reactphysics3d/utils/Logger.h>
#include <reactphysics3d/utils/DefaultLogger.h>
#include <reactphysics3d/memory/MemoryManager.h>
using namespace reactphysics3d;
// Constructor
Logger::Logger(MemoryAllocator& allocator)
DefaultLogger::DefaultLogger(MemoryAllocator& allocator)
: mAllocator(allocator), mDestinations(allocator), mFormatters(allocator)
{
// Create the log formatters
@ -41,7 +41,7 @@ Logger::Logger(MemoryAllocator& allocator)
}
// Destructor
Logger::~Logger() {
DefaultLogger::~DefaultLogger() {
removeAllDestinations();
@ -53,7 +53,7 @@ Logger::~Logger() {
}
// Return the corresponding formatter
Logger::Formatter* Logger::getFormatter(Format format) const {
DefaultLogger::Formatter* DefaultLogger::getFormatter(Format format) const {
auto it = mFormatters.find(format);
if (it != mFormatters.end()) {
@ -64,21 +64,21 @@ Logger::Formatter* Logger::getFormatter(Format format) const {
}
// Add a log file destination to the logger
void Logger::addFileDestination(const std::string& filePath, uint logLevelFlag, Format format) {
void DefaultLogger::addFileDestination(const std::string& filePath, uint logLevelFlag, Format format) {
FileDestination* destination = new (mAllocator.allocate(sizeof(FileDestination))) FileDestination(filePath, logLevelFlag, getFormatter(format));
mDestinations.add(destination);
}
/// Add a stream destination to the logger
void Logger::addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format) {
void DefaultLogger::addStreamDestination(std::ostream& outputStream, uint logLevelFlag, Format format) {
StreamDestination* destination = new (mAllocator.allocate(sizeof(StreamDestination))) StreamDestination(outputStream, logLevelFlag, getFormatter(format));
mDestinations.add(destination);
}
// Remove all logs destination previously set
void Logger::removeAllDestinations() {
void DefaultLogger::removeAllDestinations() {
// Delete all the destinations
for (uint i=0; i<mDestinations.size(); i++) {
@ -94,7 +94,7 @@ void Logger::removeAllDestinations() {
}
// Log something
void Logger::log(Level level, Category category, const std::string& message) {
void DefaultLogger::log(Level level, Category category, const std::string& message, const char* filename, int lineNumber) {
// Get current time
auto now = std::chrono::system_clock::now();
@ -105,7 +105,7 @@ void Logger::log(Level level, Category category, const std::string& message) {
// For each destination
for (auto it = mDestinations.begin(); it != mDestinations.end(); ++it) {
(*it)->write(time, message, level, category);
(*it)->write(time, message, level, category, filename, lineNumber);
}
mMutex.unlock();