aboutsummaryrefslogtreecommitdiff
path: root/tools/common/Log.h
blob: 528a3b9a227a538d38207c1478d4839b8f905e8a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef LOG_H
#define LOG_H

#include "Utils.h"
#include "PxVec3.h"

#include <sstream>

namespace Nv
{
namespace Blast
{


//////////////////////////////////////////////////////////////////////////////

void fLogf(const char* format, ...);

class Log : public Singleton<Log>
{
	friend class Singleton<Log>;

public:

	enum MessageType {
		TYPE_INFO = 0,
		TYPE_WARNING,
		TYPE_ERROR,
		TYPE_DEFERRED,

		NUM_TYPES,
		MOST_VERBOSE  = TYPE_INFO,
		LEAST_VERBOSE = TYPE_ERROR
#if defined(_DEBUG)
		, DEFAULT_VERBOSITY = MOST_VERBOSE
#else
		, DEFAULT_VERBOSITY = LEAST_VERBOSE
#endif
	};
	typedef MessageType Verbosity;

	///////////////////////////////////////////////////////////////////////////

	template<typename T>
	Log& log(const T& value, MessageType messageType);

	void flushDeferredMessages();

	///////////////////////////////////////////////////////////////////////////

	void setCurrentVerbosity(Verbosity verbosity) { mCurrentVerbosity = verbosity; }
	Verbosity getCurrentVerbosity() const { return mCurrentVerbosity; }

	// Messages types below this level will be ignored
	void setMinVerbosity(Verbosity verbosity)     { mMinVerbosity     = verbosity; }
	Verbosity getMinVerbosity()     const { return mMinVerbosity; }

	///////////////////////////////////////////////////////////////////////////

protected:
	Log(MessageType verbosity = DEFAULT_VERBOSITY)
		: mCurrentVerbosity(LEAST_VERBOSE),
		mMinVerbosity(verbosity) { }

private:
	Verbosity mCurrentVerbosity;
	Verbosity mMinVerbosity;
	std::vector<std::string> mDeferredMessages;
};

///////////////////////////////////////////////////////////////////////////

PX_INLINE std::ostream& operator<< (std::ostream& stream, const physx::PxVec3& vec)
{
	return stream << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")";
}

template<typename T>
Log& Log::log(const T& value, Log::MessageType messageType)
{
	if (TYPE_DEFERRED == messageType)
	{
		std::stringstream ss;
		ss << value;
		mDeferredMessages.push_back(ss.str());
	}
	else if(mMinVerbosity <= messageType)
	{
		std::cout << value;
	}
	return *this;
}

PX_INLINE Log& lout() { return Log::instance(); }

template <typename T>
PX_INLINE void fLog(const T& value, Log::MessageType messageType = Log::TYPE_INFO)
{
	lout().log<T>(value, messageType);
}
template <typename T>
PX_INLINE Log& operator<<(Log& logger, const T& value)
{
	return logger.log<T>(value, logger.getCurrentVerbosity());
}
PX_INLINE Log& operator<<(Log& logger, Log::MessageType verbosity)
{
	logger.setCurrentVerbosity(verbosity);
	return logger;
}
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
PX_INLINE Log& operator<<(Log& logger, ostream_manipulator pf)
{
	return operator<< <ostream_manipulator> (logger, pf);
}


} // namespace Blast
} // namespace Nv


#endif