forked from eranif/codelite
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented: Feature Request: external tool: multi instances
fixes: eranif#1016
- Loading branch information
Showing
25 changed files
with
1,607 additions
and
384 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
#include "ExternalToolsManager.h" | ||
#include <algorithm> | ||
#include "ExternalToolsProcessManager.h" | ||
#include "globals.h" | ||
#include "bitmap_loader.h" | ||
#include "imanager.h" | ||
|
||
ExternalToolsManager::ExternalToolsManager(wxWindow* parent) | ||
: ExternalToolsManagerBase(parent) | ||
{ | ||
DoPopulateTable(); | ||
} | ||
|
||
ExternalToolsManager::~ExternalToolsManager() {} | ||
|
||
void ExternalToolsManager::OnKill(wxCommandEvent& event) | ||
{ | ||
wxDataViewItemArray arr; | ||
m_dvListCtrlTasks->GetSelections(arr); | ||
for(size_t i = 0; i < arr.size(); ++i) { | ||
wxDataViewItem item = arr.Item(i); | ||
ExternalToolItemData* cd = (ExternalToolItemData*)m_dvListCtrlTasks->GetItemData(item); | ||
ToolsTaskManager::Instance()->Stop(cd->m_pid); | ||
} | ||
DoPopulateTable(); | ||
} | ||
|
||
void ExternalToolsManager::OnKillAll(wxCommandEvent& event) | ||
{ | ||
ToolsTaskManager::Instance()->StopAll(); | ||
DoPopulateTable(); | ||
} | ||
|
||
void ExternalToolsManager::OnKillAllUI(wxUpdateUIEvent& event) { event.Enable(m_dvListCtrlTasks->GetItemCount()); } | ||
void ExternalToolsManager::OnKillUI(wxUpdateUIEvent& event) | ||
{ | ||
event.Enable(m_dvListCtrlTasks->GetSelectedItemsCount()); | ||
} | ||
|
||
void ExternalToolsManager::DoPopulateTable() | ||
{ | ||
DoClear(); | ||
BitmapLoader* b = clGetManager()->GetStdIcons(); | ||
const ExternalToolItemData::Map_t& tools = ToolsTaskManager::Instance()->GetTools(); | ||
std::for_each(tools.begin(), tools.end(), [&](const std::pair<int, ExternalToolItemData>& p) { | ||
wxVector<wxVariant> cols; | ||
cols.push_back(::MakeIconText(wxString() << p.first, b->LoadBitmap("cog"))); | ||
cols.push_back(p.second.m_command); | ||
m_dvListCtrlTasks->AppendItem(cols, (wxUIntPtr)p.second.Clone()); | ||
}); | ||
} | ||
|
||
void ExternalToolsManager::DoClear() | ||
{ | ||
for(int i = 0; i < m_dvListCtrlTasks->GetItemCount(); ++i) { | ||
ExternalToolItemData* cd = | ||
(ExternalToolItemData*)m_dvListCtrlTasks->GetItemData(m_dvListCtrlTasks->RowToItem(i)); | ||
delete cd; | ||
} | ||
m_dvListCtrlTasks->DeleteAllItems(); | ||
} | ||
void ExternalToolsManager::OnRefresh(wxCommandEvent& event) | ||
{ | ||
wxUnusedVar(event); | ||
DoPopulateTable(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#ifndef EXTERNALTOOLSMANAGER_H | ||
#define EXTERNALTOOLSMANAGER_H | ||
#include "external_tools.h" | ||
|
||
class ExternalToolsManager : public ExternalToolsManagerBase | ||
{ | ||
public: | ||
ExternalToolsManager(wxWindow* parent); | ||
virtual ~ExternalToolsManager(); | ||
|
||
protected: | ||
virtual void OnRefresh(wxCommandEvent& event); | ||
void DoPopulateTable(); | ||
void DoClear(); | ||
|
||
protected: | ||
virtual void OnKill(wxCommandEvent& event); | ||
virtual void OnKillAll(wxCommandEvent& event); | ||
virtual void OnKillAllUI(wxUpdateUIEvent& event); | ||
virtual void OnKillUI(wxUpdateUIEvent& event); | ||
}; | ||
#endif // EXTERNALTOOLSMANAGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
#include "ExternalToolsProcessManager.h" | ||
#include "event_notifier.h" | ||
#include "globals.h" | ||
#include "imanager.h" | ||
#include "asyncprocess.h" | ||
#include "macromanager.h" | ||
#include "environmentconfig.h" | ||
#include "processreaderthread.h" | ||
#include <algorithm> | ||
#include <wx/utils.h> | ||
#include <wx/process.h> | ||
#include <wx/msgdlg.h> | ||
|
||
/** | ||
* @class MyProcess | ||
* @brief handler class for capturing non-redirected processes termination | ||
*/ | ||
class MyProcess : public wxProcess | ||
{ | ||
public: | ||
MyProcess() {} | ||
virtual ~MyProcess() {} | ||
void OnTerminate(int pid, int status) | ||
{ | ||
ToolsTaskManager::Instance()->ProcessTerminated(pid); | ||
delete this; | ||
} | ||
}; | ||
|
||
ToolsTaskManager* ToolsTaskManager::ms_instance = 0; | ||
|
||
ToolsTaskManager::ToolsTaskManager() | ||
{ | ||
Bind(wxEVT_ASYNC_PROCESS_OUTPUT, &ToolsTaskManager::OnProcessOutput, this); | ||
Bind(wxEVT_ASYNC_PROCESS_TERMINATED, &ToolsTaskManager::OnProcessEnd, this); | ||
} | ||
|
||
ToolsTaskManager::~ToolsTaskManager() | ||
{ | ||
Unbind(wxEVT_ASYNC_PROCESS_OUTPUT, &ToolsTaskManager::OnProcessOutput, this); | ||
Unbind(wxEVT_ASYNC_PROCESS_TERMINATED, &ToolsTaskManager::OnProcessEnd, this); | ||
} | ||
|
||
ToolsTaskManager* ToolsTaskManager::Instance() | ||
{ | ||
if(ms_instance == 0) { | ||
ms_instance = new ToolsTaskManager(); | ||
} | ||
return ms_instance; | ||
} | ||
|
||
void ToolsTaskManager::Release() | ||
{ | ||
if(ms_instance) { | ||
delete ms_instance; | ||
} | ||
ms_instance = 0; | ||
} | ||
|
||
void ToolsTaskManager::OnProcessEnd(clProcessEvent& event) | ||
{ | ||
clGetManager()->AppendOutputTabText(kOutputTab_Output, event.GetOutput()); | ||
clGetManager()->AppendOutputTabText(kOutputTab_Output, "\n"); | ||
|
||
// delete the process | ||
IProcess* proc = event.GetProcess(); | ||
ProcessTerminated(proc->GetPid()); | ||
delete proc; | ||
|
||
// Notify codelite to test for any modified bufferes | ||
EventNotifier::Get()->PostReloadExternallyModifiedEvent(); | ||
} | ||
|
||
void ToolsTaskManager::OnProcessOutput(clProcessEvent& event) | ||
{ | ||
clGetManager()->AppendOutputTabText(kOutputTab_Output, event.GetOutput()); | ||
} | ||
|
||
void ToolsTaskManager::StartTool(const ToolInfo& ti) | ||
{ | ||
wxString command, working_dir; | ||
command << ti.GetPath(); | ||
::WrapWithQuotes(command); | ||
|
||
command << " " << ti.GetArguments(); | ||
working_dir = ti.GetWd(); | ||
|
||
command = MacroManager::Instance()->Expand( | ||
command, | ||
clGetManager(), | ||
(clGetManager()->GetWorkspace() ? clGetManager()->GetWorkspace()->GetActiveProjectName() : "")); | ||
working_dir = MacroManager::Instance()->Expand( | ||
working_dir, | ||
clGetManager(), | ||
(clGetManager()->GetWorkspace() ? clGetManager()->GetWorkspace()->GetActiveProjectName() : "")); | ||
|
||
wxString projectName; | ||
wxString configName; | ||
if(clCxxWorkspaceST::Get()->IsOpen()) { | ||
projectName = clCxxWorkspaceST::Get()->GetActiveProjectName(); | ||
BuildConfigPtr bldConf = clCxxWorkspaceST::Get()->GetProjBuildConf(projectName, wxEmptyString); | ||
if(bldConf) { | ||
configName = bldConf->GetName(); | ||
} | ||
} | ||
|
||
EnvSetter envGuard(clGetManager()->GetEnv(), NULL, projectName, configName); | ||
//::WrapInShell(command); | ||
|
||
int pid = wxNOT_FOUND; | ||
if(ti.GetCaptureOutput()) { | ||
IProcess* proc = ::CreateAsyncProcess(this, command, IProcessCreateConsole, working_dir); | ||
if(!proc) { | ||
::wxMessageBox(_("Failed to launch tool\n'") + command + "'", | ||
"CodeLite", | ||
wxICON_ERROR | wxOK | wxCENTER, | ||
EventNotifier::Get()->TopFrame()); | ||
return; | ||
} | ||
|
||
pid = proc->GetPid(); | ||
|
||
} else { | ||
pid = ::wxExecute(command, wxEXEC_ASYNC | wxEXEC_MAKE_GROUP_LEADER, new MyProcess()); | ||
} | ||
|
||
if(pid > 0) { | ||
ExternalToolItemData item(command, pid); | ||
m_tools.insert(std::make_pair(pid, item)); | ||
} | ||
} | ||
|
||
void ToolsTaskManager::ProcessTerminated(int pid) | ||
{ | ||
if(m_tools.find(pid) != m_tools.end()) { | ||
m_tools.erase(pid); | ||
} | ||
} | ||
|
||
void ToolsTaskManager::StopAll() | ||
{ | ||
std::for_each(m_tools.begin(), m_tools.end(), [&](const std::pair<int, ExternalToolItemData> &p) { | ||
::wxKill(p.second.m_pid, wxSIGKILL, NULL, wxKILL_CHILDREN); | ||
}); | ||
} | ||
|
||
void ToolsTaskManager::Stop(int pid) | ||
{ | ||
if(m_tools.find(pid) != m_tools.end()) { | ||
::wxKill(pid, wxSIGKILL, NULL, wxKILL_CHILDREN); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#ifndef EXTERNALTOOLSPROCESSMANAGER_H | ||
#define EXTERNALTOOLSPROCESSMANAGER_H | ||
|
||
#include <wx/event.h> | ||
#include "cl_command_event.h" | ||
#include "externaltoolsdata.h" | ||
#include <vector> | ||
|
||
struct ExternalToolItemData { | ||
wxString m_command; | ||
int m_pid; | ||
|
||
ExternalToolItemData(const wxString& command, int pid) | ||
: m_command(command) | ||
, m_pid(pid) | ||
{ | ||
} | ||
|
||
ExternalToolItemData* Clone() const { return new ExternalToolItemData(m_command, m_pid); } | ||
~ExternalToolItemData() {} | ||
typedef std::map<int, ExternalToolItemData> Map_t; | ||
}; | ||
|
||
class ToolsTaskManager : public wxEvtHandler | ||
{ | ||
static ToolsTaskManager* ms_instance; | ||
|
||
protected: | ||
ExternalToolItemData::Map_t m_tools; | ||
|
||
protected: | ||
void OnProcessEnd(clProcessEvent& event); | ||
void OnProcessOutput(clProcessEvent& event); | ||
|
||
public: | ||
static ToolsTaskManager* Instance(); | ||
static void Release(); | ||
/** | ||
* @brief launch a tool | ||
*/ | ||
void StartTool(const ToolInfo& ti); | ||
/** | ||
* @brief a tool process terminated, remove it from our internal tracking table | ||
*/ | ||
void ProcessTerminated(int pid); | ||
/** | ||
* @brief stop all processes | ||
*/ | ||
void StopAll(); | ||
/** | ||
* @brief stop a single tool | ||
*/ | ||
void Stop(int pid); | ||
|
||
const ExternalToolItemData::Map_t& GetTools() const { return m_tools; } | ||
|
||
private: | ||
ToolsTaskManager(); | ||
virtual ~ToolsTaskManager(); | ||
}; | ||
|
||
#endif // EXTERNALTOOLSPROCESSMANAGER_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.