Main MRPT website > C++ reference for MRPT 1.5.3
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-2017, 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 
24 /** This auxiliary class redirects the output sent to a streambuf to a 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 one,
29  * so if this object will be used by several threads, set "m_threadSafe" to true.
30  * In this mode, the object will NEVER write the text to the text control, unless
31  * the method "dumpNow()" is explicitly called FROM THE MAIN THREAD.
32  */
33 class CMyRedirector : public std::streambuf
34 {
35 protected:
36  wxTextCtrl *m_txt;
37  std::streambuf *sbOld;
38  std::streambuf *sbOldErr;
39  const bool m_yieldApplication;
40  const bool m_also_cerr;
41  const bool m_threadSafe;
42  const bool m_also_to_cout_cerr;
43 
44  wxCriticalSection m_cs;
45  std::string m_strbuf;
46 
47 public:
49  wxTextCtrl *obj,
50  bool yieldApplication = false,
51  int bufferSize = 3000,
52  bool also_cerr = false,
53  bool threadSafe = false,
54  bool also_to_cout_cerr = false ) : m_txt(obj), m_yieldApplication(yieldApplication), m_also_cerr(also_cerr),m_threadSafe(threadSafe), m_also_to_cout_cerr(also_to_cout_cerr)
55  {
56  if (bufferSize)
57  {
58  char *ptr = new char[bufferSize];
59  setp(ptr, ptr + bufferSize);
60  }
61  else
62  setp(0, 0);
63 
64  // Redirect:
65  sbOld = std::cout.rdbuf();
66  std::cout.rdbuf( this );
67 
68  if (m_also_cerr)
69  {
70  sbOldErr = std::cerr.rdbuf();
71  std::cerr.rdbuf( this );
72  }
73  }
74  virtual ~CMyRedirector()
75  {
76  sync();
77 
78  // Restore normal output:
79  std::cout.rdbuf(sbOld);
80 
81  if (m_also_cerr)
82  std::cerr.rdbuf(sbOldErr);
83 
84  delete[] pbase();
85  }
86 
87  void flush()
88  {
89  sync();
90  }
91 
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)
104  m_txt->GetEventHandler()->CallAfter(&wxTextCtrl::WriteText, s);
105 #else
106  m_txt->WriteText(s); // bad solution, but at least compiles (and may work, unsafely) for old wx2.8 in Ubuntu precise
107 #endif
108  }
109  else
110  { // Critical section is already adquired.
111  m_strbuf+=str;
112  }
113  if (m_also_to_cout_cerr) ::printf("%s",str.c_str());
114  if (m_yieldApplication && wxThread::IsMain()) wxTheApp->Yield(true); // Let the app. process messages
115  }
116 
117  /** Writes all the stored strings to the text control (only for threadSafe mode).
118  CALL THIS METHOD FROM THE MAIN THREAD!
119  */
120  void dumpNow()
121  {
122  wxCriticalSectionLocker lock(m_cs);
123 
124  if (!m_strbuf.empty())
125  {
126  if (m_also_to_cout_cerr) ::printf("%s",m_strbuf.c_str());
127 #ifdef wxUSE_UNICODE
128  *m_txt << wxString( m_strbuf.c_str(), wxConvUTF8 );
129 #else
130  *m_txt << _U( m_strbuf.c_str() );
131 #endif
132  m_strbuf.clear();
133  }
134  }
135 
136 private:
137  int overflow(int c)
138  {
139  sync();
140 
141  if (c != EOF)
142  {
143  wxCriticalSectionLocker lock(m_cs);
144  if (pbase() == epptr())
145  {
146  std::string temp;
147  temp += char(c);
148  writeString(temp);
149  }
150  else
151  sputc(c);
152  }
153 
154  return 0;
155  }
156 
157  int sync()
158  {
159  wxCriticalSectionLocker lock(m_cs);
160 
161  if (pbase() != pptr())
162  {
163  int len = int(pptr() - pbase());
164  std::string temp(pbase(), len);
165  writeString(temp);
166  setp(pbase(), epptr());
167  }
168  return 0;
169  }
170 };
171 
172 #endif
virtual ~CMyRedirector()
Definition: CMyRedirector.h:74
const bool m_also_to_cout_cerr
Definition: CMyRedirector.h:42
#define _U(x)
Definition: WxSubsystem.h:469
std::streambuf * sbOld
Definition: CMyRedirector.h:37
const bool m_also_cerr
Definition: CMyRedirector.h:40
wxTextCtrl * m_txt
Definition: CMyRedirector.h:36
const bool m_threadSafe
Definition: CMyRedirector.h:41
std::string m_strbuf
Definition: CMyRedirector.h:45
This auxiliary class redirects the output sent to a streambuf to a wxTextCtrl object.
Definition: CMyRedirector.h:33
const bool m_yieldApplication
Definition: CMyRedirector.h:39
std::streambuf * sbOldErr
Definition: CMyRedirector.h:38
wxCriticalSection m_cs
Definition: CMyRedirector.h:44
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:48
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.13 for MRPT 1.5.3 at Tue Aug 22 01:03:35 UTC 2017