refactors logging

This commit is contained in:
tosh 2013-05-21 01:00:10 +02:00
parent 4385fc31e8
commit a86b8a1d93
25 changed files with 414 additions and 673 deletions

View file

@ -37,13 +37,10 @@
#include <AgentTypes.h>
#include <PacketHeaders.h>
#include <PerfStat.h>
#include <shared_Log.h>
#include <voxels_Log.h>
#include <avatars_Log.h>
#include "Application.h"
#include "InterfaceConfig.h"
#include "Log.h"
#include "LogDisplay.h"
#include "OculusManager.h"
#include "Util.h"
#include "renderer/ProgramObject.h"
@ -159,10 +156,6 @@ Application::Application(int& argc, char** argv) :
_voxels.setViewFrustum(&_viewFrustum);
shared_lib::printLog = & ::printLog;
voxels_lib::printLog = & ::printLog;
avatars_lib::printLog = & ::printLog;
unsigned int listenPort = AGENT_SOCKET_LISTEN_PORT;
const char** constArgv = const_cast<const char**>(argv);
const char* portStr = getCmdOption(argc, constArgv, "--listenPort");
@ -1772,7 +1765,7 @@ void Application::displayOverlay() {
glPointSize(1.0f);
if (_renderStatsOn->isChecked()) { displayStats(); }
if (_logOn->isChecked()) { logdisplay::Render(_glWidget->width(), _glWidget->height()); }
if (_logOn->isChecked()) { LogDisplay::instance.render(_glWidget->width(), _glWidget->height()); }
// Show chat entry field
if (_chatEntryOn) {

View file

@ -1,364 +0,0 @@
//
// Log.cpp
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "Log.h"
#include <string.h>
#include <stdarg.h>
#include <pthread.h>
#include "InterfaceConfig.h"
#include "Util.h"
#include "ui/TextRenderer.h"
namespace logdisplay {
class Logger {
public:
Logger();
~Logger();
inline void render(unsigned screenWidth, unsigned screenHeight);
inline void setStream(FILE* stream);
inline void setLogWidth(unsigned pixels);
inline void setCharacterSize(unsigned width, unsigned height);
// format, eventually forward, and add the log message (called by printLog)
inline int vprint(char const* fmt, va_list);
private:
// don't copy/assign
Logger(Logger const&); // = delete;
Logger& operator=(Logger const&); // = delete;
// add formatted message for console diplay (called by vprint)
inline void addMessage(char const*);
TextRenderer _textRenderer;
FILE* _stream; // FILE as secondary destination for log messages
char* _chars; // character buffer base address
char* _charsEnd; // character buffer, exclusive end
char** _lines; // line buffer base address
char** _linesEnd; // line buffer, exclusive end
char* _writePos; // character position to write to
char* _writeLineStartPos; // character position where line being written starts
char** _lastLinePos; // last line in the log
unsigned _writtenInLine; // character counter for line wrapping
unsigned _lineLength; // number of characters before line wrap
unsigned _logWidth; // width of the log in pixels
unsigned _charWidth; // width of a character in pixels
unsigned _charHeight; // height of a character in pixels
pthread_mutex_t _mutex;
};
//
// Initialization / state management
//
Logger::Logger() :
_textRenderer(MONO_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT),
_stream(DEFAULT_STREAM),
_chars(0l),
_lines(0l),
_logWidth(DEFAULT_CONSOLE_WIDTH) {
pthread_mutex_init(& _mutex, 0l);
// allocate twice as much (so we have spare space for a copy not to block
// logging from other threads during 'render')
_chars = new char[CHARACTER_BUFFER_SIZE * 2];
_charsEnd = _chars + CHARACTER_BUFFER_SIZE;
_lines = new char*[LINE_BUFFER_SIZE * 2];
_linesEnd = _lines + LINE_BUFFER_SIZE;
// initialize the log to all empty lines
_chars[0] = '\0';
_writePos = _chars;
_writeLineStartPos = _chars;
_lastLinePos = _lines;
_writtenInLine = 0;
memset(_lines, 0, LINE_BUFFER_SIZE * sizeof(char*));
setCharacterSize(DEFAULT_CHAR_WIDTH, DEFAULT_CHAR_HEIGHT);
}
Logger::~Logger() {
delete[] _chars;
delete[] _lines;
}
inline void Logger::setStream(FILE* stream) {
pthread_mutex_lock(& _mutex);
_stream = stream;
pthread_mutex_unlock(& _mutex);
}
inline void Logger::setLogWidth(unsigned pixels) {
pthread_mutex_lock(& _mutex);
_logWidth = pixels;
_lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mutex);
}
inline void Logger::setCharacterSize(unsigned width, unsigned height) {
pthread_mutex_lock(& _mutex);
_charWidth = width;
_charHeight = height;
_lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mutex);
}
//
// Logging
//
inline int Logger::vprint(char const* fmt, va_list args) {
pthread_mutex_lock(& _mutex);
// print to buffer
char buf[MAX_MESSAGE_LENGTH];
int n = vsnprintf(buf, MAX_MESSAGE_LENGTH, fmt, args);
if (n > 0) {
// all fine? log the message
addMessage(buf);
} else {
// error? -> mutter on stream or stderr
fprintf(_stream != 0l ? _stream : stderr,
"Log: Failed to log message with format string = \"%s\".\n", fmt);
}
pthread_mutex_unlock(& _mutex);
return n;
}
inline void Logger::addMessage(char const* ptr) {
// precondition: mutex is locked so noone gets in our way
// T-pipe, if requested
if (_stream != 0l) {
fprintf(_stream, "%s", ptr);
}
while (*ptr != '\0') {
// process the characters
char c = *ptr++;
if (c == '\t') {
// found TAB -> write SPACE
c = ' ';
} else if (c == '\n') {
// found LF -> write NUL (c == '\0' tells us to wrap, below)
c = '\0';
}
*_writePos++ = c;
if (_writePos == _charsEnd) {
// reached the end of the circular character buffer? -> start over
_writePos = _chars;
}
if (++_writtenInLine >= _lineLength || c == '\0') {
// new line? store its start to the line buffer and mark next line as empty
++_lastLinePos;
if (_lastLinePos == _linesEnd) {
_lastLinePos = _lines;
_lastLinePos[1] = 0l;
} else if (_lastLinePos + 1 != _linesEnd) {
_lastLinePos[1] = 0l;
} else {
_lines[0] = 0l;
}
*_lastLinePos = _writeLineStartPos;
// debug mode: make sure all line pointers we write here are valid
assert(! (_lastLinePos < _lines || _lastLinePos >= _linesEnd));
assert(! (*_lastLinePos < _chars || *_lastLinePos >= _charsEnd));
// terminate line, unless done already
if (c != '\0') {
*_writePos++ = '\0';
if (_writePos == _charsEnd) {
_writePos = _chars;
}
}
// remember start position in character buffer for next line and reset character count
_writeLineStartPos = _writePos;
_writtenInLine = 0;
}
}
}
//
// Rendering
//
inline void Logger::render(unsigned screenWidth, unsigned screenHeight) {
// rendering might take some time, so create a local copy of the portion we need
// instead of having to hold the mutex all the time
pthread_mutex_lock(& _mutex);
// determine number of visible lines (integer division rounded up)
unsigned showLines = (screenHeight + _charHeight - 1) / _charHeight;
char** lastLine = _lastLinePos;
char** firstLine = _lastLinePos;
if (! *lastLine) {
// empty log
pthread_mutex_unlock(& _mutex);
return;
}
// scan for first line
for (int n = 2; n <= showLines; ++n) {
char** prevFirstLine = firstLine;
--firstLine;
if (firstLine < _lines) {
firstLine = _linesEnd - 1;
}
if (! *firstLine) {
firstLine = prevFirstLine;
showLines = n - 1;
break;
}
// debug mode: make sure all line pointers we find here are valid
assert(! (firstLine < _lines || firstLine >= _linesEnd));
assert(! (*firstLine < _chars || *firstLine >= _charsEnd));
}
// copy the line buffer portion into a contiguous region at _linesEnd
if (firstLine <= lastLine) {
memcpy(_linesEnd, firstLine, showLines * sizeof(char*));
} else {
unsigned atEnd = _linesEnd - firstLine;
memcpy(_linesEnd, firstLine, atEnd * sizeof(char*));
memcpy(_linesEnd + atEnd, _lines, (showLines - atEnd) * sizeof(char*));
}
// copy relevant char buffer portion and determine information to remap the pointers
char* firstChar = *firstLine;
char* lastChar = *lastLine + strlen(*lastLine) + 1;
ptrdiff_t charOffset = _charsEnd - firstChar, charOffsetBeforeFirst = 0;
if (firstChar <= lastChar) {
memcpy(_charsEnd, firstChar, lastChar - firstChar + 1);
} else {
unsigned atEnd = _charsEnd - firstChar;
memcpy(_charsEnd, firstChar, atEnd);
memcpy(_charsEnd + atEnd, _chars, lastChar + 1 - _chars);
charOffsetBeforeFirst = _charsEnd + atEnd - _chars;
}
// determine geometry information from font metrics
QFontMetrics const& fontMetrics = _textRenderer.metrics();
int yStep = fontMetrics.lineSpacing();
// scale
float xScale = float(_charWidth) / fontMetrics.width('*');
float yScale = float(_charHeight) / yStep;
// scaled translation
int xStart = int((screenWidth - _logWidth) / xScale);
int yStart = screenHeight / yScale - fontMetrics.descent();
// first line to render
char** line = _linesEnd + showLines;
// ok, now the lock can be released - we have all we need
// and won't hold it while talking to OpenGL
pthread_mutex_unlock(& _mutex);
glPushMatrix();
glScalef(xScale, yScale, 1.0f);
for (int y = yStart; y > 0; y -= yStep) {
// debug mode: check line pointer is valid
assert(! (line < _linesEnd || line >= _linesEnd + (_linesEnd - _lines)));
// get character pointer
if (--line < _linesEnd) {
break;
}
char* chars = *line;
// debug mode: check char pointer we find is valid
assert(! (chars < _chars || chars >= _charsEnd));
// remap character pointer it to copied buffer
chars += chars >= firstChar ? charOffset : charOffsetBeforeFirst;
// debug mode: check char pointer is still valid (in new range)
assert(! (chars < _charsEnd || chars >= _charsEnd + (_charsEnd - _chars)));
// render the string
glColor3f(TEXT_COLOR_RED, TEXT_COLOR_GREEN, TEXT_COLOR_BLUE);
_textRenderer.draw(xStart, y, chars);
//fprintf(stderr, "Logger::render, message = \"%s\"\n", chars);
}
glPopMatrix();
}
//
// There's one Logger and it exists globally...
//
Logger logger;
// Entrypoints
void Render(unsigned screenWidth, unsigned screenHeight) { logger.render(screenWidth, screenHeight); }
void SetStream(FILE* stream) { logger.setStream(stream); }
void SetLogWidth(unsigned pixels) { logger.setLogWidth(pixels); }
void SetCharacterSize(unsigned width, unsigned height) { logger.setCharacterSize(width, height); }
} // namespace logdisplay
int printLog(char const* fmt, ...) {
int result;
va_list args;
va_start(args,fmt);
result = logdisplay::logger.vprint(fmt, args);
va_end(args);
return result;
}

View file

@ -1,68 +0,0 @@
//
// Log.h
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Log__
#define __interface__Log__
#include <stdio.h>
#include <stdarg.h>
//
// Log function. Call it as you would call 'printf'.
//
int printLog(char const* fmt, ...);
//
// Logging control.
//
namespace logdisplay {
void Render(unsigned screenWidth, unsigned screenHeight);
// settings
static float const TEXT_COLOR_RED = 0.7f; // text foreground color, red component
static float const TEXT_COLOR_GREEN = 0.6f; // text foreground color, green component
static float const TEXT_COLOR_BLUE = 1.0f; // text foregdound color, blue component
static FILE* DEFAULT_STREAM = stdout; // stream to also log to
static unsigned const DEFAULT_CHAR_WIDTH = 7; // width of a single character
static unsigned const DEFAULT_CHAR_HEIGHT = 16; // height of a single character
static unsigned const DEFAULT_CONSOLE_WIDTH = 400; // width of the (right-aligned) log console
void SetStream(FILE* stream);
void SetLogWidth(unsigned pixels);
void SetCharacterSize(unsigned width, unsigned height);
// limits
unsigned const CHARACTER_BUFFER_SIZE = 16384; // number of character that are buffered
unsigned const LINE_BUFFER_SIZE = 256; // number of lines that are buffered
unsigned const MAX_MESSAGE_LENGTH = 512; // maximum number of characters for a message
}
//
// Macro to log OpenGL errors.
// Example: printGlError( glPushMatrix() );
//
#define printLogGlError(stmt) \
stmt; \
{ \
GLenum e = glGetError(); \
if (e != GL_NO_ERROR) { \
printLog(__FILE__ ":" printLogGlError_stringize(__LINE__) \
" [OpenGL] %s\n", gluErrorString(e)); \
} \
} \
(void) 0
#define printLogGlError_stringize(x) printLogGlError_stringize_i(x)
#define printLogGlError_stringize_i(x) # x
#endif

View file

@ -0,0 +1,306 @@
//
// LogDisplay.cpp
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "LogDisplay.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "Util.h"
using namespace std;
FILE* const LogDisplay::DEFAULT_STREAM = stdout;
//
// Singleton constructor
//
LogDisplay LogDisplay::instance;
//
// State management
//
LogDisplay::LogDisplay() :
_textRenderer(MONO_FONT_FAMILY, -1, -1, false, TextRenderer::SHADOW_EFFECT),
_stream(DEFAULT_STREAM),
_chars(0l),
_lines(0l),
_logWidth(DEFAULT_CONSOLE_WIDTH) {
pthread_mutex_init(& _mutex, 0l);
// allocate twice as much (so we have spare space for a copy not to block
// logging from other threads during 'render')
_chars = new char[CHARACTER_BUFFER_SIZE * 2];
_charsEnd = _chars + CHARACTER_BUFFER_SIZE;
_lines = new char*[LINE_BUFFER_SIZE * 2];
_linesEnd = _lines + LINE_BUFFER_SIZE;
// initialize the log to all empty lines
_chars[0] = '\0';
_writePos = _chars;
_writeLineStartPos = _chars;
_lastLinePos = _lines;
_writtenInLine = 0;
memset(_lines, 0, LINE_BUFFER_SIZE * sizeof(char*));
setCharacterSize(DEFAULT_CHAR_WIDTH, DEFAULT_CHAR_HEIGHT);
printLog = & printLogHandler;
}
LogDisplay::~LogDisplay() {
delete[] _chars;
delete[] _lines;
}
void LogDisplay::setStream(FILE* stream) {
pthread_mutex_lock(& _mutex);
_stream = stream;
pthread_mutex_unlock(& _mutex);
}
void LogDisplay::setLogWidth(unsigned pixels) {
pthread_mutex_lock(& _mutex);
_logWidth = pixels;
_lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mutex);
}
void LogDisplay::setCharacterSize(unsigned width, unsigned height) {
pthread_mutex_lock(& _mutex);
_charWidth = width;
_charHeight = height;
_lineLength = _logWidth / _charWidth;
pthread_mutex_unlock(& _mutex);
}
//
// Logging
//
int LogDisplay::printLogHandler(char const* fmt, ...) {
va_list args;
int n;
char buf[MAX_MESSAGE_LENGTH];
va_start(args,fmt);
// print to buffer
n = vsnprintf(buf, MAX_MESSAGE_LENGTH, fmt, args);
if (n > 0) {
// all fine? log the message
instance.addMessage(buf);
} else {
// error? -> mutter on stream or stderr
fprintf(instance._stream != 0l ? instance._stream : stderr,
"Log: Failed to log message with format string = \"%s\".\n", fmt);
}
va_end(args);
return n;
}
inline void LogDisplay::addMessage(char const* ptr) {
pthread_mutex_lock(& _mutex);
// T-pipe, if requested
if (_stream != 0l) {
fprintf(_stream, "%s", ptr);
}
while (*ptr != '\0') {
// process the characters
char c = *ptr++;
if (c == '\t') {
// found TAB -> write SPACE
c = ' ';
} else if (c == '\n') {
// found LF -> write NUL (c == '\0' tells us to wrap, below)
c = '\0';
}
*_writePos++ = c;
if (_writePos == _charsEnd) {
// reached the end of the circular character buffer? -> start over
_writePos = _chars;
}
if (++_writtenInLine >= _lineLength || c == '\0') {
// new line? store its start to the line buffer and mark next line as empty
++_lastLinePos;
if (_lastLinePos == _linesEnd) {
_lastLinePos = _lines;
_lastLinePos[1] = 0l;
} else if (_lastLinePos + 1 != _linesEnd) {
_lastLinePos[1] = 0l;
} else {
_lines[0] = 0l;
}
*_lastLinePos = _writeLineStartPos;
// debug mode: make sure all line pointers we write here are valid
assert(! (_lastLinePos < _lines || _lastLinePos >= _linesEnd));
assert(! (*_lastLinePos < _chars || *_lastLinePos >= _charsEnd));
// terminate line, unless done already
if (c != '\0') {
*_writePos++ = '\0';
if (_writePos == _charsEnd) {
_writePos = _chars;
}
}
// remember start position in character buffer for next line and reset character count
_writeLineStartPos = _writePos;
_writtenInLine = 0;
}
}
pthread_mutex_unlock(& _mutex);
}
//
// Rendering
//
void LogDisplay::render(unsigned screenWidth, unsigned screenHeight) {
// rendering might take some time, so create a local copy of the portion we need
// instead of having to hold the mutex all the time
pthread_mutex_lock(& _mutex);
// determine number of visible lines (integer division rounded up)
unsigned showLines = (screenHeight + _charHeight - 1) / _charHeight;
char** lastLine = _lastLinePos;
char** firstLine = _lastLinePos;
if (! *lastLine) {
// empty log
pthread_mutex_unlock(& _mutex);
return;
}
// scan for first line
for (int n = 2; n <= showLines; ++n) {
char** prevFirstLine = firstLine;
--firstLine;
if (firstLine < _lines) {
firstLine = _linesEnd - 1;
}
if (! *firstLine) {
firstLine = prevFirstLine;
showLines = n - 1;
break;
}
// debug mode: make sure all line pointers we find here are valid
assert(! (firstLine < _lines || firstLine >= _linesEnd));
assert(! (*firstLine < _chars || *firstLine >= _charsEnd));
}
// copy the line buffer portion into a contiguous region at _linesEnd
if (firstLine <= lastLine) {
memcpy(_linesEnd, firstLine, showLines * sizeof(char*));
} else {
unsigned atEnd = _linesEnd - firstLine;
memcpy(_linesEnd, firstLine, atEnd * sizeof(char*));
memcpy(_linesEnd + atEnd, _lines, (showLines - atEnd) * sizeof(char*));
}
// copy relevant char buffer portion and determine information to remap the pointers
char* firstChar = *firstLine;
char* lastChar = *lastLine + strlen(*lastLine) + 1;
ptrdiff_t charOffset = _charsEnd - firstChar, charOffsetBeforeFirst = 0;
if (firstChar <= lastChar) {
memcpy(_charsEnd, firstChar, lastChar - firstChar + 1);
} else {
unsigned atEnd = _charsEnd - firstChar;
memcpy(_charsEnd, firstChar, atEnd);
memcpy(_charsEnd + atEnd, _chars, lastChar + 1 - _chars);
charOffsetBeforeFirst = _charsEnd + atEnd - _chars;
}
// determine geometry information from font metrics
QFontMetrics const& fontMetrics = _textRenderer.metrics();
int yStep = fontMetrics.lineSpacing();
// scale
float xScale = float(_charWidth) / fontMetrics.width('*');
float yScale = float(_charHeight) / yStep;
// scaled translation
int xStart = int((screenWidth - _logWidth) / xScale);
int yStart = screenHeight / yScale - fontMetrics.descent();
// first line to render
char** line = _linesEnd + showLines;
// ok, now the lock can be released - we have all we need
// and won't hold it while talking to OpenGL
pthread_mutex_unlock(& _mutex);
glPushMatrix();
glScalef(xScale, yScale, 1.0f);
for (int y = yStart; y > 0; y -= yStep) {
// debug mode: check line pointer is valid
assert(! (line < _linesEnd || line >= _linesEnd + (_linesEnd - _lines)));
// get character pointer
if (--line < _linesEnd) {
break;
}
char* chars = *line;
// debug mode: check char pointer we find is valid
assert(! (chars < _chars || chars >= _charsEnd));
// remap character pointer it to copied buffer
chars += chars >= firstChar ? charOffset : charOffsetBeforeFirst;
// debug mode: check char pointer is still valid (in new range)
assert(! (chars < _charsEnd || chars >= _charsEnd + (_charsEnd - _chars)));
// render the string
glColor3ub(GLubyte(TEXT_COLOR >> 16),
GLubyte((TEXT_COLOR >> 8) & 0xff),
GLubyte(TEXT_COLOR & 0xff));
_textRenderer.draw(xStart, y, chars);
//fprintf(stderr, "LogDisplay::render, message = \"%s\"\n", chars);
}
glPopMatrix();
}

View file

@ -0,0 +1,80 @@
//
// LogDisplay.h
// interface
//
// Created by Tobias Schwinger on 4/14/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__LogDisplay__
#define __interface__LogDisplay__
#include <stdarg.h>
#include <pthread.h>
#include "Log.h"
#include "ui/TextRenderer.h"
class LogDisplay {
public:
static LogDisplay instance;
void render(unsigned screenWidth, unsigned screenHeight);
// settings
static unsigned const TEXT_COLOR = 0xb299ff; // text foreground color (bytes, RGB)
static FILE* const DEFAULT_STREAM; // = stdout; // stream to also log to (defined in .cpp)
static unsigned const DEFAULT_CHAR_WIDTH = 7; // width of a single character
static unsigned const DEFAULT_CHAR_HEIGHT = 16; // height of a single character
static unsigned const DEFAULT_CONSOLE_WIDTH = 400; // width of the (right-aligned) log console
void setStream(FILE* stream);
void setLogWidth(unsigned pixels);
void setCharacterSize(unsigned width, unsigned height);
// limits
static unsigned const CHARACTER_BUFFER_SIZE = 16384; // number of character that are buffered
static unsigned const LINE_BUFFER_SIZE = 256; // number of lines that are buffered
static unsigned const MAX_MESSAGE_LENGTH = 512; // maximum number of characters for a message
private:
// use static 'instance' to access the single instance
LogDisplay();
~LogDisplay();
// don't copy/assign
LogDisplay(LogDisplay const&); // = delete;
LogDisplay& operator=(LogDisplay const&); // = delete;
// format and log message - entrypoint used to replace global 'printLog'
static int static printLogHandler(char const* fmt, ...);
// log formatted message (called by printLogHandler)
inline void addMessage(char const*);
TextRenderer _textRenderer;
FILE* _stream; // FILE as secondary destination for log messages
char* _chars; // character buffer base address
char* _charsEnd; // character buffer, exclusive end
char** _lines; // line buffer base address
char** _linesEnd; // line buffer, exclusive end
char* _writePos; // character position to write to
char* _writeLineStartPos; // character position where line being written starts
char** _lastLinePos; // last line in the log
unsigned _writtenInLine; // character counter for line wrapping
unsigned _lineLength; // number of characters before line wrap
unsigned _logWidth; // width of the log in pixels
unsigned _charWidth; // width of a character in pixels
unsigned _charHeight; // height of a character in pixels
pthread_mutex_t _mutex;
};
#endif

View file

@ -1,106 +0,0 @@
//
// LogStream.h
// interface
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__LogStream__
#define __interface__LogStream__
#include <sstream>
#include "Log.h"
//
// Makes the logging facility accessible as a C++ stream.
//
// Example:
//
// // somewhere central - ideally one per thread (else pass 'true' as
// // second constructor argument and compromise some efficiency)
// LogStream lOut(printLog);
//
// // elsewhere:
// lOut << "Hello there!" << std::endl;
//
class LogStream {
std::ostringstream _outStream;
Log& _logRef;
bool _isThreadSafe;
public:
inline LogStream(Log& log, bool threadSafe = false);
class StreamRef; friend class StreamRef;
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
private:
// don't
LogStream(LogStream const&); // = delete;
LogStream& operator=(LogStream const&); // = delete;
inline void ostreamBegin();
inline void ostreamEnd();
};
inline LogStream::LogStream(Log& log, bool threadSafe) :
_outStream(std::ios_base::out), _logRef(log), _isThreadSafe(threadSafe) { }
inline void LogStream::ostreamBegin() {
if (_isThreadSafe) {
// the user wants to share this LogStream among threads,
// so lock the global log here, already
pthread_mutex_lock(& _logRef._mutex);
}
_outStream.str("");
}
inline void LogStream::ostreamEnd() {
if (! _isThreadSafe) {
// haven't locked, so far (we have memory for each thread)
pthread_mutex_lock(& _logRef._mutex);
}
_logRef.addMessage(_outStream.str().c_str());
pthread_mutex_unlock(& _logRef._mutex);
}
//
// The Log::StreamRef class makes operator<< work. It...
//
class LogStream::StreamRef {
mutable LogStream* _logStream;
typedef std::ostream& (*manipulator)(std::ostream&);
friend class LogStream;
template< typename T > friend inline LogStream::StreamRef const operator<<(LogStream&, T const&);
StreamRef(LogStream* log) : _logStream(log) { }
public:
// ...forwards << operator calls to stringstream...
template< typename T > StreamRef const operator<<(T const& x) const { _logStream->_outStream << x; return *this; }
// ...has to dance around to make manipulators (such as std::hex, std::endl) work...
StreamRef const operator<<(manipulator x) const { _logStream->_outStream << x; return *this; }
// ...informs the logger that a stream has ended when it has the responsibility...
~StreamRef() { if (_logStream != 0l) { _logStream->ostreamEnd(); } }
// ...which is passed on upon copy.
StreamRef(StreamRef const& other) : _logStream(other._logStream) { other._logStream = 0l; }
private:
// don't
StreamRef& operator=(StreamRef const&); // = delete;
};
template< typename T > inline LogStream::StreamRef const operator<<(LogStream& s, T const& x) {
s.ostreamBegin();
s._outStream << x;
return LogStream::StreamRef(& s); // calls streamEnd at the end of the stream expression
}
#endif

View file

@ -14,10 +14,8 @@
#include <PacketHeaders.h>
#include "AvatarData.h"
#include "avatars_Log.h"
using namespace std;
using avatars_lib::printLog;
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
@ -224,4 +222,4 @@ void AvatarData::setHeadPitch(float p) {
const float MAX_PITCH = 60;
const float MIN_PITCH = -60;
_headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH);
}
}

View file

@ -7,9 +7,6 @@
#include "Orientation.h"
#include "SharedUtil.h"
//#include "avatars_Log.h"
//using avatars_lib::printLog;
static const bool USING_QUATERNIONS = true;

View file

@ -1,17 +0,0 @@
//
// avatars_Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "shared_Log.h"
#include <cstdio>
namespace avatars_lib {
using namespace std;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -1,20 +0,0 @@
//
// avatars_Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__avatars_Log__
#define __hifi__avatars_Log__
namespace avatars_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
#endif /* defined(__hifi__avatars_Log__) */

View file

@ -10,7 +10,7 @@
#include "Agent.h"
#include "AgentTypes.h"
#include <cstring>
#include "shared_Log.h"
#include "Log.h"
#include "UDPSocket.h"
#include "SharedUtil.h"
@ -20,8 +20,6 @@
#include <arpa/inet.h>
#endif
using shared_lib::printLog;
int unpackAgentId(unsigned char* packedData, uint16_t* agentId) {
memcpy(agentId, packedData, sizeof(uint16_t));
return sizeof(uint16_t);
@ -150,4 +148,4 @@ void Agent::printLog(Agent const& agent) {
agent._type,
publicAddressBuffer,
publicAddressPort);
}
}

View file

@ -15,7 +15,7 @@
#include "AgentTypes.h"
#include "PacketHeaders.h"
#include "SharedUtil.h"
#include "shared_Log.h"
#include "Log.h"
#ifdef _WIN32
#include "Syssocket.h"
@ -23,8 +23,6 @@
#include <arpa/inet.h>
#endif
using shared_lib::printLog;
const char SOLO_AGENT_TYPES[3] = {
AGENT_TYPE_AVATAR_MIXER,
AGENT_TYPE_AUDIO_MIXER,

View file

@ -1,17 +1,15 @@
//
// voxels_Log.cpp
// Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "voxels_Log.h"
#include "Log.h"
#include <cstdio>
namespace voxels_lib {
using namespace std;
using namespace std;
int (* printLog)(char const*, ...) = & printf;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -1,5 +1,5 @@
//
// shared_Log.h
// Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
@ -9,12 +9,13 @@
#ifndef __hifi__shared_Log__
#define __hifi__shared_Log__
namespace shared_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
//
// Pointer to log function
//
// An application may reset this variable to receive the log messages
// issued using 'printLog'. It defaults to a pointer to 'printf'.
//
extern int (* printLog)(char const*, ...);
#endif /* defined(__hifi__shared_Log__) */

View file

@ -11,9 +11,7 @@
#include <cstring>
#include "SharedUtil.h"
#include "OctalCode.h"
#include "shared_Log.h"
using shared_lib::printLog;
#include "Log.h"
int numberOfThreeBitSectionsInCode(unsigned char * octalCode) {
if (*octalCode == 255) {

View file

@ -14,9 +14,7 @@
#include <string>
#include <map>
#include "shared_Log.h"
using shared_lib::printLog;
#include "Log.h"
// Static class members initialization here!
std::map<std::string,PerfStatHistory,std::less<std::string> > PerfStat::groupHistoryMap;

View file

@ -14,7 +14,7 @@
#ifdef _WIN32
#include "Syssocket.h"
#endif
#include "shared_Log.h"
#include "Log.h"
#include "SharedUtil.h"
#include "OctalCode.h"
@ -22,8 +22,6 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
using shared_lib::printLog;
double usecTimestamp(timeval *time) {
return (time->tv_sec * 1000000.0 + time->tv_usec);
}

View file

@ -21,9 +21,7 @@
#include <unistd.h>
#endif
#include "shared_Log.h"
using shared_lib::printLog;
#include "Log.h"
sockaddr_in destSockaddr, senderAddress;

View file

@ -13,8 +13,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include "shared_Log.h"
using shared_lib::printLog;
#include "Log.h"
#ifndef _WIN32
// (Windows port is incomplete and the build files do not support CURL, yet)

View file

@ -1,17 +0,0 @@
//
// shared_Log.cpp
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#include "shared_Log.h"
#include <cstdio>
namespace shared_lib {
using namespace std;
int (* printLog)(char const*, ...) = & printf;
}

View file

@ -9,11 +9,10 @@
//
#include "Plane.h"
#include <stdio.h>
#include "voxels_Log.h"
using voxels_lib::printLog;
#include "Log.h"
// These are some useful utilities that vec3 is missing
void printVec3(const char* name, const glm::vec3& v) {

View file

@ -14,9 +14,8 @@
#include "ViewFrustum.h"
#include "SharedUtil.h"
#include "voxels_Log.h"
#include "Log.h"
using voxels_lib::printLog;
using namespace std;
ViewFrustum::ViewFrustum() :

View file

@ -10,14 +10,11 @@
#include <cmath>
#include <cstring>
#include "SharedUtil.h"
#include "voxels_Log.h"
#include "Log.h"
#include "VoxelNode.h"
#include "VoxelConstants.h"
#include "OctalCode.h"
#include "AABox.h"
using voxels_lib::printLog;
// using voxels_lib::printLog;
VoxelNode::VoxelNode() {
unsigned char* rootCode = new unsigned char[1];

View file

@ -13,7 +13,7 @@
#include <cstdio>
#include <cmath>
#include "SharedUtil.h"
#include "voxels_Log.h"
#include "Log.h"
#include "PacketHeaders.h"
#include "OctalCode.h"
#include "VoxelTree.h"
@ -24,8 +24,6 @@
#include <glm/gtc/noise.hpp>
using voxels_lib::printLog;
int boundaryDistanceForRenderLevel(unsigned int renderLevel) {
float voxelSizeScale = 50000.0f;
return voxelSizeScale / powf(2, renderLevel);

View file

@ -1,20 +0,0 @@
//
// voxels_Log.h
// hifi
//
// Created by Tobias Schwinger on 4/17/13.
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
//
#ifndef __hifi__voxels_Log__
#define __hifi__voxels_Log__
namespace voxels_lib {
// variable that can be set from outside to redirect the log output
// of this library
extern int (* printLog)(char const*, ...);
}
#endif /* defined(__hifi__voxels_Log__) */