Skip to content

Commit

Permalink
Added new function CreateAsyncProcessCB which instead of using the st…
Browse files Browse the repository at this point in the history
…andard events it uses callback object (with 2 functions: OnProcessOutput and OnProcessTerminated) these functions are calling using wxEvtHandler::CallAfter method
  • Loading branch information
eranif committed Oct 13, 2013
1 parent e4926c4 commit 57cb33a
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 181 deletions.
40 changes: 25 additions & 15 deletions CodeLite/asyncprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,35 @@ class IProcess;
IProcess* CreateAsyncProcess(wxEvtHandler *parent, const wxString& cmd, IProcessCreateFlags flags, const wxString &workingDir)
{
#ifdef __WXMSW__
wxString errMsg;
return WinProcessImpl::Execute(parent, cmd, errMsg, flags, workingDir);
wxString errMsg;
return WinProcessImpl::Execute(parent, cmd, errMsg, flags, workingDir);
#else
return UnixProcessImpl::Execute(parent, cmd, flags, workingDir);
return UnixProcessImpl::Execute(parent, cmd, flags, workingDir);
#endif
}

IProcess* CreateAsyncProcessCB(wxEvtHandler *parent, IProcessCallback* cb, const wxString& cmd, IProcessCreateFlags flags, const wxString &workingDir)
{
#ifdef __WXMSW__
wxString errMsg;
return WinProcessImpl::Execute(parent, cmd, errMsg, flags, workingDir, cb);
#else
return UnixProcessImpl::Execute(parent, cmd, flags, workingDir, cb);
#endif
}

// Static methods:
bool IProcess::GetProcessExitCode(int pid, int &exitCode)
bool IProcess::GetProcessExitCode(int pid, int &exitCode)
{
wxUnusedVar(pid);
wxUnusedVar(exitCode);
exitCode = 0;
return true;
}

void IProcess::SetProcessExitCode(int pid, int exitCode)
wxUnusedVar(pid);
wxUnusedVar(exitCode);

exitCode = 0;
return true;
}

void IProcess::SetProcessExitCode(int pid, int exitCode)
{
wxUnusedVar(pid);
wxUnusedVar(exitCode);
}
wxUnusedVar(pid);
wxUnusedVar(exitCode);
}
189 changes: 111 additions & 78 deletions CodeLite/asyncprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,85 +23,118 @@
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

#ifndef I_PROCESS_H
#define I_PROCESS_H

#include <wx/string.h>
#include <wx/event.h>
#ifndef I_PROCESS_H
#define I_PROCESS_H

#include <wx/string.h>
#include <wx/event.h>
#include "codelite_exports.h"
#include <map>

enum IProcessCreateFlags {
IProcessCreateDefault = 0x0000001, // Default: create process with no console window
IProcessCreateConsole = 0x0000002, // Create with console window shown
IProcessCreateWithHiddenConsole = 0x0000004 // Create process with a hidden console
};

/**
* @class IProcess
* @author eran
* @date 10/09/09
* @file i_process.h
* @brief
*/
class WXDLLIMPEXP_CL IProcess

enum IProcessCreateFlags {
IProcessCreateDefault = 0x0000001, // Default: create process with no console window
IProcessCreateConsole = 0x0000002, // Create with console window shown
IProcessCreateWithHiddenConsole = 0x0000004 // Create process with a hidden console
};

class WXDLLIMPEXP_CL IProcess;
class WXDLLIMPEXP_CL IProcessCallback : public wxEvtHandler
{
public:
virtual void OnProcessOutput(const wxString &str) {
wxUnusedVar(str);
}
virtual void OnProcessTerminated() {}
};

/**
* @class IProcess
* @author eran
* @date 10/09/09
* @file i_process.h
* @brief
*/
class WXDLLIMPEXP_CL IProcess
{
protected:
wxEvtHandler * m_parent;
int m_pid;
bool m_hardKill;

public:
IProcess(wxEvtHandler *parent) : m_parent(parent), m_pid(-1), m_hardKill(false) {}
virtual ~IProcess() {}

protected:
wxEvtHandler * m_parent;
int m_pid;
bool m_hardKill;
IProcessCallback* m_callback;

public:
// Handle process exit code. This is done this way this
// under Linux / Mac the exit code is returned only after the signal child has been
// handled by codelite
static void SetProcessExitCode(int pid, int exitCode);
static bool GetProcessExitCode(int pid, int &exitCode);

// Read from process stdout - return immediately if no data is available
virtual bool Read(wxString& buff) = 0;

// Write to the process stdin
virtual bool Write(const wxString& buff) = 0;

/**
* @brief this method is mostly needed on MSW where writing a password
* is done directly on the console buffer rather than its stdin
*/
virtual bool WriteToConsole(const wxString &buff) = 0;

// Return true if the process is still alive
virtual bool IsAlive() = 0;

// Clean the process resources and kill the process if it is
// still alive
virtual void Cleanup() = 0;

// Terminate the process. It is recommended to use this method
// so it will invoke the 'Cleaup' procedure and the process
// termination event will be sent out
virtual void Terminate() = 0;

void SetPid(int pid) {
this->m_pid = pid;
}

int GetPid() const {
return m_pid;
}

void SetHardKill(bool hardKill) {
this->m_hardKill = hardKill;
}
bool GetHardKill() const {
return m_hardKill;
}
};

// Help method
WXDLLIMPEXP_CL IProcess* CreateAsyncProcess(wxEvtHandler *parent, const wxString& cmd, IProcessCreateFlags flags = IProcessCreateDefault, const wxString &workingDir = wxEmptyString);
#endif // I_PROCESS_H
IProcess(wxEvtHandler *parent) : m_parent(parent), m_pid(-1), m_hardKill(false), m_callback(NULL) {}
virtual ~IProcess() {}

public:
// Handle process exit code. This is done this way this
// under Linux / Mac the exit code is returned only after the signal child has been
// handled by codelite
static void SetProcessExitCode(int pid, int exitCode);
static bool GetProcessExitCode(int pid, int &exitCode);

// Read from process stdout - return immediately if no data is available
virtual bool Read(wxString& buff) = 0;

// Write to the process stdin
virtual bool Write(const wxString& buff) = 0;

/**
* @brief this method is mostly needed on MSW where writing a password
* is done directly on the console buffer rather than its stdin
*/
virtual bool WriteToConsole(const wxString &buff) = 0;

// Return true if the process is still alive
virtual bool IsAlive() = 0;

// Clean the process resources and kill the process if it is
// still alive
virtual void Cleanup() = 0;

// Terminate the process. It is recommended to use this method
// so it will invoke the 'Cleaup' procedure and the process
// termination event will be sent out
virtual void Terminate() = 0;

void SetPid(int pid) {
this->m_pid = pid;
}

int GetPid() const {
return m_pid;
}

void SetHardKill(bool hardKill) {
this->m_hardKill = hardKill;
}
bool GetHardKill() const {
return m_hardKill;
}
IProcessCallback* GetCallback() {
return m_callback;
}
};

// Help method
/**
* @brief start process
* @param parent the parent. all events will be sent to this object
* @param cmd command line to execute
* @param flags possible creation flag
* @param workingDir set the working directory of the executed process
* @return
*/
WXDLLIMPEXP_CL IProcess* CreateAsyncProcess(wxEvtHandler *parent, const wxString& cmd, IProcessCreateFlags flags = IProcessCreateDefault, const wxString &workingDir = wxEmptyString);
/**
* @brief start process
* @brief cb callback object. Instead of events, OnProcessOutput and OnProcessTerminated will be called respectively
* @param parent the parent. all events will be sent to this object
* @param cmd command line to execute
* @param flags possible creation flag
* @param workingDir set the working directory of the executed process
* @return
*/
WXDLLIMPEXP_CL IProcess* CreateAsyncProcessCB(wxEvtHandler *parent, IProcessCallback* cb, const wxString& cmd, IProcessCreateFlags flags = IProcessCreateDefault, const wxString &workingDir = wxEmptyString);

#endif // I_PROCESS_H
52 changes: 35 additions & 17 deletions CodeLite/processreaderthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,31 +56,49 @@ void* ProcessReaderThread::Entry()
wxString buff;
if(m_process->Read( buff )) {
if( buff.IsEmpty() == false ) {
// we got some data, send event to parent
wxCommandEvent e(wxEVT_PROC_DATA_READ);

// If we got a callback object, use it
if ( m_process && m_process->GetCallback() ) {
m_process->GetCallback()->CallAfter( &IProcessCallback::OnProcessOutput, buff );

} else {
// fallback to the event system
// we got some data, send event to parent
wxCommandEvent e(wxEVT_PROC_DATA_READ);
ProcessEventData *ed = new ProcessEventData();
ed->SetData(buff);
ed->SetProcess( m_process );

e.SetClientData( ed );
if ( m_notifiedWindow ) {
m_notifiedWindow->AddPendingEvent( e );

} else {
wxDELETE(ed);
}

}
}
} else {

// Process terminated, exit
// If we got a callback object, use it
if ( m_process && m_process->GetCallback() ) {
m_process->GetCallback()->CallAfter( &IProcessCallback::OnProcessTerminated );

} else {
// fallback to the event system
wxCommandEvent e(wxEVT_PROC_TERMINATED);
ProcessEventData *ed = new ProcessEventData();
ed->SetData(buff);
ed->SetProcess( m_process );

e.SetClientData( ed );

if ( m_notifiedWindow ) {
m_notifiedWindow->AddPendingEvent( e );
} else {
delete ed;
wxDELETE(ed);
}
}
} else {
// Process terminated??, exit
wxCommandEvent e(wxEVT_PROC_TERMINATED);
ProcessEventData *ed = new ProcessEventData();
ed->SetProcess( m_process );
e.SetClientData( ed );

if ( m_notifiedWindow ) {
m_notifiedWindow->AddPendingEvent( e );
} else {
delete ed;
}
break;
}
}
Expand Down
3 changes: 2 additions & 1 deletion CodeLite/unixprocess_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ bool UnixProcessImpl::Write(const wxString& buff)
return bytes == (int)tmpbuf.length();
}

IProcess* UnixProcessImpl::Execute(wxEvtHandler* parent, const wxString& cmd, IProcessCreateFlags flags, const wxString& workingDirectory)
IProcess* UnixProcessImpl::Execute(wxEvtHandler* parent, const wxString& cmd, IProcessCreateFlags flags, const wxString& workingDirectory, IProcessCallback *cb)
{
wxUnusedVar(flags);

Expand Down Expand Up @@ -409,6 +409,7 @@ IProcess* UnixProcessImpl::Execute(wxEvtHandler* parent, const wxString& cmd, IP
wxSetWorkingDirectory(curdir);

UnixProcessImpl *proc = new UnixProcessImpl(parent);
proc->m_callback = cb;
proc->SetReadHandle (master);
proc->SetWriteHandler(master);

Expand Down
52 changes: 26 additions & 26 deletions CodeLite/unixprocess_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,40 @@
class wxTerminal;
class WXDLLIMPEXP_CL UnixProcessImpl : public IProcess
{
int m_readHandle;
int m_writeHandle;
ProcessReaderThread *m_thr;
int m_readHandle;
int m_writeHandle;
ProcessReaderThread *m_thr;

friend class wxTerminal;
friend class wxTerminal;
private:
void StartReaderThread();
void StartReaderThread();

public:
UnixProcessImpl(wxEvtHandler *parent);
virtual ~UnixProcessImpl();
UnixProcessImpl(wxEvtHandler *parent);
virtual ~UnixProcessImpl();

static IProcess *Execute(wxEvtHandler *parent, const wxString &cmd, IProcessCreateFlags flags, const wxString &workingDirectory = wxEmptyString);
static IProcess *Execute(wxEvtHandler *parent, const wxString &cmd, IProcessCreateFlags flags, const wxString &workingDirectory = wxEmptyString, IProcessCallback *cb = NULL);

void SetReadHandle(const int& readHandle) {
this->m_readHandle = readHandle;
}
void SetWriteHandler(const int& writeHandler) {
this->m_writeHandle = writeHandler;
}
const int& GetReadHandle() const {
return m_readHandle;
}
const int& GetWriteHandle() const {
return m_writeHandle;
}
void SetReadHandle(const int& readHandle) {
this->m_readHandle = readHandle;
}
void SetWriteHandler(const int& writeHandler) {
this->m_writeHandle = writeHandler;
}
const int& GetReadHandle() const {
return m_readHandle;
}
const int& GetWriteHandle() const {
return m_writeHandle;
}

public:
virtual void Cleanup();
virtual bool IsAlive();
virtual bool Read(wxString& buff);
virtual bool Write(const wxString& buff);
virtual void Terminate();
virtual bool WriteToConsole(const wxString& buff);
virtual void Cleanup();
virtual bool IsAlive();
virtual bool Read(wxString& buff);
virtual bool Write(const wxString& buff);
virtual void Terminate();
virtual bool WriteToConsole(const wxString& buff);

};
#endif //#if defined(__WXMAC )||defined(__WXGTK__)
Expand Down
Loading

0 comments on commit 57cb33a

Please sign in to comment.