Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development
PipedProcess usage?
Pecan:
--- Quote from: dmoore on October 30, 2006, 09:41:02 pm ---so what is the standard way of converting int/float/double to a unicode wxString and back? operator<<, operator>> and the relevant constructor appear to simply fail without warning.
--- End quote ---
"...simply fail without warning." So true! Unicode string streaming is terrible.
The following code snippets from others may be of interest to you.
--- Code: ---#include <sstream>
// Read in and set window position --------------------------------
wxFileConfig cfgFile(wxTheApp->GetAppName(), // appname
wxEmptyString, // vendor
wxEmptyString, // local filename
wxEmptyString, // global file
wxCONFIG_USE_LOCAL_FILE);
wxString winPos;
cfgFile.Read(_T("WindowPosition"), &winPos) ;
if ( not winPos.IsEmpty() )
{ long windowXpos, windowYpos, windowWidth, windowHeight;
wxWX2MBbuf buf = cbU2C(winPos);
std::string cstring( buf );
std::stringstream istream(cstring);
istream >> windowXpos ;
istream >> windowYpos ;
istream >> windowWidth ;
istream >> windowHeight ;
this->SetSize(windowXpos, windowYpos, windowWidth, windowHeight);
}
// Record position ------------------------------------------------------
wxFileConfig cfgFile(g_AppName, // appname
wxEmptyString, // vendor
wxEmptyString, // local filename
wxEmptyString, // global file
wxCONFIG_USE_LOCAL_FILE);
wxWindow* pwin = wxTheApp->GetTopWindow();
int winXposn, winYposn, winWidth, winHeight;
pwin->GetPosition( &winXposn, &winYposn );
pwin->GetSize( &winWidth, &winHeight );
// Using std::stringstream; wxStringStream dont work in unicode
std::string cwinPos;
std::ostringstream ostream;
ostream << winXposn <<" " << winYposn <<" " << winWidth <<" " <<winHeight;
cwinPos = ostream.str();
wxString winPos = cbC2U( cwinPos.c_str());
cfgFile.Write(_T("WindowPosition"), winPos) ;
// This could also be done as:
winPos = winPos.Format(wxT("%d %d %d %d"),
winXposn, winYposn, winWidth, winHeight);
--- End code ---
Conversions:
--- Code: ---#include <wx/string.h>
// Return @c str as a proper unicode-compatible string
wxString cbC2U(const char* str)
{
#if wxUSE_UNICODE
return wxString(str, wxConvUTF8);
#else
return wxString(str);
#endif
}
// Return multibyte (C string) representation of the string
wxWX2MBbuf cbU2C(const wxString& str)
{
#if wxUSE_UNICODE
return str.mb_str(wxConvUTF8);
#else
return (wxChar*)str.mb_str();
#endif
}
--- End code ---
dmoore:
--- Quote from: mandrav on October 30, 2006, 10:29:46 pm ---No, no...
EVT_PIPEDPROCESS_STDOUT works fine (proven).
PipedProcess::Launch() doesn't work and it's not used.
--- End quote ---
whoops. anyway, I went back to basics and did some exploration with wxProcess to pipe a simple python debug session and send something down the output stream and retrieve from the input stream - this works - see code snippet below. Perhaps someone can tell me how it could be done more efficiently with a PipedProcess and the role of the Idle message handler (I tried to implement the latter but it just crashed C::B). I'm still confused by PipedProcess - do i need to setup a wxTimer to poll stdout buffer, or does processing EVT_PIPEDPROCESS_STDOUT handle all this for me. The latter doesn't seem to be the case, and if not how do I tell EVT_PIPEDPROCESS_STDOUT to hijack the timer that I create?? Sacrificing a goat to Bjarne + going through the source code, macro definitions, wxWidgets docs and C::B wikis trying to figure this out is killing me - I had a hard enough time with the python interpreter until i realized it doesn't update stdin and stdout if you don't specify the right set of options
--- Code: ---BEGIN_EVENT_TABLE(InterpretedLangs, cbPlugin)
EVT_MENU(ID_LangMenu_RunPiped,InterpretedLangs::OnRunPiped)
EVT_TIMER(ID_TimerPollDebugger, InterpretedLangs::OnTimer)
...
END_EVENT_TABLE()
void InterpretedLangs::OnTimer(wxTimerEvent& event)
{
if (m_pp && m_pp->IsInputAvailable())
{
char buf0[1001]; //Sloppy i know - was in a hurry
for(int i=0;i<1001;++i)
buf0[i]=0;
m_istream->Read(buf0,1000);
wxString sbuf=wxString::FromAscii(buf0);
wxMessageBox(sbuf);
}
}
void InterpretedLangs::OnRunPiped(wxCommandEvent &event)
{
m_TimerPollDebugger=new wxTimer(this, ID_TimerPollDebugger);
m_TimerPollDebugger->Start(100);
m_pp=new wxProcess(this,ID_PipedProcess);
m_pp->Redirect();
wxExecute(_T("c:/python25/python.exe -u -m pdb c:/python25/test.py"),wxEXEC_ASYNC,m_pp);
m_ostream=m_pp->GetOutputStream();
m_ostream->Write("w\n",2);
m_istream=m_pp->GetInputStream();
}
--- End code ---
--- Quote ---wxString::Format(_T("%d, %5.2f"), i, f);
--- End quote ---
color me pleasantly surprised. I gave up on the wxstring stream style commands after wxstring::printf didn't work.
dmoore:
--- Quote from: mandrav on October 30, 2006, 10:29:46 pm ---No, no...
EVT_PIPEDPROCESS_STDOUT works fine (proven).
--- End quote ---
ok, so maybe i was a little bit lazy before writing my previous post, so I went back and studied various bits of CB source a little more closely and read up some more on wxWidgets (and slaughtered a few goats along the way). Having done that, I'm not sure I would say that EVT_PIPEDPROCESS_STDOUT works fine since you have to define your own timer to force idle events in order to ever see EVT_PIPEDPROCESS_STDOUT messages. While this is the fault of wxWidgets, it still introduces a bunch of redundancy to have to declare a timer every time I want to use PipedProcess and will cause problems down the road if wxWidgets ever sorts out this problem with idle events: Every plugin that uses the PipedProcess will need to be modified to remove the redundant timers. Shouldn't PipedProcess create its owner timer and idle events, which it can use to generate EVT_PIPEDPROCESS_STDOUT messages? (Presumably that's what PipedProcess::Launch was for?) At least then when wxWidgets gets its act together on this, it's only one module that needs fixing.
Finally, it is also unclear to me that idle time processing is necessarily going to be more efficient for piping stdout/stderr than just starting/stopping a wxTimer as needed by any given plugin. I can imagine a dozen or more plugins receiving idle events when only one of them is actually active (although they should all just return quickly). Each programmer would need to take care to declare their plugins in such a way that they only receive idle messages while in their activated state.
Navigation
[0] Message Index
[*] Previous page
Go to full version