MRPT  1.9.9
CMyRedirector.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 #ifndef CMyRedirector_H
10 #define CMyRedirector_H
11 
12 #include <wx/string.h>
13 #include <wx/textctrl.h>
14 #include <wx/app.h>
15 #include <wx/thread.h>
16 #include <streambuf>
17 #include <iostream>
18 #include <cstdio>
19 #include <functional>
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;
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  char* ptr = new char[bufferSize];
64  setp(ptr, ptr + bufferSize);
65  }
66  else
67  setp(0, 0);
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  virtual ~CMyRedirector()
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  delete[] pbase();
89  }
90 
91  void flush() { sync(); }
92  virtual void writeString(const std::string& str)
93  {
94  if (!m_threadSafe)
95  {
96  wxString s;
97 #ifdef wxUSE_UNICODE
98  s = wxString(str.c_str(), wxConvUTF8);
99 #else
100  s = _U(str.c_str());
101 #endif
102 
103 #if wxCHECK_VERSION(3, 0, 0) && !defined(__APPLE__) // OSX build error?
104  m_txt->GetEventHandler()->CallAfter(&wxTextCtrl::WriteText, s);
105 #else
106  m_txt->WriteText(s); // bad solution, but at least compiles (and
107 // may work, unsafely) for old wx2.8 in Ubuntu
108 // precise
109 #endif
110  }
111  else
112  { // Critical section is already adquired.
113  m_strbuf += str;
114  }
115  if (m_also_to_cout_cerr) ::printf("%s", str.c_str());
116  if (m_yieldApplication && wxThread::IsMain())
117  wxTheApp->Yield(true); // Let the app. process messages
118  }
119 
120  /** Writes all the stored strings to the text control (only for threadSafe
121  mode).
122  CALL THIS METHOD FROM THE MAIN THREAD!
123  */
124  void dumpNow()
125  {
126  wxCriticalSectionLocker lock(m_cs);
127 
128  if (!m_strbuf.empty())
129  {
130  if (m_also_to_cout_cerr) ::printf("%s", m_strbuf.c_str());
131 #ifdef wxUSE_UNICODE
132  *m_txt << wxString(m_strbuf.c_str(), wxConvUTF8);
133 #else
134  *m_txt << _U(m_strbuf.c_str());
135 #endif
136  m_strbuf.clear();
137  }
138  }
139 
140  private:
141  int overflow(int c)
142  {
143  sync();
144 
145  if (c != EOF)
146  {
147  wxCriticalSectionLocker lock(m_cs);
148  if (pbase() == epptr())
149  {
150  std::string temp;
151  temp += char(c);
152  writeString(temp);
153  }
154  else
155  sputc(c);
156  }
157 
158  return 0;
159  }
160 
161  int sync()
162  {
163  wxCriticalSectionLocker lock(m_cs);
164 
165  if (pbase() != pptr())
166  {
167  int len = int(pptr() - pbase());
168  std::string temp(pbase(), len);
169  writeString(temp);
170  setp(pbase(), epptr());
171  }
172  return 0;
173  }
174 };
175 
176 #endif
virtual ~CMyRedirector()
Definition: CMyRedirector.h:79
const bool m_also_to_cout_cerr
Definition: CMyRedirector.h:45
#define _U(x)
Definition: WxSubsystem.h:503
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
GLdouble s
Definition: glext.h:3676
GLenum GLsizei len
Definition: glext.h:4712
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
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
const GLubyte * c
Definition: glext.h:6313
GLsizei const GLchar ** string
Definition: glext.h:4101
wxCriticalSection m_cs
Definition: CMyRedirector.h:47
virtual void writeString(const std::string &str)
Definition: CMyRedirector.h:92
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).
int overflow(int c)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020