]> git.mxchange.org Git - simgear.git/commitdiff
Logging tweaks.
authorJames Turner <zakalawe@mac.com>
Fri, 8 Feb 2013 19:37:29 +0000 (19:37 +0000)
committerJames Turner <zakalawe@mac.com>
Fri, 8 Feb 2013 19:37:29 +0000 (19:37 +0000)
More pieces to support logging to buffers in the GUI.

simgear/debug/BufferedLogCallback.cxx
simgear/debug/BufferedLogCallback.hxx
simgear/debug/logstream.cxx
simgear/debug/logstream.hxx

index 72d437c68d30985f2b029d64bb23f1c91c90b5c1..6fbe6e99379c00ab62667f337f4bb769d655bb54 100644 (file)
@@ -37,6 +37,8 @@ public:
     sgDebugClass m_class;
     sgDebugPriority m_priority;
     vector_cstring m_buffer;
+    unsigned int m_stamp;
+    unsigned int m_maxLength;
 };
    
 BufferedLogCallback::BufferedLogCallback(sgDebugClass c, sgDebugPriority p) :
@@ -44,6 +46,8 @@ BufferedLogCallback::BufferedLogCallback(sgDebugClass c, sgDebugPriority p) :
 {
     d->m_class = c;
     d->m_priority = p;
+    d->m_stamp = 0;
+    d->m_maxLength = 0xffff;
 }
 
 BufferedLogCallback::~BufferedLogCallback()
@@ -61,17 +65,37 @@ void BufferedLogCallback::operator()(sgDebugClass c, sgDebugPriority p,
     
     if ((c & d->m_class) == 0 || p < d->m_priority) return;
     
-    vector_cstring::value_type msg = (vector_cstring::value_type) strdup(aMessage.c_str());
+    vector_cstring::value_type msg;
+    if (aMessage.size() >= d->m_maxLength) {
+        msg = (vector_cstring::value_type) malloc(d->m_maxLength);
+        strncpy((char*) msg, aMessage.c_str(), d->m_maxLength - 1);
+        msg[d->m_maxLength - 1] = 0; // add final NULL byte
+    } else {
+        msg = (vector_cstring::value_type) strdup(aMessage.c_str());
+    }
+    
     SGGuard<SGMutex> g(d->m_mutex);
     d->m_buffer.push_back(msg);
+    d->m_stamp++;
+}
+unsigned int BufferedLogCallback::stamp() const
+{
+    return d->m_stamp;
 }
  
-void BufferedLogCallback::threadsafeCopy(vector_cstring& aOutput)
+unsigned int BufferedLogCallback::threadsafeCopy(vector_cstring& aOutput)
 {
     SGGuard<SGMutex> 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));
+    return d->m_stamp;
 } 
  
+void BufferedLogCallback::truncateAt(unsigned int t)
+{
+    d->m_maxLength = t;
+}
 } // of namespace simgear
index 21359fd96511854c442191e1cac3d0abcbc23219..f48ac3c023a7bff819e6c4b17ef48a69f2f10dfd 100644 (file)
@@ -37,9 +37,20 @@ public:
     BufferedLogCallback(sgDebugClass c, sgDebugPriority p);
     virtual ~BufferedLogCallback();
     
+    /// truncate messages longer than a certain length. This is to work-around
+    /// for broken PUI behaviour, it can be removed once PUI is gone.
+    void truncateAt(unsigned int);
+    
     virtual void operator()(sgDebugClass c, sgDebugPriority p, 
         const char* file, int line, const std::string& aMessage);
     
+    /**
+     * read the stamp value associated with the log buffer. This is
+     * incremented whenever the log contents change, so can be used
+     * to poll for changes.
+     */
+    unsigned int stamp() const;
+    
     /**
     * copying a (large) vector of std::string would be very expensive.
     * once logged, this call retains storage of the underlying string data,
@@ -53,8 +64,10 @@ public:
      * copy the buffered log data into the provided output list
      * (which will be cleared first). This method is safe to call from
      * any thread.
+     *
+     * returns the stamp value of the copied data
      */
-    void threadsafeCopy(vector_cstring& aOutput);
+    unsigned int threadsafeCopy(vector_cstring& aOutput);
 private:
     class BufferedLogCallbackPrivate;
     std::auto_ptr<BufferedLogCallbackPrivate> d;
index 589c4e67ca9428b6ce5972c5f0d499bdfd4b90d8..f3bcc99d49f7f98783fbe2e663dca181c024fd64 100644 (file)
@@ -157,6 +157,25 @@ private:
         int line;
         std::string message;
     };
+    
+    class PauseThread
+    {
+    public:
+        PauseThread(LogStreamPrivate* parent) : m_parent(parent)
+        {
+            m_wasRunning = m_parent->stop();
+        }
+        
+        ~PauseThread()
+        {
+            if (m_wasRunning) {
+                m_parent->startLog();
+            }
+        }
+    private:
+        LogStreamPrivate* m_parent;
+        bool m_wasRunning;
+    };
 public:
     LogStreamPrivate() :
         m_logClass(SG_ALL), 
@@ -169,7 +188,10 @@ public:
                     
     SGMutex m_lock;
     SGBlockingQueue<LogEntry> m_entries;
-    std::vector<simgear::LogCallback*> m_callbacks;    
+    
+    typedef std::vector<simgear::LogCallback*> CallbackVec;
+    CallbackVec m_callbacks;    
+    
     sgDebugClass m_logClass;
     sgDebugPriority m_logPriority;
     bool m_isRunning;
@@ -219,22 +241,25 @@ public:
     
     void addCallback(simgear::LogCallback* cb)
     {
-        bool wasRunning = stop();
+        PauseThread pause(this);
         m_callbacks.push_back(cb);
-        if (wasRunning) {
-            startLog();
+    }
+    
+    void removeCallback(simgear::LogCallback* cb)
+    {
+        PauseThread pause(this);
+        CallbackVec::iterator it = std::find(m_callbacks.begin(), m_callbacks.end(), cb);
+        if (it != m_callbacks.end()) {
+            m_callbacks.erase(it);
         }
     }
     
     void setLogLevels( sgDebugClass c, sgDebugPriority p )
     {
-        bool wasRunning = stop();
+        PauseThread pause(this);
         m_logPriority = p;
         m_logClass = c;
         m_stderrCallback->setLogLevels(c, p);
-        if (wasRunning) {
-            startLog();
-        }
     }
     
     bool would_log( sgDebugClass c, sgDebugPriority p ) const
@@ -274,6 +299,12 @@ logstream::addCallback(simgear::LogCallback* cb)
     global_privateLogstream->addCallback(cb);
 }
 
+void
+logstream::removeCallback(simgear::LogCallback* cb)
+{   
+    global_privateLogstream->removeCallback(cb);
+}
+
 void
 logstream::log( sgDebugClass c, sgDebugPriority p,
         const char* fileName, int line, const std::string& msg)
index 36816b63a72c1741a2e3afcf0ebb8b805d141a94..0af98c6a71a7d05dc5be344d6308e7c219b8c746 100644 (file)
@@ -93,9 +93,8 @@ public:
      * must use appropriate locking.
      */
     void addCallback(simgear::LogCallback* cb);
-    
-  //  friend logstream& sglog();
-//    static logstream *initGlobalLogstream();
+     
+    void removeCallback(simgear::LogCallback* cb);
 
 private:
     // constructor