mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
Compare commits
3 Commits
fac2feb598
...
cc69874ebc
| Author | SHA1 | Date | |
|---|---|---|---|
| cc69874ebc | |||
| 08f61ef9e4 | |||
| 0180958621 |
@@ -15,11 +15,15 @@
|
|||||||
#include "DhfsWxProcess.hpp"
|
#include "DhfsWxProcess.hpp"
|
||||||
|
|
||||||
enum class DhfsInstanceState {
|
enum class DhfsInstanceState {
|
||||||
|
STARTING,
|
||||||
RUNNING,
|
RUNNING,
|
||||||
|
STOPPING,
|
||||||
STOPPED,
|
STOPPED,
|
||||||
};
|
};
|
||||||
|
|
||||||
class DhfsInstance {
|
class DhfsInstance {
|
||||||
|
friend DhfsWxProcess;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DhfsInstance();
|
DhfsInstance();
|
||||||
|
|
||||||
@@ -31,14 +35,16 @@ public:
|
|||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
virtual void OnTerminate(int pid, int status) = 0;
|
protected:
|
||||||
|
virtual void OnStateChange() = 0;
|
||||||
|
|
||||||
virtual void OnRead(std::string s) = 0;
|
virtual void OnRead(std::string s) = 0;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
std::unique_ptr<DhfsWxProcess> process = std::make_unique<DhfsWxProcess>(*this);
|
std::unique_ptr<DhfsWxProcess> process = std::make_unique<DhfsWxProcess>(*this);
|
||||||
|
|
||||||
private:
|
void OnTerminateInternal(int pid, int status);
|
||||||
|
|
||||||
DhfsInstanceState _state = DhfsInstanceState::STOPPED;
|
DhfsInstanceState _state = DhfsInstanceState::STOPPED;
|
||||||
std::thread _readThread;
|
std::thread _readThread;
|
||||||
std::thread _readThreadErr;
|
std::thread _readThreadErr;
|
||||||
|
|||||||
@@ -25,13 +25,17 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
|||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case DhfsInstanceState::RUNNING:
|
case DhfsInstanceState::RUNNING:
|
||||||
|
case DhfsInstanceState::STARTING:
|
||||||
|
case DhfsInstanceState::STOPPING:
|
||||||
return;
|
return;
|
||||||
case DhfsInstanceState::STOPPED:
|
case DhfsInstanceState::STOPPED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Unknown DhfsInstanceState");
|
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||||
}
|
}
|
||||||
_state = DhfsInstanceState::RUNNING;
|
|
||||||
|
_state = DhfsInstanceState::STARTING;
|
||||||
|
OnStateChange();
|
||||||
|
|
||||||
std::vector<char*> args;
|
std::vector<char*> args;
|
||||||
auto readyOptions = options.getOptions();
|
auto readyOptions = options.getOptions();
|
||||||
@@ -46,18 +50,36 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
|||||||
throw Exception("Failed to start DHFS");
|
throw Exception("Failed to start DHFS");
|
||||||
}
|
}
|
||||||
|
|
||||||
OnRead("Started! " + std::to_string(ret) + " PID: " + std::to_string(process->GetPid()) + "\n");
|
OnRead("Started! PID: " + std::to_string(process->GetPid()) + "\n");
|
||||||
|
|
||||||
_readThread = std::thread([&]() {
|
_readThread = std::thread([&]() {
|
||||||
auto stream = process->GetInputStream();
|
auto stream = process->GetInputStream();
|
||||||
|
|
||||||
|
bool searching = true;
|
||||||
|
std::string lastLine;
|
||||||
|
|
||||||
while (!stream->Eof() || stream->CanRead()) {
|
while (!stream->Eof() || stream->CanRead()) {
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
buffer[bytesRead] = '\0'; // Null-terminate the string
|
buffer[bytesRead] = '\0';
|
||||||
|
if (searching) {
|
||||||
|
for (size_t i = 0; i < bytesRead; i++) {
|
||||||
|
lastLine += buffer[i];
|
||||||
|
if (buffer[i] == '\n') {
|
||||||
|
if (lastLine.find("Listening on:") != std::string::npos) {
|
||||||
|
searching = false;
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
if (_state == DhfsInstanceState::STARTING) {
|
||||||
|
_state = DhfsInstanceState::RUNNING;
|
||||||
|
OnStateChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastLine = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
OnRead(std::string(buffer));
|
OnRead(std::string(buffer));
|
||||||
} else if (bytesRead == 0) {
|
|
||||||
break; // EOF reached
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -67,10 +89,8 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
|||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||||
if (bytesRead > 0) {
|
if (bytesRead > 0) {
|
||||||
buffer[bytesRead] = '\0'; // Null-terminate the string
|
buffer[bytesRead] = '\0';
|
||||||
OnRead(std::string(buffer));
|
OnRead(std::string(buffer));
|
||||||
} else if (bytesRead == 0) {
|
|
||||||
break; // EOF reached
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -80,21 +100,30 @@ void DhfsInstance::stop() {
|
|||||||
std::lock_guard<std::mutex> lock(_mutex);
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case DhfsInstanceState::RUNNING:
|
case DhfsInstanceState::RUNNING:
|
||||||
|
case DhfsInstanceState::STARTING:
|
||||||
break;
|
break;
|
||||||
case DhfsInstanceState::STOPPED:
|
case DhfsInstanceState::STOPPED:
|
||||||
|
case DhfsInstanceState::STOPPING:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("Unknown DhfsInstanceState");
|
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||||
}
|
}
|
||||||
|
|
||||||
_state = DhfsInstanceState::STOPPED;
|
_state = DhfsInstanceState::STOPPING;
|
||||||
|
OnStateChange();
|
||||||
|
|
||||||
int err = wxProcess::Kill(process->GetPid(), wxSIGTERM, wxKILL_CHILDREN);
|
int err = wxProcess::Kill(process->GetPid(), wxSIGTERM, wxKILL_CHILDREN);
|
||||||
_readThread.join();
|
|
||||||
_readThreadErr.join();
|
|
||||||
OnRead("Stopped!\n");
|
|
||||||
if (err != wxKILL_OK) {
|
if (err != wxKILL_OK) {
|
||||||
OnRead("Failed to stop DHFS: " + std::to_string(err) + "\n");
|
OnRead("Failed to stop DHFS: " + std::to_string(err) + "\n");
|
||||||
}
|
}
|
||||||
OnTerminate(0, 0);
|
}
|
||||||
|
|
||||||
|
void DhfsInstance::OnTerminateInternal(int pid, int status) {
|
||||||
|
std::lock_guard<std::mutex> lock(_mutex);
|
||||||
|
_state = DhfsInstanceState::STOPPED;
|
||||||
|
|
||||||
|
_readThread.join();
|
||||||
|
_readThreadErr.join();
|
||||||
|
OnRead("Stopped!\n");
|
||||||
|
OnStateChange();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,5 +10,5 @@ DhfsWxProcess::DhfsWxProcess(DhfsInstance& parent): wxProcess(wxPROCESS_REDIRECT
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DhfsWxProcess::OnTerminate(int pid, int status) {
|
void DhfsWxProcess::OnTerminate(int pid, int status) {
|
||||||
_instance.stop();
|
_instance.OnTerminateInternal(pid, status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
DhfsGuiInstance::DhfsGuiInstance(LauncherAppMainFrame& parent): _parent(parent) {
|
DhfsGuiInstance::DhfsGuiInstance(LauncherAppMainFrame& parent): _parent(parent) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DhfsGuiInstance::OnTerminate(int pid, int status) {
|
void DhfsGuiInstance::OnStateChange() {
|
||||||
wxCommandEvent* event = new wxCommandEvent(SHUTDOWN_EVENT, _parent.GetId());
|
wxCommandEvent* event = new wxCommandEvent(DHFS_STATE_CHANGE_EVENT, _parent.GetId());
|
||||||
event->SetEventObject(&_parent);
|
event->SetEventObject(&_parent);
|
||||||
_parent.GetEventHandler()->QueueEvent(event);
|
_parent.GetEventHandler()->QueueEvent(event);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class DhfsGuiInstance : public DhfsInstance {
|
|||||||
public:
|
public:
|
||||||
DhfsGuiInstance(LauncherAppMainFrame& parent);
|
DhfsGuiInstance(LauncherAppMainFrame& parent);
|
||||||
|
|
||||||
void OnTerminate(int pid, int status) override;
|
void OnStateChange() override;
|
||||||
|
|
||||||
void OnRead(std::string s) override;
|
void OnRead(std::string s) override;
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
|
|||||||
m_panel1->SetSizer( bSizer2 );
|
m_panel1->SetSizer( bSizer2 );
|
||||||
m_panel1->Layout();
|
m_panel1->Layout();
|
||||||
bSizer2->Fit( m_panel1 );
|
bSizer2->Fit( m_panel1 );
|
||||||
m_notebook1->AddPage( m_panel1, _("Info"), false );
|
m_notebook1->AddPage( m_panel1, _("Info"), true );
|
||||||
m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_panel3 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
wxGridSizer* gSizer1;
|
wxGridSizer* gSizer1;
|
||||||
gSizer1 = new wxGridSizer( 1, 1, 0, 0 );
|
gSizer1 = new wxGridSizer( 1, 1, 0, 0 );
|
||||||
@@ -65,7 +65,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
|
|||||||
m_panel3->SetSizer( gSizer1 );
|
m_panel3->SetSizer( gSizer1 );
|
||||||
m_panel3->Layout();
|
m_panel3->Layout();
|
||||||
gSizer1->Fit( m_panel3 );
|
gSizer1->Fit( m_panel3 );
|
||||||
m_notebook1->AddPage( m_panel3, _("Logs"), true );
|
m_notebook1->AddPage( m_panel3, _("Logs"), false );
|
||||||
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_panel2 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
wxBoxSizer* bSizer5;
|
wxBoxSizer* bSizer5;
|
||||||
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
bSizer5 = new wxBoxSizer( wxVERTICAL );
|
||||||
@@ -137,7 +137,7 @@ MainFrame::MainFrame( wxWindow* parent, wxWindowID id, const wxString& title, co
|
|||||||
m_panel4 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_panel4 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
m_notebook1->AddPage( m_panel4, _("Advanced Settings"), false );
|
m_notebook1->AddPage( m_panel4, _("Advanced Settings"), false );
|
||||||
m_panel5 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
m_panel5 = new wxPanel( m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||||
m_notebook1->AddPage( m_panel5, _("a page"), false );
|
m_notebook1->AddPage( m_panel5, _("Web UI"), false );
|
||||||
|
|
||||||
bSizer3->Add( m_notebook1, 1, wxEXPAND, 5 );
|
bSizer3->Add( m_notebook1, 1, wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include "Exception.h"
|
#include "Exception.h"
|
||||||
|
|
||||||
wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||||
wxDEFINE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
wxDEFINE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
||||||
: MainFrame(parent) {
|
: MainFrame(parent) {
|
||||||
@@ -20,7 +20,7 @@ LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
|||||||
m_webViewSizer->Fit(m_panel5);
|
m_webViewSizer->Fit(m_panel5);
|
||||||
|
|
||||||
Bind(NEW_LINE_OUTPUT_EVENT, &LauncherAppMainFrame::onNewLineOutput, this);
|
Bind(NEW_LINE_OUTPUT_EVENT, &LauncherAppMainFrame::onNewLineOutput, this);
|
||||||
Bind(SHUTDOWN_EVENT, &LauncherAppMainFrame::onShutdown, this);
|
Bind(DHFS_STATE_CHANGE_EVENT, &LauncherAppMainFrame::onDhfsInstanceStateChange, this);
|
||||||
wxFont font = wxFont(wxSize(16, 16),
|
wxFont font = wxFont(wxSize(16, 16),
|
||||||
wxFontFamily::wxFONTFAMILY_TELETYPE,
|
wxFontFamily::wxFONTFAMILY_TELETYPE,
|
||||||
wxFontStyle::wxFONTSTYLE_NORMAL,
|
wxFontStyle::wxFONTSTYLE_NORMAL,
|
||||||
@@ -31,17 +31,36 @@ LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
|||||||
|
|
||||||
void LauncherAppMainFrame::updateState() {
|
void LauncherAppMainFrame::updateState() {
|
||||||
switch (_dhfsInstance.state()) {
|
switch (_dhfsInstance.state()) {
|
||||||
case DhfsInstanceState::RUNNING:
|
case DhfsInstanceState::RUNNING: {
|
||||||
m_statusText->SetLabel("Running");
|
m_statusText->SetLabel("Running");
|
||||||
m_startStopButton->SetLabel("Stop");
|
m_startStopButton->SetLabel("Stop");
|
||||||
m_statusBar1->SetStatusText("Running", 0);
|
m_statusBar1->SetStatusText("Running", 0);
|
||||||
|
|
||||||
|
if (m_notebook1->GetSelection() == 4) {
|
||||||
|
if (m_webView != nullptr)
|
||||||
|
m_webView->LoadURL("http://localhost:8080");
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case DhfsInstanceState::STARTING: {
|
||||||
|
m_statusText->SetLabel("Starting");
|
||||||
|
m_startStopButton->SetLabel("Stop");
|
||||||
|
m_statusBar1->SetStatusText("Starting", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DhfsInstanceState::STOPPED: {
|
case DhfsInstanceState::STOPPED: {
|
||||||
m_statusText->SetLabel("Stopped");
|
m_statusText->SetLabel("Stopped");
|
||||||
m_startStopButton->SetLabel("Start");
|
m_startStopButton->SetLabel("Start");
|
||||||
m_statusBar1->SetStatusText("Stopped", 0);
|
m_statusBar1->SetStatusText("Stopped", 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DhfsInstanceState::STOPPING: {
|
||||||
|
m_statusText->SetLabel("Stopping");
|
||||||
|
m_startStopButton->SetLabel("Kill");
|
||||||
|
m_statusBar1->SetStatusText("Stopping", 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw Exception("Unhandled switch case");
|
throw Exception("Unhandled switch case");
|
||||||
}
|
}
|
||||||
@@ -50,8 +69,10 @@ void LauncherAppMainFrame::updateState() {
|
|||||||
void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
||||||
switch (_dhfsInstance.state()) {
|
switch (_dhfsInstance.state()) {
|
||||||
case DhfsInstanceState::RUNNING:
|
case DhfsInstanceState::RUNNING:
|
||||||
|
case DhfsInstanceState::STARTING: {
|
||||||
_dhfsInstance.stop();
|
_dhfsInstance.stop();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DhfsInstanceState::STOPPED: {
|
case DhfsInstanceState::STOPPED: {
|
||||||
DhfsStartOptions options;
|
DhfsStartOptions options;
|
||||||
options.java_home = wxFileConfig::Get()->Read(kJavaHomeSettingsKey);
|
options.java_home = wxFileConfig::Get()->Read(kJavaHomeSettingsKey);
|
||||||
@@ -65,6 +86,10 @@ void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
|||||||
_dhfsInstance.start(options);
|
_dhfsInstance.start(options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DhfsInstanceState::STOPPING: {
|
||||||
|
// TODO:
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
throw Exception("Unhandled switch case");
|
throw Exception("Unhandled switch case");
|
||||||
}
|
}
|
||||||
@@ -88,14 +113,14 @@ void LauncherAppMainFrame::onNewLineOutput(wxCommandEvent& event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LauncherAppMainFrame::OnNotebookPageChanged(wxBookCtrlEvent& event) {
|
void LauncherAppMainFrame::OnNotebookPageChanged(wxBookCtrlEvent& event) {
|
||||||
}
|
|
||||||
|
|
||||||
void LauncherAppMainFrame::OnNotebookPageChanging(wxBookCtrlEvent& event) {
|
|
||||||
if (event.GetSelection() == 4) prepareWebview();
|
if (event.GetSelection() == 4) prepareWebview();
|
||||||
else unloadWebview();
|
else unloadWebview();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherAppMainFrame::onShutdown(wxCommandEvent& event) {
|
void LauncherAppMainFrame::OnNotebookPageChanging(wxBookCtrlEvent& event) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherAppMainFrame::onDhfsInstanceStateChange(wxCommandEvent& event) {
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ static constexpr auto kMountPointSettingsKey = "DHFS/MountDir";
|
|||||||
static constexpr auto kDataDirSettingsKey = "DHFS/DataDir";
|
static constexpr auto kDataDirSettingsKey = "DHFS/DataDir";
|
||||||
|
|
||||||
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||||
wxDECLARE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
wxDECLARE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
|
||||||
|
|
||||||
/** Implementing MainFrame */
|
/** Implementing MainFrame */
|
||||||
class LauncherAppMainFrame : public MainFrame {
|
class LauncherAppMainFrame : public MainFrame {
|
||||||
@@ -39,7 +39,7 @@ protected:
|
|||||||
|
|
||||||
void onNewLineOutput(wxCommandEvent& event);
|
void onNewLineOutput(wxCommandEvent& event);
|
||||||
|
|
||||||
void onShutdown(wxCommandEvent& event);
|
void onDhfsInstanceStateChange(wxCommandEvent& event);
|
||||||
|
|
||||||
void updateState();
|
void updateState();
|
||||||
|
|
||||||
|
|||||||
@@ -1211,7 +1211,7 @@
|
|||||||
</object>
|
</object>
|
||||||
<object class="notebookpage" expanded="true">
|
<object class="notebookpage" expanded="true">
|
||||||
<property name="bitmap"></property>
|
<property name="bitmap"></property>
|
||||||
<property name="label">a page</property>
|
<property name="label">Web UI</property>
|
||||||
<property name="select">0</property>
|
<property name="select">0</property>
|
||||||
<object class="wxPanel" expanded="true">
|
<object class="wxPanel" expanded="true">
|
||||||
<property name="BottomDockable">1</property>
|
<property name="BottomDockable">1</property>
|
||||||
|
|||||||
Reference in New Issue
Block a user