From 6e571b66f12c4a9001cca3fa1d7e611dc3a58d15 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 28 Feb 2019 10:20:04 +0100 Subject: [PATCH] ProcessManager: Move ProcessTableModel class to its own files. --- Applications/ProcessManager/Makefile | 1 + .../ProcessManager/ProcessTableModel.cpp | 151 ++++++++++++++++ .../ProcessManager/ProcessTableModel.h | 46 +++++ Applications/ProcessManager/ProcessView.cpp | 164 +----------------- LibGUI/GTableModel.h | 5 + 5 files changed, 204 insertions(+), 163 deletions(-) create mode 100644 Applications/ProcessManager/ProcessTableModel.cpp create mode 100644 Applications/ProcessManager/ProcessTableModel.h diff --git a/Applications/ProcessManager/Makefile b/Applications/ProcessManager/Makefile index bc14fe2364..b996d9443b 100644 --- a/Applications/ProcessManager/Makefile +++ b/Applications/ProcessManager/Makefile @@ -1,4 +1,5 @@ OBJS = \ + ProcessTableModel.o \ ProcessView.o \ main.o diff --git a/Applications/ProcessManager/ProcessTableModel.cpp b/Applications/ProcessManager/ProcessTableModel.cpp new file mode 100644 index 0000000000..c94bc8fd45 --- /dev/null +++ b/Applications/ProcessManager/ProcessTableModel.cpp @@ -0,0 +1,151 @@ +#include "ProcessTableModel.h" +#include +#include + +ProcessTableModel::ProcessTableModel() +{ +} + +ProcessTableModel::~ProcessTableModel() +{ +} + +int ProcessTableModel::row_count() const +{ + return m_processes.size(); +} + +int ProcessTableModel::column_count() const +{ + return 4; +} + +String ProcessTableModel::column_name(int column) const +{ + switch (column) { + case 0: return "PID"; + case 1: return "State"; + case 2: return "CPU"; + case 3: return "Name"; + default: ASSERT_NOT_REACHED(); + } +} + +int ProcessTableModel::column_width(int column) const +{ + switch (column) { + case 0: return 30; + case 1: return 80; + case 2: return 30; + case 3: return 200; + default: ASSERT_NOT_REACHED(); + } +} + +GModelIndex ProcessTableModel::selected_index() const +{ + return { m_selected_row, 0 }; +} + +void ProcessTableModel::set_selected_index(GModelIndex index) +{ + if (index.row() >= 0 && index.row() < m_pids.size()) + m_selected_row = index.row(); +} + +String ProcessTableModel::data(int row, int column) const +{ + ASSERT(is_valid({ row, column })); + auto it = m_processes.find(m_pids[row]); + auto& process = *(*it).value; + switch (column) { + case 0: return String::format("%d", process.current_state.pid); + case 1: return process.current_state.state; + case 2: return String::format("%d", (int)process.current_state.cpu_percent); + case 3: return process.current_state.name; + } + ASSERT_NOT_REACHED(); +} + +void ProcessTableModel::update() +{ + FILE* fp = fopen("/proc/all", "r"); + if (!fp) { + perror("failed to open /proc/all"); + exit(1); + } + + unsigned last_sum_nsched = 0; + for (auto& it : m_processes) + last_sum_nsched += it.value->current_state.nsched; + + HashTable live_pids; + unsigned sum_nsched = 0; + for (;;) { + char buf[BUFSIZ]; + char* ptr = fgets(buf, sizeof(buf), fp); + if (!ptr) + break; + auto parts = String(buf, Chomp).split(','); + if (parts.size() < 17) + break; + bool ok; + pid_t pid = parts[0].to_uint(ok); + ASSERT(ok); + unsigned nsched = parts[1].to_uint(ok); + ASSERT(ok); + ProcessState state; + state.pid = pid; + state.nsched = nsched; + unsigned uid = parts[5].to_uint(ok); + ASSERT(ok); + //state.user = s_usernames->get(uid); + state.user = String::format("%u", uid); + state.priority = parts[16]; + state.state = parts[7]; + state.name = parts[11]; + state.linear = parts[12].to_uint(ok); + ASSERT(ok); + state.committed = parts[13].to_uint(ok); + ASSERT(ok); + + { + auto it = m_processes.find(pid); + if (it == m_processes.end()) + m_processes.set(pid, make()); + } + auto it = m_processes.find(pid); + ASSERT(it != m_processes.end()); + (*it).value->previous_state = (*it).value->current_state; + (*it).value->current_state = state; + + live_pids.set(pid); + + sum_nsched += nsched; + } + int rc = fclose(fp); + ASSERT(rc == 0); + + m_pids.clear(); + Vector pids_to_remove; + for (auto& it : m_processes) { + if (!live_pids.contains(it.key)) { + pids_to_remove.append(it.key); + continue; + } + + auto& process = *it.value; + dword nsched_diff = process.current_state.nsched - process.previous_state.nsched; + process.current_state.cpu_percent = ((float)nsched_diff * 100) / (float)(sum_nsched - last_sum_nsched); + m_pids.append(it.key); + } + for (auto pid : pids_to_remove) + m_processes.remove(pid); +} + +pid_t ProcessTableModel::selected_pid() const +{ + if (m_selected_row == -1) + return -1; + return m_pids[m_selected_row]; +} diff --git a/Applications/ProcessManager/ProcessTableModel.h b/Applications/ProcessManager/ProcessTableModel.h new file mode 100644 index 0000000000..009c9bcabe --- /dev/null +++ b/Applications/ProcessManager/ProcessTableModel.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include +#include +#include +#include + +class ProcessTableModel final : public GTableModel { +public: + ProcessTableModel(); + virtual ~ProcessTableModel() override; + + virtual int row_count() const override; + virtual int column_count() const override; + virtual String column_name(int column) const override; + virtual int column_width(int column) const override; + virtual GModelIndex selected_index() const override; + virtual void set_selected_index(GModelIndex) override; + virtual String data(int row, int column) const override; + virtual void update() override; + + pid_t selected_pid() const; + +private: + struct ProcessState { + pid_t pid; + unsigned nsched; + String name; + String state; + String user; + String priority; + unsigned linear; + unsigned committed; + float cpu_percent; + }; + + struct Process { + ProcessState current_state; + ProcessState previous_state; + }; + + HashMap> m_processes; + Vector m_pids; + int m_selected_row { -1 }; +}; diff --git a/Applications/ProcessManager/ProcessView.cpp b/Applications/ProcessManager/ProcessView.cpp index efc0e28d5e..6eee050fd2 100644 --- a/Applications/ProcessManager/ProcessView.cpp +++ b/Applications/ProcessManager/ProcessView.cpp @@ -6,173 +6,11 @@ #include #include #include -#include +#include "ProcessTableModel.h" #include "ProcessView.h" static HashMap* s_usernames; -class ProcessTableModel final : public GTableModel { -public: - ProcessTableModel() - { - - } - virtual ~ProcessTableModel() override { } - - virtual int row_count() const override { return m_processes.size(); } - virtual int column_count() const override { return 4; } - - virtual String column_name(int column) const override - { - switch (column) { - case 0: return "PID"; - case 1: return "State"; - case 2: return "CPU"; - case 3: return "Name"; - default: ASSERT_NOT_REACHED(); - } - } - virtual int column_width(int column) const override - { - switch (column) { - case 0: return 30; - case 1: return 80; - case 2: return 30; - case 3: return 200; - default: ASSERT_NOT_REACHED(); - } - } - - virtual GModelIndex selected_index() const override { return { m_selected_row, 0 }; } - virtual void set_selected_index(GModelIndex index) override - { - if (index.row() >= 0 && index.row() < m_pids.size()) - m_selected_row = index.row(); - } - - virtual String data(int row, int column) const override - { - if (row < 0 || row >= row_count()) - return { }; - if (column < 0 || column >= column_count()) - return { }; - auto it = m_processes.find(m_pids[row]); - auto& process = *(*it).value; - switch (column) { - case 0: return String::format("%d", process.current_state.pid); - case 1: return process.current_state.state; - case 2: return String::format("%d", (int)process.current_state.cpu_percent); - case 3: return process.current_state.name; - } - ASSERT_NOT_REACHED(); - } - - virtual void update() override - { - FILE* fp = fopen("/proc/all", "r"); - if (!fp) { - perror("failed to open /proc/all"); - exit(1); - } - - unsigned last_sum_nsched = 0; - for (auto& it : m_processes) - last_sum_nsched += it.value->current_state.nsched; - - HashTable live_pids; - unsigned sum_nsched = 0; - for (;;) { - char buf[BUFSIZ]; - char* ptr = fgets(buf, sizeof(buf), fp); - if (!ptr) - break; - auto parts = String(buf, Chomp).split(','); - if (parts.size() < 17) - break; - bool ok; - pid_t pid = parts[0].to_uint(ok); - ASSERT(ok); - unsigned nsched = parts[1].to_uint(ok); - ASSERT(ok); - ProcessState state; - state.pid = pid; - state.nsched = nsched; - unsigned uid = parts[5].to_uint(ok); - ASSERT(ok); - //state.user = s_usernames->get(uid); - state.user = String::format("%u", uid); - state.priority = parts[16]; - state.state = parts[7]; - state.name = parts[11]; - state.linear = parts[12].to_uint(ok); - ASSERT(ok); - state.committed = parts[13].to_uint(ok); - ASSERT(ok); - - { - auto it = m_processes.find(pid); - if (it == m_processes.end()) - m_processes.set(pid, make()); - } - auto it = m_processes.find(pid); - ASSERT(it != m_processes.end()); - (*it).value->previous_state = (*it).value->current_state; - (*it).value->current_state = state; - - live_pids.set(pid); - - sum_nsched += nsched; - } - int rc = fclose(fp); - ASSERT(rc == 0); - - m_pids.clear(); - Vector pids_to_remove; - for (auto& it : m_processes) { - if (!live_pids.contains(it.key)) { - pids_to_remove.append(it.key); - continue; - } - - auto& process = *it.value; - dword nsched_diff = process.current_state.nsched - process.previous_state.nsched; - process.current_state.cpu_percent = ((float)nsched_diff * 100) / (float)(sum_nsched - last_sum_nsched); - m_pids.append(it.key); - } - for (auto pid : pids_to_remove) - m_processes.remove(pid); - } - - pid_t selected_pid() const - { - if (m_selected_row == -1) - return -1; - return m_pids[m_selected_row]; - } - -private: - struct ProcessState { - pid_t pid; - unsigned nsched; - String name; - String state; - String user; - String priority; - unsigned linear; - unsigned committed; - float cpu_percent; - }; - - struct Process { - ProcessState current_state; - ProcessState previous_state; - }; - - HashMap> m_processes; - Vector m_pids; - int m_selected_row { -1 }; -}; - ProcessView::ProcessView(GWidget* parent) : GWidget(parent) { diff --git a/LibGUI/GTableModel.h b/LibGUI/GTableModel.h index c05db160d8..365bc84bf6 100644 --- a/LibGUI/GTableModel.h +++ b/LibGUI/GTableModel.h @@ -17,4 +17,9 @@ public: virtual void set_selected_index(GModelIndex) { } virtual GModelIndex selected_index() const { return GModelIndex(); } virtual void update() = 0; + + bool is_valid(GModelIndex index) const + { + return index.row() >= 0 && index.row() < row_count() && index.column() >= 0 && index.column() < column_count(); + } };