diff --git a/simgear/debug/BufferedLogCallback.cxx b/simgear/debug/BufferedLogCallback.cxx new file mode 100644 index 00000000..72d437c6 --- /dev/null +++ b/simgear/debug/BufferedLogCallback.cxx @@ -0,0 +1,77 @@ +/** \file BufferedLogCallback.cxx + * Buffer certain log messages permanently for later retrieval and display + */ + +// Copyright (C) 2013 James Turner zakalawe@mac.com +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#include + +#include + +#include +#include +#include + +namespace simgear +{ + +class BufferedLogCallback::BufferedLogCallbackPrivate +{ +public: + SGMutex m_mutex; + sgDebugClass m_class; + sgDebugPriority m_priority; + vector_cstring m_buffer; +}; + +BufferedLogCallback::BufferedLogCallback(sgDebugClass c, sgDebugPriority p) : + d(new BufferedLogCallbackPrivate) +{ + d->m_class = c; + d->m_priority = p; +} + +BufferedLogCallback::~BufferedLogCallback() +{ + BOOST_FOREACH(unsigned char* msg, d->m_buffer) { + free(msg); + } +} + +void BufferedLogCallback::operator()(sgDebugClass c, sgDebugPriority p, + const char* file, int line, const std::string& aMessage) +{ + SG_UNUSED(file); + SG_UNUSED(line); + + if ((c & d->m_class) == 0 || p < d->m_priority) return; + + vector_cstring::value_type msg = (vector_cstring::value_type) strdup(aMessage.c_str()); + SGGuard g(d->m_mutex); + d->m_buffer.push_back(msg); +} + +void BufferedLogCallback::threadsafeCopy(vector_cstring& aOutput) +{ + SGGuard g(d->m_mutex); + size_t sz = d->m_buffer.size(); + aOutput.resize(sz); + memcpy(aOutput.data(), d->m_buffer.data(), sz * sizeof(vector_cstring::value_type)); +} + +} // of namespace simgear diff --git a/simgear/debug/BufferedLogCallback.hxx b/simgear/debug/BufferedLogCallback.hxx new file mode 100644 index 00000000..21359fd9 --- /dev/null +++ b/simgear/debug/BufferedLogCallback.hxx @@ -0,0 +1,66 @@ +/** \file BufferedLogCallback.hxx + * Buffer certain log messages permanently for later retrieval and display + */ + +// Copyright (C) 2013 James Turner zakalawe@mac.com +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + + +#ifndef SG_DEBUG_BUFFEREDLOGCALLBACK_HXX +#define SG_DEBUG_BUFFEREDLOGCALLBACK_HXX + +#include +#include // for std::auto_ptr + +#include + +namespace simgear +{ + +class BufferedLogCallback : public LogCallback +{ +public: + BufferedLogCallback(sgDebugClass c, sgDebugPriority p); + virtual ~BufferedLogCallback(); + + virtual void operator()(sgDebugClass c, sgDebugPriority p, + const char* file, int line, const std::string& aMessage); + + /** + * copying a (large) vector of std::string would be very expensive. + * once logged, this call retains storage of the underlying string data, + * so when copying, it's sufficient to pass around the strings as raw + * char arrays. This means we're only copying a vector of pointers, + * which is very efficient. + */ + typedef std::vector vector_cstring; + + /** + * copy the buffered log data into the provided output list + * (which will be cleared first). This method is safe to call from + * any thread. + */ + void threadsafeCopy(vector_cstring& aOutput); +private: + class BufferedLogCallbackPrivate; + std::auto_ptr d; +}; + + +} // of namespace simgear + +#endif // of SG_DEBUG_BUFFEREDLOGCALLBACK_HXX \ No newline at end of file diff --git a/simgear/debug/CMakeLists.txt b/simgear/debug/CMakeLists.txt index 70ede629..07690068 100644 --- a/simgear/debug/CMakeLists.txt +++ b/simgear/debug/CMakeLists.txt @@ -1,7 +1,7 @@ include (SimGearComponent) -set(HEADERS debug_types.h logstream.hxx) -set(SOURCES logstream.cxx) +set(HEADERS debug_types.h logstream.hxx BufferedLogCallback.hxx) +set(SOURCES logstream.cxx BufferedLogCallback.cxx) simgear_component(debug debug "${SOURCES}" "${HEADERS}") \ No newline at end of file diff --git a/simgear/debug/logstream.cxx b/simgear/debug/logstream.cxx index fd91aee5..589c4e67 100644 --- a/simgear/debug/logstream.cxx +++ b/simgear/debug/logstream.cxx @@ -133,54 +133,6 @@ private: sgDebugPriority m_priority; }; -namespace simgear -{ - -class BufferedLogCallback::BufferedLogCallbackPrivate -{ -public: - SGMutex m_mutex; - sgDebugClass m_class; - sgDebugPriority m_priority; - string_list m_buffer; -}; - -BufferedLogCallback::BufferedLogCallback(sgDebugClass c, sgDebugPriority p) : - d(new BufferedLogCallbackPrivate) -{ - d->m_class = c; - d->m_priority = p; -} - -BufferedLogCallback::~BufferedLogCallback() -{ -} - -void BufferedLogCallback::operator()(sgDebugClass c, sgDebugPriority p, - const char* file, int line, const std::string& aMessage) -{ - SG_UNUSED(file); - SG_UNUSED(line); - - if ((c & d->m_class) == 0 || p < d->m_priority) return; - - SGGuard g(d->m_mutex); - d->m_buffer.push_back(aMessage); -} - -void BufferedLogCallback::threadsafeCopy(string_list& aOutput) -{ - aOutput.clear(); - SGGuard g(d->m_mutex); - size_t sz = d->m_buffer.size(); - aOutput.resize(sz); - for (unsigned int i=0; im_buffer[i]; - } -} - -} // of namespace simgear - class LogStreamPrivate : public SGThread { private: diff --git a/simgear/debug/logstream.hxx b/simgear/debug/logstream.hxx index f50a4cc2..36816b63 100644 --- a/simgear/debug/logstream.hxx +++ b/simgear/debug/logstream.hxx @@ -28,11 +28,7 @@ #include #include -#include #include -#include // for std::auto_ptr - -typedef std::vector string_list; // forward decls class SGPath; @@ -48,27 +44,6 @@ public: const char* file, int line, const std::string& aMessage) = 0; }; - -class BufferedLogCallback : public LogCallback -{ -public: - BufferedLogCallback(sgDebugClass c, sgDebugPriority p); - virtual ~BufferedLogCallback(); - - virtual void operator()(sgDebugClass c, sgDebugPriority p, - const char* file, int line, const std::string& aMessage); - - /** - * copy the buffered log data into the provided output list - * (which will be cleared first). This method is safe to call from - * any thread. - */ - void threadsafeCopy(string_list& aOutput); -private: - class BufferedLogCallbackPrivate; - std::auto_ptr d; -}; - } // of namespace simgear /**