Below are the two classes I have at the moment, both are work in progress mainly because I have reached a huge knowledge ceiling and have been resorting to trial and error for a few days now. I could use some help identifying all the major errors and/or misunderstandings in the code below.
P.S. The code below had all of the formatting removed. If someone could point out how to add it back in to make the code below legible, let me know and I'll fix it ASAP. Thanks to anyone who takes the time to read and/or offer feedback.
//CrawlerProcess.h
Code: Select all
enum class WorkerEvent {
SPIDERS_FINISHED,
END_OF_PROCESS,
};
class CrawlerProcess : public wxProcess {
protected:
wxWindow* m_parent;
wxString m_cmd;
public:
CrawlerProcess(wxWindow* parent, const wxString& cmd) :
m_cmd{ cmd },
wxProcess(parent)
{
m_parent = parent;
Redirect();
}
virtual bool HasInput();
};
Code: Select all
bool CrawlerProcess::HasInput() {
bool hasInput = false;
if (IsInputAvailable()) {
wxTextInputStream tis(*GetInputStream());
// this assumes that the output is always line buffered
wxString msg1;
msg1 << tis.ReadLine();
if (std::string::npos != msg1.find("DONE")) {
wxThreadEvent* te = new wxThreadEvent();
te->SetInt((int)WorkerEvent::SPIDERS_FINISHED);
wxQueueEvent(m_parent, te);
}
hasInput = true;
}
if (IsErrorAvailable()) {
wxTextInputStream tis(*GetErrorStream());
// this assumes that the output is always line buffered
wxString msg2;
msg2 << tis.ReadLine();
hasInput = true;
}
return hasInput;
}
Code: Select all
class ProcessFrame : public wxGenericProgressDialog {
private:
// the idle event wake up timer
wxTimer m_timerIdleWakeUp;
CrawlerProcess* process{};
wxTextInputStream* aasdf{};
protected:
// the checking if proc is done timer
wxTimer m_timerProcDone;
// the flag that indicates when process is done
bool proc_done = false;
BatFile m_bf;
int m_crawler_select;
public:
ProcessFrame(wxWindow* parent, int style, BatFile bf);
~ProcessFrame() {}
void Execute(wxString command);
void CreateAndShowProgressDlg();
void OnProcDoneTimer(wxTimerEvent& event);
void OnIdle(wxIdleEvent& event);
void OnComms(wxThreadEvent& event);
void OnProcessTerminated(wxProcessEvent& event);
};
Code: Select all
enum {
Exec_TimerIdle = 10,
Exec_TimerProcDone = 11
};
ProcessFrame::ProcessFrame(wxWindow* parent, int style, BatFile bf) :
m_timerIdleWakeUp(this, Exec_TimerIdle),
m_timerProcDone(this, Exec_TimerProcDone),
m_bf{bf},
//m_crawler_select{crawler_select},
wxGenericProgressDialog("In Progress", "Beginning", 100, parent, style)
{
//crawling process starts here asynchronously
this->Execute(m_bf.GetCommand());
m_timerProcDone.Start(500);
Bind(wxEVT_TIMER, &ProcessFrame::OnProcDoneTimer, this, Exec_TimerProcDone);
Bind(wxEVT_THREAD, &ProcessFrame::OnComms, this);
}
void ProcessFrame::Execute(wxString command) {
process = new CrawlerProcess(this, command);
process->Bind(wxEVT_END_PROCESS, &ProcessFrame::OnProcessTerminated, this);
process->Bind(wxEVT_END_PROCESS, &ProcessFrame::OnAsyncTerminated, this);
process->Redirect();
if (!wxExecute(command, wxEXEC_ASYNC, process)) {
delete process;
}
else {
m_timerIdleWakeUp.Start(100);
Bind(wxEVT_IDLE, &ProcessFrame::OnIdle, this);
CreateAndShowProgressDlg();
}
}
void ProcessFrame::CreateAndShowProgressDlg() {
Bind(wxEVT_TIMER, &ProcessFrame::OnProcDoneTimer, this, Exec_TimerProcDone);
Bind(wxEVT_THREAD, &ProcessFrame::OnComms, this);
}
void ProcessFrame::OnProcDoneTimer(wxTimerEvent & WXUNUSED(event)) {
if (proc_done) {
m_timerProcDone.Stop();
}
}
void ProcessFrame::OnIdle(wxIdleEvent & event) {
if (m_timerIdleWakeUp.IsRunning()) {
if (process->HasInput()) {
event.RequestMore();
}
}
}
void ProcessFrame::OnComms(wxThreadEvent & event) {
WorkerEvent we = (WorkerEvent)event.GetInt();
switch (we) {
case WorkerEvent::SPIDERS_FINISHED: {
this->Update(100, spider_close);
Unbind(wxEVT_IDLE, &ProcessFrame::OnIdle, this);
proc_done = true;
break;
}
case WorkerEvent::END_OF_PROCESS: {
this->Update(100, spider_close);
break;
}
}
}
void ProcessFrame::OnProcessTerminated(wxProcessEvent& event) {
m_timerIdleWakeUp.Stop();
}