3 Commits

Author SHA1 Message Date
cc69874ebc correct notebook page event
changing apparently works weirdly on windows?
2025-06-26 12:49:16 +02:00
08f61ef9e4 reload web ui on start 2025-06-26 12:34:01 +02:00
0180958621 starting/stopping 2025-06-26 12:30:10 +02:00
9 changed files with 93 additions and 33 deletions

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -10,5 +10,5 @@ DhfsWxProcess::DhfsWxProcess(DhfsInstance& parent): wxProcess(wxPROCESS_REDIRECT
}
void DhfsWxProcess::OnTerminate(int pid, int status) {
_instance.stop();
_instance.OnTerminateInternal(pid, status);
}

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 );

View File

@@ -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();
}

View File

@@ -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();

View File

@@ -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>