|
|
nono 1.7.0
//
// nono
// Copyright (C) 2025 nono project
// Licensed under nono-license.txt
//
//
// スレッドモニタ
//
#include "wxthreadmonitor.h"
#include "wxtextscreen.h"
#include "mainapp.h"
#include "thread.h"
// パネルには WXTextScreen 同様に四辺に DefaultPadding を手動で入れてある。
// イベントテーブル
wxBEGIN_EVENT_TABLE(WXThreadMonitorPanel, inherited)
EVT_TIMER(wxID_ANY, WXThreadMonitorPanel::OnTimer)
wxEND_EVENT_TABLE()
// コンストラクタ
WXThreadMonitorPanel::WXThreadMonitorPanel(wxWindow *parent)
: inherited(parent)
{
SetName("ThreadMonitorPanel");
thman = gMainApp.GetThreadManager();
// スレッド数とスレッド名の長さはここで一度だけ取得?。
{
std::lock_guard<std::mutex> lock(thman->threads_mutex);
nthreads = thman->threads.size();
maxnamelen = 0;
for (const auto& info : thman->threads) {
maxnamelen = std::max(maxnamelen, (uint)info.name.size());
}
}
FontChanged();
timer.SetOwner(this);
timer.Start(500);
}
// デストラクタ
WXThreadMonitorPanel::~WXThreadMonitorPanel()
{
}
void
WXThreadMonitorPanel::FontChanged()
{
constexpr int padding = WXTextScreen::DefaultPadding;
inherited::FontChanged();
uint cap = ThreadInfo::Capacity;
wxSize size(
(maxnamelen + 6) * font_width + cap * 2 + padding * 2,
(nthreads * 2 + 1) * font_height + padding * 2);
// バックバッファのサイズを固定
SetMinBitmapSize(size);
SetSize(size);
SetMinSize(size);
redraw_all = true;
}
void
WXThreadMonitorPanel::OnTimer(wxTimerEvent& event)
{
Refresh();
}
void
WXThreadMonitorPanel::Draw()
{
constexpr int padding = WXTextScreen::DefaultPadding;
int y;
int x;
if (redraw_all) {
Fill();
redraw_all = false;
y = 1;
for (const auto& info : thman->threads) {
DrawStringSJIS(padding,
padding + y * font_height + font_height / 2,
info.name.c_str());
y += 2;
}
}
x = maxnamelen + 1;
// 現在値
uint tx = padding + x * font_width;
x += 5;
// グラフの開始位置とサイズ
uint gx = padding + x * font_width;
uint gw = bitmap.GetWidth() - padding - gx;
uint gh = font_height * 2 - 2;
y = 1;
for (const auto& info : thman->threads) {
char numbuf[16];
snprintf(numbuf, sizeof(numbuf), "%3u%%", info.load->PeekLatest());
uint ty = padding + y * font_height + font_height / 2;
DrawStringSJIS(tx, ty, numbuf);
uint gy = padding + y * font_height;
DrawGraph(gx, gy, gw, gh, info);
y += 2;
}
}
void
WXThreadMonitorPanel::DrawGraph(uint left, uint top, uint width, uint height,
const ThreadInfo& info)
{
bitmap.FillRect(UD_WHITE, left, top, width, height);
uint cap = info.load->Capacity();
uint len = info.load->Length();
uint blank = cap - len;
for (int t = 0; t < len; t++) {
uint v = info.load->Peek(t);
if (v != 0) {
uint ph = v * height / 100;
uint x0 = left + (blank + t) * 2;
uint y1 = top + height;
uint y0 = y1 - ph;
bitmap.FillRect(UD_GREEN, x0, y0, 2, ph);
}
}
}
//
// スレッドモニタウィンドウ
//
// コンストラクタ
WXThreadMonitorWindow::WXThreadMonitorWindow(wxWindow *parent)
: inherited(parent, wxID_ANY, _("Thread Status"))
{
new WXThreadMonitorPanel(this);
Fit();
}
// デストラクタ
WXThreadMonitorWindow::~WXThreadMonitorWindow()
{
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.