File:  [Isaki's NoNo m68k/m88k emulator] / nono / wx / wxthreadmonitor.cpp
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:57 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
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()
{
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.