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



Page generated by Doxygen 1.8.14 for MRPT 2.0.3 Git: 8e9e8af54 Wed May 13 17:41:24 2020 +0200 at miƩ may 13 17:55:54 CEST 2020