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"
|
||||
|
||||
enum class DhfsInstanceState {
|
||||
STARTING,
|
||||
RUNNING,
|
||||
STOPPING,
|
||||
STOPPED,
|
||||
};
|
||||
|
||||
class DhfsInstance {
|
||||
friend DhfsWxProcess;
|
||||
|
||||
public:
|
||||
DhfsInstance();
|
||||
|
||||
@@ -31,14 +35,16 @@ public:
|
||||
|
||||
void stop();
|
||||
|
||||
virtual void OnTerminate(int pid, int status) = 0;
|
||||
protected:
|
||||
virtual void OnStateChange() = 0;
|
||||
|
||||
virtual void OnRead(std::string s) = 0;
|
||||
|
||||
protected:
|
||||
private:
|
||||
std::unique_ptr<DhfsWxProcess> process = std::make_unique<DhfsWxProcess>(*this);
|
||||
|
||||
private:
|
||||
void OnTerminateInternal(int pid, int status);
|
||||
|
||||
DhfsInstanceState _state = DhfsInstanceState::STOPPED;
|
||||
std::thread _readThread;
|
||||
std::thread _readThreadErr;
|
||||
|
||||
@@ -25,13 +25,17 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
||||
std::lock_guard<std::mutex> lock(_mutex);
|
||||
switch (_state) {
|
||||
case DhfsInstanceState::RUNNING:
|
||||
case DhfsInstanceState::STARTING:
|
||||
case DhfsInstanceState::STOPPING:
|
||||
return;
|
||||
case DhfsInstanceState::STOPPED:
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||
}
|
||||
_state = DhfsInstanceState::RUNNING;
|
||||
|
||||
_state = DhfsInstanceState::STARTING;
|
||||
OnStateChange();
|
||||
|
||||
std::vector<char*> args;
|
||||
auto readyOptions = options.getOptions();
|
||||
@@ -46,18 +50,36 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
||||
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([&]() {
|
||||
auto stream = process->GetInputStream();
|
||||
|
||||
bool searching = true;
|
||||
std::string lastLine;
|
||||
|
||||
while (!stream->Eof() || stream->CanRead()) {
|
||||
char buffer[1024];
|
||||
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||
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));
|
||||
} else if (bytesRead == 0) {
|
||||
break; // EOF reached
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -67,10 +89,8 @@ void DhfsInstance::start(DhfsStartOptions options) {
|
||||
char buffer[1024];
|
||||
size_t bytesRead = stream->Read(buffer, sizeof(buffer) - 1).LastRead();
|
||||
if (bytesRead > 0) {
|
||||
buffer[bytesRead] = '\0'; // Null-terminate the string
|
||||
buffer[bytesRead] = '\0';
|
||||
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);
|
||||
switch (_state) {
|
||||
case DhfsInstanceState::RUNNING:
|
||||
case DhfsInstanceState::STARTING:
|
||||
break;
|
||||
case DhfsInstanceState::STOPPED:
|
||||
case DhfsInstanceState::STOPPING:
|
||||
return;
|
||||
default:
|
||||
throw std::runtime_error("Unknown DhfsInstanceState");
|
||||
}
|
||||
|
||||
_state = DhfsInstanceState::STOPPED;
|
||||
_state = DhfsInstanceState::STOPPING;
|
||||
OnStateChange();
|
||||
|
||||
int err = wxProcess::Kill(process->GetPid(), wxSIGTERM, wxKILL_CHILDREN);
|
||||
_readThread.join();
|
||||
_readThreadErr.join();
|
||||
OnRead("Stopped!\n");
|
||||
if (err != wxKILL_OK) {
|
||||
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) {
|
||||
_instance.stop();
|
||||
_instance.OnTerminateInternal(pid, status);
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
DhfsGuiInstance::DhfsGuiInstance(LauncherAppMainFrame& parent): _parent(parent) {
|
||||
}
|
||||
|
||||
void DhfsGuiInstance::OnTerminate(int pid, int status) {
|
||||
wxCommandEvent* event = new wxCommandEvent(SHUTDOWN_EVENT, _parent.GetId());
|
||||
void DhfsGuiInstance::OnStateChange() {
|
||||
wxCommandEvent* event = new wxCommandEvent(DHFS_STATE_CHANGE_EVENT, _parent.GetId());
|
||||
event->SetEventObject(&_parent);
|
||||
_parent.GetEventHandler()->QueueEvent(event);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class DhfsGuiInstance : public DhfsInstance {
|
||||
public:
|
||||
DhfsGuiInstance(LauncherAppMainFrame& parent);
|
||||
|
||||
void OnTerminate(int pid, int status) override;
|
||||
void OnStateChange() 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->Layout();
|
||||
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 );
|
||||
wxGridSizer* gSizer1;
|
||||
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->Layout();
|
||||
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 );
|
||||
wxBoxSizer* bSizer5;
|
||||
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_notebook1->AddPage( m_panel4, _("Advanced Settings"), false );
|
||||
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 );
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Exception.h"
|
||||
|
||||
wxDEFINE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||
wxDEFINE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
||||
wxDEFINE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
|
||||
|
||||
LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
||||
: MainFrame(parent) {
|
||||
@@ -20,7 +20,7 @@ LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
||||
m_webViewSizer->Fit(m_panel5);
|
||||
|
||||
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),
|
||||
wxFontFamily::wxFONTFAMILY_TELETYPE,
|
||||
wxFontStyle::wxFONTSTYLE_NORMAL,
|
||||
@@ -31,17 +31,36 @@ LauncherAppMainFrame::LauncherAppMainFrame(wxWindow* parent)
|
||||
|
||||
void LauncherAppMainFrame::updateState() {
|
||||
switch (_dhfsInstance.state()) {
|
||||
case DhfsInstanceState::RUNNING:
|
||||
case DhfsInstanceState::RUNNING: {
|
||||
m_statusText->SetLabel("Running");
|
||||
m_startStopButton->SetLabel("Stop");
|
||||
m_statusBar1->SetStatusText("Running", 0);
|
||||
|
||||
if (m_notebook1->GetSelection() == 4) {
|
||||
if (m_webView != nullptr)
|
||||
m_webView->LoadURL("http://localhost:8080");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case DhfsInstanceState::STARTING: {
|
||||
m_statusText->SetLabel("Starting");
|
||||
m_startStopButton->SetLabel("Stop");
|
||||
m_statusBar1->SetStatusText("Starting", 0);
|
||||
break;
|
||||
}
|
||||
case DhfsInstanceState::STOPPED: {
|
||||
m_statusText->SetLabel("Stopped");
|
||||
m_startStopButton->SetLabel("Start");
|
||||
m_statusBar1->SetStatusText("Stopped", 0);
|
||||
break;
|
||||
}
|
||||
case DhfsInstanceState::STOPPING: {
|
||||
m_statusText->SetLabel("Stopping");
|
||||
m_startStopButton->SetLabel("Kill");
|
||||
m_statusBar1->SetStatusText("Stopping", 0);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Exception("Unhandled switch case");
|
||||
}
|
||||
@@ -50,8 +69,10 @@ void LauncherAppMainFrame::updateState() {
|
||||
void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
||||
switch (_dhfsInstance.state()) {
|
||||
case DhfsInstanceState::RUNNING:
|
||||
case DhfsInstanceState::STARTING: {
|
||||
_dhfsInstance.stop();
|
||||
break;
|
||||
}
|
||||
case DhfsInstanceState::STOPPED: {
|
||||
DhfsStartOptions options;
|
||||
options.java_home = wxFileConfig::Get()->Read(kJavaHomeSettingsKey);
|
||||
@@ -65,6 +86,10 @@ void LauncherAppMainFrame::OnStartStopButtonClick(wxCommandEvent& event) {
|
||||
_dhfsInstance.start(options);
|
||||
break;
|
||||
}
|
||||
case DhfsInstanceState::STOPPING: {
|
||||
// TODO:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw Exception("Unhandled switch case");
|
||||
}
|
||||
@@ -88,14 +113,14 @@ void LauncherAppMainFrame::onNewLineOutput(wxCommandEvent& event) {
|
||||
}
|
||||
|
||||
void LauncherAppMainFrame::OnNotebookPageChanged(wxBookCtrlEvent& event) {
|
||||
}
|
||||
|
||||
void LauncherAppMainFrame::OnNotebookPageChanging(wxBookCtrlEvent& event) {
|
||||
if (event.GetSelection() == 4) prepareWebview();
|
||||
else unloadWebview();
|
||||
}
|
||||
|
||||
void LauncherAppMainFrame::onShutdown(wxCommandEvent& event) {
|
||||
void LauncherAppMainFrame::OnNotebookPageChanging(wxBookCtrlEvent& event) {
|
||||
}
|
||||
|
||||
void LauncherAppMainFrame::onDhfsInstanceStateChange(wxCommandEvent& event) {
|
||||
updateState();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ static constexpr auto kMountPointSettingsKey = "DHFS/MountDir";
|
||||
static constexpr auto kDataDirSettingsKey = "DHFS/DataDir";
|
||||
|
||||
wxDECLARE_EVENT(NEW_LINE_OUTPUT_EVENT, wxCommandEvent);
|
||||
wxDECLARE_EVENT(SHUTDOWN_EVENT, wxCommandEvent);
|
||||
wxDECLARE_EVENT(DHFS_STATE_CHANGE_EVENT, wxCommandEvent);
|
||||
|
||||
/** Implementing MainFrame */
|
||||
class LauncherAppMainFrame : public MainFrame {
|
||||
@@ -39,7 +39,7 @@ protected:
|
||||
|
||||
void onNewLineOutput(wxCommandEvent& event);
|
||||
|
||||
void onShutdown(wxCommandEvent& event);
|
||||
void onDhfsInstanceStateChange(wxCommandEvent& event);
|
||||
|
||||
void updateState();
|
||||
|
||||
|
||||
@@ -1211,7 +1211,7 @@
|
||||
</object>
|
||||
<object class="notebookpage" expanded="true">
|
||||
<property name="bitmap"></property>
|
||||
<property name="label">a page</property>
|
||||
<property name="label">Web UI</property>
|
||||
<property name="select">0</property>
|
||||
<object class="wxPanel" expanded="true">
|
||||
<property name="BottomDockable">1</property>
|
||||
|
||||
Reference in New Issue
Block a user