44#include " PythonInterpCtrl.h"
55#include < globals.h>
66
7- DECLARE_LOCAL_EVENT_TYPE (wxEVT_PY_NOTIFY_UI_CODEOK, -1 )
7+ // DECLARE_LOCAL_EVENT_TYPE(wxEVT_PY_NOTIFY_UI_CODEOK, -1)
88DEFINE_EVENT_TYPE ( wxEVT_PY_NOTIFY_UI_CODEOK )
99
10- DECLARE_LOCAL_EVENT_TYPE (wxEVT_PY_NOTIFY_UI_INPUT, -1 )
10+ // DECLARE_LOCAL_EVENT_TYPE(wxEVT_PY_NOTIFY_UI_INPUT, -1)
1111DEFINE_EVENT_TYPE ( wxEVT_PY_NOTIFY_UI_INPUT )
1212
13- // //////////////////////////////////// PythonInterpJob /////////////////////////////////////////////
14-
15- bool PyInterpJob::operator ()()
16- {
17- // talk to m_client
18- // wxMessageBox(_("entered operator..."));
19- int status=0 ;
20- if (!pctl->RunCode (m_code,status))
21- return false ; // TODO: maybe retry before failing out completely
22- if (status>=0 )
23- {
24- wxCommandEvent pe (wxEVT_PY_NOTIFY_UI_CODEOK,0 );
25- ::wxPostEvent (parent,pe);
26- }
27- wxCommandEvent pe (wxEVT_PY_NOTIFY_UI_NOTIFY,0 );
28- ::wxPostEvent (parent,pe);
29- bool break_called=false ;
30- while (status>0 )
31- {
32- m_break_mutex.Lock ();
33- if (m_break_job && !break_called)
34- {
35- m_break_mutex.Unlock ();
36- if (pctl->BreakCode ())
37- break_called=true ;
38- } else
39- m_break_mutex.Unlock ();
40- bool line_input_request;
41- if (!pctl->Continue (status,line_input_request))
42- return false ; // TODO: maybe retry before failing out completely
43- // PyNotifyUIEvent pe(id,pyinst,parent,PYSTATE_NOTIFY);
44- ::wxPostEvent (parent,pe);
45- if (line_input_request)
46- {
47- pctl->m_input_mutex .Lock ();
48- wxCommandEvent ie (wxEVT_PY_NOTIFY_UI_INPUT,0 );
49- ::wxPostEvent (parent,ie);
50- pctl->m_input_cond ->Wait ();
51- pctl->m_input_mutex .Unlock ();
52- }
53- // sleep for some period of time
54- else
55- if (status>0 )
56- Sleep (50 ); // TODO: Make the sleep period user-defined
57- }
58- if (status==0 )
59- {
60- wxCommandEvent pef (wxEVT_PY_NOTIFY_UI_FINISHED,0 );
61- ::wxPostEvent (parent,pef);
62- } else
63- {
64- wxCommandEvent pef (wxEVT_PY_NOTIFY_UI_ABORTED,0 );
65- ::wxPostEvent (parent,pef);
66- }
67- return true ;
68- }
69-
70- void PyInterpJob::Break ()
71- {
72- m_break_mutex.Lock ();
73- m_break_job=true ;
74- m_break_mutex.Unlock ();
75- }
13+ // DECLARE_LOCAL_EVENT_TYPE(wxEVT_PY_PROC_END, -1)
14+ DEFINE_EVENT_TYPE ( wxEVT_PY_PROC_END )
7615
7716// //////////////////////////////////// PythonIOCtrl //////////////////////////////////////////////
7817
7918BEGIN_EVENT_TABLE (PythonIOCtrl, wxTextCtrl)
8019 EVT_CHAR (PythonIOCtrl::OnUserInput)
8120// EVT_TEXT(wxID_ANY, PythonIOCtrl::OnTextChange)
82- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_INPUT, PythonIOCtrl::OnLineInputRequest)
21+ // EVT_COMMAND(0, wxEVT_PY_NOTIFY_UI_INPUT, PythonIOCtrl::OnLineInputRequest)
8322END_EVENT_TABLE()
8423
8524void PythonIOCtrl::OnUserInput(wxKeyEvent& ke)
@@ -117,8 +56,6 @@ void PythonIOCtrl::OnUserInput(wxKeyEvent& ke)
11756 line.Replace (_T (" \n " ),_T (" " )); // will cause major problems if there is more than one line feed returned here, so we remove them (TODO: fix on server side?? server should treat buffered lines as new input without errors)
11857 line.Append (_T (" \n " ));
11958 m_pyctrl->stdin_append (line);
120- m_pyctrl->m_input_cond ->Signal ();
121- m_pyctrl->m_input_mutex .Unlock ();
12259 return ;
12360 }
12461 }
@@ -135,11 +72,10 @@ void PythonIOCtrl::OnTextChange(wxCommandEvent &e)
13572 e.Skip (true );
13673}
13774
138- void PythonIOCtrl::OnLineInputRequest (wxCommandEvent &e )
75+ void PythonIOCtrl::LineInputRequest ( )
13976{
14077 if (!m_line_entry_mode)
14178 {
142- m_pyctrl->m_input_mutex .Lock ();
14379 m_line_entry_mode=true ;
14480 m_line_entry_point=this ->GetLastPosition ();
14581 this ->SetSelection (m_line_entry_point,m_line_entry_point);
@@ -199,12 +135,9 @@ BEGIN_EVENT_TABLE(PythonInterpCtrl, wxPanel)
199135// EVT_PY_NOTIFY_UI(PythonInterpCtrl::OnPyNotify)
200136// EVT_END_PROCESS(ID_PROC, PythonInterpCtrl::OnEndProcess)
201137// EVT_LEFT_DCLICK(PythonInterpCtrl::OnDClick)
202- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_NOTIFY, PythonInterpCtrl::OnPyNotify)
203- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_CODEOK, PythonInterpCtrl::OnPyCode)
204- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_INPUT, PythonInterpCtrl::OnLineInputRequest)
205- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_STARTED, PythonInterpCtrl::OnPyNotify)
206- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_FINISHED, PythonInterpCtrl::OnPyJobDone)
207- EVT_COMMAND(0 , wxEVT_PY_NOTIFY_UI_ABORTED, PythonInterpCtrl::OnPyJobAbort)
138+ EVT_XMLRPC_RESPONSE(wxID_ANY, PythonInterpCtrl::OnPyNotify)
139+ // EVT_COMMAND(0, wxEVT_PY_NOTIFY_UI_CODEOK, PythonInterpCtrl::OnPyCode)
140+ // EVT_COMMAND(0, wxEVT_PY_NOTIFY_UI_INPUT, PythonInterpCtrl::OnLineInputRequest)
208141 EVT_COMMAND(0 , wxEVT_PY_PROC_END, PythonInterpCtrl::OnEndProcess)
209142
210143 EVT_SIZE (PythonInterpCtrl::OnSize)
@@ -215,7 +148,6 @@ PythonInterpCtrl::PythonInterpCtrl(wxWindow* parent, int id, const wxString &nam
215148 m_killlevel=0 ;
216149 m_port=0 ;
217150 m_pyinterp=NULL ;
218- m_input_cond=new wxCondition (m_input_mutex);
219151 m_sw=new wxSplitterWindow (this , wxID_ANY);
220152 m_ioctrl=new PythonIOCtrl (m_sw, this );// new wxTextCtrl(m_sw, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RICH|wxTE_MULTILINE|wxTE_READONLY|wxTE_PROCESS_ENTER|wxTE_PROCESS_TAB|wxEXPAND);
221153 m_codectrl=new PythonCodeCtrl (m_sw, this );
@@ -266,7 +198,13 @@ long PythonInterpCtrl::LaunchProcess(const wxString &processcmd, const wxArraySt
266198 }
267199 if (!global&&!local) // No interpreter script found, return failure.
268200 return -2 ; // TODO: Return meaningful messages (or at least use the codeblocks logger)
269- m_pyinterp=new PyInstance (cmd,_T (" localhost" ),m_port,this );
201+
202+ m_pyinterp = XmlRpcMgr::Get ().LaunchProcess (cmd,m_port);
203+ if (m_pyinterp->IsDead ())
204+ {
205+ Manager::Get ()->GetLogManager ()->Log (_ (" Error Starting Interpreter" ));
206+ return -1 ;
207+ }
270208 // TODO: Perform any initial communication with the running python process...
271209 return 1 ;
272210}
@@ -292,17 +230,48 @@ bool PythonInterpCtrl::DispatchCode(const wxString &code)
292230{
293231 if (m_pyinterp->IsJobRunning ())
294232 return false ;
295- m_pyinterp-> AddJob ( new PyInterpJob ( wxString (code. c_str ()),m_pyinterp, this ,m_ioctrl)) ;
233+ int status ;
296234 m_code=code;
235+ if (RunCode (wxString (code.c_str ())))
236+ {
237+ wxTextAttr oldta=m_ioctrl->GetDefaultStyle ();
238+ wxTextAttr ta=oldta;
239+ wxFont f=ta.GetFont ();
240+ f.SetWeight (wxFONTWEIGHT_BOLD);
241+ ta.SetFont (f);
242+ m_ioctrl->SetDefaultStyle (ta);
243+ m_ioctrl->AppendText (m_code);
244+ m_ioctrl->SetDefaultStyle (oldta);
245+ m_ioctrl->AppendText (_T (" \n " ));
246+ // wxCommandEvent pe(wxEVT_PY_NOTIFY_UI_CODEOK,0);
247+ // ::wxPostEvent(this,pe);
248+ }
297249 return true ;
298250}
299251
300- void PythonInterpCtrl::OnPyNotify (wxCommandEvent & event)
252+ void PythonInterpCtrl::OnPyNotify (XmlRpcResponseEvent & event)
301253{
302- if (m_ioctrl->m_line_entry_mode )
303- return ;
304- m_ioctrl->AppendText (stdout_retrieve ());
305- m_ioctrl->AppendText (stderr_retrieve ());
254+ // if(m_ioctrl->m_line_entry_mode)
255+ // return;
256+ if (event.GetState ()==XMLRPC_STATE_RESPONSE )
257+ {
258+ XmlRpc::XmlRpcValue val = event.GetResponse ();
259+ int return_code = val[0 ];
260+ std::string stdout (val[1 ]);
261+ std::string stderr (val[2 ]);
262+ int input_request = val[3 ];
263+
264+ m_ioctrl->AppendText (wxString (stdout.c_str (),wxConvUTF8));
265+ // TODO: Color errors
266+ m_ioctrl->AppendText (wxString (stderr.c_str (),wxConvUTF8));
267+
268+ if (input_request)
269+ m_ioctrl->ProcessEvent (event);
270+
271+ if (return_code == 1 )
272+ this ->Continue ();
273+ }
274+ // TODO: If not in error and more input available, need to call RunCode("cont")
306275}
307276
308277void PythonInterpCtrl::OnLineInputRequest (wxCommandEvent& event)
@@ -426,106 +395,34 @@ void PythonInterpCtrl::OnUserInput(wxKeyEvent& ke)
426395// m_ioctrl->SetInsertionPointEnd();
427396}
428397
429- void PythonInterpCtrl::stdin_append (const wxString &data)
430- { // asynchronously dispatch data to python interpreter's stdin
431- wxMutexLocker ml (io_mutex);
432- stdin_data+=data;
433- }
434-
435- void PythonInterpCtrl::stdout_append (const wxString &data)
436- { // asynchronously dispatch data to python interpreter's stdin
437- wxMutexLocker ml (io_mutex);
438- stdout_data+=data;
439- }
440-
441- void PythonInterpCtrl::stderr_append (const wxString &data)
442- { // asynchronously dispatch data to python interpreter's stdin
443- wxMutexLocker ml (io_mutex);
444- stderr_data+=data;
445- }
446-
447- wxString PythonInterpCtrl::stdin_retrieve ()
448- {
449- wxMutexLocker ml (io_mutex);
450- wxString s (stdin_data);
451- stdin_data=_T (" " );
452- return s;
453- }
454-
455- wxString PythonInterpCtrl::stdout_retrieve ()
456- {
457- wxMutexLocker ml (io_mutex);
458- wxString s (stdout_data);
459- stdout_data=_T (" " );
460- return s;
461- }
462-
463- wxString PythonInterpCtrl::stderr_retrieve ()
464- {
465- wxMutexLocker ml (io_mutex);
466- wxString s (stderr_data);
467- stderr_data=_T (" " );
468- return s;
469- }
470398
471- bool PythonInterpCtrl::RunCode (const wxString &codestr, int &status )
399+ bool PythonInterpCtrl::RunCode (const wxString &codestr)
472400{
401+ // TODO: Should use a common ID for this and cont
473402 XmlRpc::XmlRpcValue args, result;
474403 args[0 ]=codestr.utf8_str ();
475404 args[1 ]=stdin_retrieve ().utf8_str ();
476- if (m_pyinterp->Exec (_ (" run_code" ), args, result))
477- {
478- status=result[0 ];
479- std::string r1=result[1 ];
480- stdout_append (wxString::FromUTF8 (r1.c_str ()));
481- std::string r2=result[2 ];
482- stderr_append (wxString::FromUTF8 (r2.c_str ()));
483- return true ;
484- }
485- status=-4 ;
486- return false ;
405+ return m_pyinterp->ExecAsync (_T (" run_code" ), args, this );
487406}
488407
489- bool PythonInterpCtrl::Continue (int &status, bool &line_input_request )
408+ bool PythonInterpCtrl::Continue ()
490409{
491410 XmlRpc::XmlRpcValue args, result;
492411 args[0 ]=stdin_retrieve ().utf8_str ();
493- if (m_pyinterp->Exec (_ (" cont" ), args, result))
494- {
495- status=result[0 ];
496- std::string r1=result[1 ];
497- stdout_append (wxString::FromUTF8 (r1.c_str ()));
498- std::string r2=result[2 ];
499- stderr_append (wxString::FromUTF8 (r2.c_str ()));
500- line_input_request=result[3 ];
501- return true ;
502- }
503- status=-4 ;
504- return false ;
412+ return m_pyinterp->ExecAsync (_ (" cont" ), args, this );
505413}
506414
507415bool PythonInterpCtrl::BreakCode ()
508416{
509- m_pyinterp->Break ();
510- return true ;
511- XmlRpc::XmlRpcValue args, result;
512- if (m_pyinterp->Exec (_ (" break_code" ), args, result))
513- {
514- // TODO: evaluate result -- if it not true, there was no code running
515- wxMessageBox (_ (" break sent" ));
516- return true ;
517- }
518- wxMessageBox (_ (" break not sent" ));
519- return false ;
417+ // TODO: Need to use a separate ID for this
418+ XmlRpc::XmlRpcValue args;
419+ return m_pyinterp->ExecAsync (_ (" break_code" ), args, this );
520420}
521421
522422bool PythonInterpCtrl::SendKill ()
523423{
424+ // TODO: Need to use a separate ID for this
524425 XmlRpc::XmlRpcValue args, result;
525- if (m_pyinterp->Exec (_ (" end" ), args, result))
526- {
527- return true ;
528- }
529- return false ;
426+ return m_pyinterp->ExecAsync (_ (" end" ), args, this );
530427}
531428
0 commit comments