MRPT  1.9.9
CMyRedirector.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #pragma once
10 
11 #include <wx/app.h>
12 #include <wx/string.h>
13 #include <wx/textctrl.h>
14 #include <wx/thread.h>
15 #include <cstdio>
16 #include <functional>
17 #include <iostream>
18 #include <streambuf>
19 
20 #include "wx28-fixes.h"
21 
22 /** This auxiliary class redirects the output sent to a streambuf to a
23  * wxTextCtrl object.
24  * Uses code from http://www.devmaster.net/forums/showthread.php?t=7037
25  * Jose Luis Blanco - Dec 2007
26  * NOTE (10-Aug-2009): Added thread-safe support:
27  * We cannot write in a wxTextCtrl from a thread different than the main wx
28  * one,
29  * so if this object will be used by several threads, set "m_threadSafe" to
30  * true.
31  * In this mode, the object will NEVER write the text to the text control,
32  * unless
33  * the method "dumpNow()" is explicitly called FROM THE MAIN THREAD.
34  */
35 class CMyRedirector : public std::streambuf
36 {
37  protected:
38  wxTextCtrl* m_txt;
39  std::streambuf* sbOld;
40  std::streambuf* sbOldErr;
41  const bool m_yieldApplication;
42  const bool m_also_cerr;
43  const bool m_threadSafe;
44  const bool m_also_to_cout_cerr;
45 
46  wxCriticalSection m_cs;
47  std::string m_strbuf;
48  std::vector<char> m_buf;
49 
50  public:
52  wxTextCtrl* obj, bool yieldApplication = false, int bufferSize = 3000,
53  bool also_cerr = false, bool threadSafe = false,
54  bool also_to_cout_cerr = false)
55  : m_txt(obj),
56  m_yieldApplication(yieldApplication),
57  m_also_cerr(also_cerr),
58  m_threadSafe(threadSafe),
59  m_also_to_cout_cerr(also_to_cout_cerr)
60  {
61  if (bufferSize)
62  {
63  m_buf.resize(bufferSize);
64  setp(&m_buf[0], &m_buf[bufferSize]);
65  }
66  else
67  setp(nullptr, nullptr);
68 
69  // Redirect:
70  sbOld = std::cout.rdbuf();
71  std::cout.rdbuf(this);
72 
73  if (m_also_cerr)
74  {
75  sbOldErr = std::cerr.rdbuf();
76  std::cerr.rdbuf(this);
77  }
78  }
79  ~CMyRedirector() override
80  {
81  sync();
82 
83  // Restore normal output:
84  std::cout.rdbuf(sbOld);
85 
86  if (m_also_cerr) std::cerr.rdbuf(sbOldErr);
87  }
88 
89  void flush() { sync(); }
90  virtual void writeString(const std::string& str)
91  {
92  if (!m_threadSafe)
93  {
94  const auto s = wxString(str);
95 
96 #if wxCHECK_VERSION(3, 0, 0) && !defined(__APPLE__) // OSX build error?
97  m_txt->GetEventHandler()->CallAfter(&wxTextCtrl::WriteText, s);
98 #else
99  m_txt->WriteText(s); // bad solution, but at least compiles (and
100 // may work, unsafely) for old wx2.8 in Ubuntu
101 // precise
102 #endif
103  }
104  else
105  { // Critical section is already adquired.
106  m_strbuf += str;
107  }
108  if (m_also_to_cout_cerr) ::printf("%s", str.c_str());
109  if (m_yieldApplication && wxThread::IsMain())
110  wxTheApp->Yield(true); // Let the app. process messages
111  }
112 
113  /** Writes all the stored strings to the text control (only for threadSafe
114  mode).
115  CALL THIS METHOD FROM THE MAIN THREAD!
116  */
117  void dumpNow()
118  {
119  wxCriticalSectionLocker lock(m_cs);
120 
121  if (!m_strbuf.empty())
122  {
123  if (m_also_to_cout_cerr) ::printf("%s", m_strbuf.c_str());
124 #ifdef wxUSE_UNICODE
125  *m_txt << wxString(m_strbuf.c_str(), wxConvUTF8);
126 #else
127  *m_txt << m_strbuf.c_str();
128 #endif
129  m_strbuf.clear();
130  }
131  }
132 
133  private:
134  int overflow(int c) override
135  {
136  sync();
137 
138  if (c != EOF)
139  {
140  wxCriticalSectionLocker lock(m_cs);
141  if (pbase() == epptr())
142  {
143  std::string temp;
144  temp += char(c);
145  writeString(temp);
146  }
147  else
148  sputc(c);
149  }
150 
151  return 0;
152  }
153 
154  int sync() override
155  {
156  wxCriticalSectionLocker lock(m_cs);
157 
158  if (pbase() != pptr())
159  {
160  int len = int(pptr() - pbase());
161  std::string temp(pbase(), len);
162  writeString(temp);
163  setp(pbase(), epptr());
164  }
165  return 0;
166  }
167 };
const bool m_also_to_cout_cerr
Definition: CMyRedirector.h:44
std::streambuf * sbOld
Definition: CMyRedirector.h:39
const bool m_also_cerr
Definition: CMyRedirector.h:42
wxTextCtrl * m_txt
Definition: CMyRedirector.h:38
const bool m_threadSafe
Definition: CMyRedirector.h:43
std::string m_strbuf
Definition: CMyRedirector.h:47
int sync() override
This auxiliary class redirects the output sent to a streambuf to a wxTextCtrl object.
Definition: CMyRedirector.h:35
const bool m_yieldApplication
Definition: CMyRedirector.h:41
std::streambuf * sbOldErr
Definition: CMyRedirector.h:40
int overflow(int c) override
wxCriticalSection m_cs
Definition: CMyRedirector.h:46
~CMyRedirector() override
Definition: CMyRedirector.h:79
virtual void writeString(const std::string &str)
Definition: CMyRedirector.h:90
std::vector< char > m_buf
Definition: CMyRedirector.h:48
CMyRedirector(wxTextCtrl *obj, bool yieldApplication=false, int bufferSize=3000, bool also_cerr=false, bool threadSafe=false, bool also_to_cout_cerr=false)
Definition: CMyRedirector.h:51
void dumpNow()
Writes all the stored strings to the text control (only for threadSafe mode).



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 338471620 Mon Feb 17 00:12:39 2020 +0100 at lun feb 17 00:15:10 CET 2020