diff --git a/DevTools/HackStudio/Makefile b/DevTools/HackStudio/Makefile index c96a770342..728552f7c3 100644 --- a/DevTools/HackStudio/Makefile +++ b/DevTools/HackStudio/Makefile @@ -5,6 +5,7 @@ OBJS = \ TextDocument.o \ TerminalWrapper.o \ FindInFilesWidget.o \ + ProcessStateWidget.o \ main.o APP = HackStudio diff --git a/DevTools/HackStudio/ProcessStateWidget.cpp b/DevTools/HackStudio/ProcessStateWidget.cpp new file mode 100644 index 0000000000..98a0ab4bbb --- /dev/null +++ b/DevTools/HackStudio/ProcessStateWidget.cpp @@ -0,0 +1,71 @@ +#include "ProcessStateWidget.h" +#include +#include +#include +#include + +ProcessStateWidget::ProcessStateWidget(GWidget* parent) + : GWidget(parent) +{ + set_size_policy(SizePolicy::Fill, SizePolicy::Fixed); + set_preferred_size(0, 20); + + set_layout(make(Orientation::Horizontal)); + + auto pid_label_label = GLabel::construct("Process:", this); + pid_label_label->set_font(Font::default_bold_font()); + m_pid_label = GLabel::construct("", this); + + auto state_label_label = GLabel::construct("State:", this); + state_label_label->set_font(Font::default_bold_font()); + m_state_label = GLabel::construct("", this); + + // FIXME: This should show CPU% instead. + auto cpu_label_label = GLabel::construct("Times scheduled:", this); + cpu_label_label->set_font(Font::default_bold_font()); + m_cpu_label = GLabel::construct("", this); + + auto memory_label_label = GLabel::construct("Memory (resident):", this); + memory_label_label->set_font(Font::default_bold_font()); + m_memory_label = GLabel::construct("", this); + + m_timer = CTimer::construct(500, [this] { + refresh(); + }); +} + +ProcessStateWidget::~ProcessStateWidget() +{ +} + +void ProcessStateWidget::refresh() +{ + if (m_pid == -1) { + m_pid_label->set_text("(none)"); + m_state_label->set_text("n/a"); + m_cpu_label->set_text("n/a"); + m_memory_label->set_text("n/a"); + return; + } + + auto processes = CProcessStatisticsReader::get_all(); + auto child_process_data = processes.get(m_pid); + + if (!child_process_data.has_value()) + return; + + auto active_process_data = processes.get(child_process_data.value().pgid); + + auto& data = active_process_data.value(); + + m_pid_label->set_text(String::format("%s(%d)", data.name.characters(), m_pid)); + m_state_label->set_text(data.state); + m_cpu_label->set_text(String::format("%d", data.times_scheduled)); + m_memory_label->set_text(String::format("%d", data.amount_resident)); +} + +void ProcessStateWidget::set_pid(pid_t pid) +{ + m_pid = pid; + refresh(); +} diff --git a/DevTools/HackStudio/ProcessStateWidget.h b/DevTools/HackStudio/ProcessStateWidget.h new file mode 100644 index 0000000000..5f9c35c0c0 --- /dev/null +++ b/DevTools/HackStudio/ProcessStateWidget.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +class CTimer; +class GLabel; + +class ProcessStateWidget final : public GWidget { + C_OBJECT(ProcessStateWidget) +public: + virtual ~ProcessStateWidget() override; + + void set_pid(pid_t); + +private: + explicit ProcessStateWidget(GWidget* parent); + + void refresh(); + + RefPtr m_pid_label; + RefPtr m_state_label; + RefPtr m_cpu_label; + RefPtr m_memory_label; + + RefPtr m_timer; + + pid_t m_pid { -1 }; +}; diff --git a/DevTools/HackStudio/TerminalWrapper.cpp b/DevTools/HackStudio/TerminalWrapper.cpp index 26c80bfa46..6ee696eed9 100644 --- a/DevTools/HackStudio/TerminalWrapper.cpp +++ b/DevTools/HackStudio/TerminalWrapper.cpp @@ -1,4 +1,5 @@ #include "TerminalWrapper.h" +#include "ProcessStateWidget.h" #include #include #include @@ -44,6 +45,7 @@ void TerminalWrapper::run_command(const String& command) } else if (WIFSIGNALED(wstatus)) { m_terminal_widget->inject_string(String::format("\033[34;1m(Command signaled with %s!)\033[0m\n", strsignal(WTERMSIG(wstatus)))); } + m_process_state_widget->set_pid(-1); m_pid = -1; }; @@ -106,6 +108,9 @@ void TerminalWrapper::run_command(const String& command) } ASSERT_NOT_REACHED(); } + + // Parent process, cont'd. + m_process_state_widget->set_pid(m_pid); } TerminalWrapper::TerminalWrapper(GWidget* parent) @@ -113,6 +118,8 @@ TerminalWrapper::TerminalWrapper(GWidget* parent) { set_layout(make(Orientation::Vertical)); + m_process_state_widget = ProcessStateWidget::construct(this); + RefPtr config = CConfigFile::get_for_app("Terminal"); m_terminal_widget = TerminalWidget::construct(-1, false, config); add_child(*m_terminal_widget); diff --git a/DevTools/HackStudio/TerminalWrapper.h b/DevTools/HackStudio/TerminalWrapper.h index 90ca7c44e4..5da7766199 100644 --- a/DevTools/HackStudio/TerminalWrapper.h +++ b/DevTools/HackStudio/TerminalWrapper.h @@ -2,6 +2,7 @@ #include +class ProcessStateWidget; class TerminalWidget; class TerminalWrapper final : public GWidget { @@ -14,6 +15,7 @@ public: private: explicit TerminalWrapper(GWidget* parent); + RefPtr m_process_state_widget; RefPtr m_terminal_widget; pid_t m_pid { -1 }; };