|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2025 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // スレッドモニタ
9: //
10:
11: #include "wxthreadmonitor.h"
12: #include "wxtextscreen.h"
13: #include "mainapp.h"
14: #include "thread.h"
15:
16:
17: // パネルには WXTextScreen 同様に四辺に DefaultPadding を手動で入れてある。
18:
19: // イベントテーブル
20: wxBEGIN_EVENT_TABLE(WXThreadMonitorPanel, inherited)
21: EVT_TIMER(wxID_ANY, WXThreadMonitorPanel::OnTimer)
22: wxEND_EVENT_TABLE()
23:
24: // コンストラクタ
25: WXThreadMonitorPanel::WXThreadMonitorPanel(wxWindow *parent)
26: : inherited(parent)
27: {
28: SetName("ThreadMonitorPanel");
29:
30: thman = gMainApp.GetThreadManager();
31:
32: // スレッド数とスレッド名の長さはここで一度だけ取得?。
33: {
34: std::lock_guard<std::mutex> lock(thman->threads_mutex);
35:
36: nthreads = thman->threads.size();
37: maxnamelen = 0;
38: for (const auto& info : thman->threads) {
39: maxnamelen = std::max(maxnamelen, (uint)info.name.size());
40: }
41: }
42:
43: FontChanged();
44:
45: timer.SetOwner(this);
46: timer.Start(500);
47: }
48:
49: // デストラクタ
50: WXThreadMonitorPanel::~WXThreadMonitorPanel()
51: {
52: }
53:
54: void
55: WXThreadMonitorPanel::FontChanged()
56: {
57: constexpr int padding = WXTextScreen::DefaultPadding;
58:
59: inherited::FontChanged();
60:
61: uint cap = ThreadInfo::Capacity;
62: wxSize size(
63: (maxnamelen + 6) * font_width + cap * 2 + padding * 2,
64: (nthreads * 2 + 1) * font_height + padding * 2);
65:
66: // バックバッファのサイズを固定
67: SetMinBitmapSize(size);
68:
69: SetSize(size);
70: SetMinSize(size);
71:
72: redraw_all = true;
73: }
74:
75: void
76: WXThreadMonitorPanel::OnTimer(wxTimerEvent& event)
77: {
78: Refresh();
79: }
80:
81: void
82: WXThreadMonitorPanel::Draw()
83: {
84: constexpr int padding = WXTextScreen::DefaultPadding;
85: int y;
86: int x;
87:
88: if (redraw_all) {
89: Fill();
90: redraw_all = false;
91:
92: y = 1;
93: for (const auto& info : thman->threads) {
94: DrawStringSJIS(padding,
95: padding + y * font_height + font_height / 2,
96: info.name.c_str());
97: y += 2;
98: }
99: }
100: x = maxnamelen + 1;
101:
102: // 現在値
103: uint tx = padding + x * font_width;
104: x += 5;
105: // グラフの開始位置とサイズ
106: uint gx = padding + x * font_width;
107: uint gw = bitmap.GetWidth() - padding - gx;
108: uint gh = font_height * 2 - 2;
109: y = 1;
110: for (const auto& info : thman->threads) {
111: char numbuf[16];
112: snprintf(numbuf, sizeof(numbuf), "%3u%%", info.load->PeekLatest());
113: uint ty = padding + y * font_height + font_height / 2;
114: DrawStringSJIS(tx, ty, numbuf);
115:
116: uint gy = padding + y * font_height;
117: DrawGraph(gx, gy, gw, gh, info);
118: y += 2;
119: }
120: }
121:
122: void
123: WXThreadMonitorPanel::DrawGraph(uint left, uint top, uint width, uint height,
124: const ThreadInfo& info)
125: {
126: bitmap.FillRect(UD_WHITE, left, top, width, height);
127:
128: uint cap = info.load->Capacity();
129: uint len = info.load->Length();
130: uint blank = cap - len;
131: for (int t = 0; t < len; t++) {
132: uint v = info.load->Peek(t);
133: if (v != 0) {
134: uint ph = v * height / 100;
135: uint x0 = left + (blank + t) * 2;
136: uint y1 = top + height;
137: uint y0 = y1 - ph;
138: bitmap.FillRect(UD_GREEN, x0, y0, 2, ph);
139: }
140: }
141: }
142:
143:
144: //
145: // スレッドモニタウィンドウ
146: //
147:
148: // コンストラクタ
149: WXThreadMonitorWindow::WXThreadMonitorWindow(wxWindow *parent)
150: : inherited(parent, wxID_ANY, _("Thread Status"))
151: {
152: new WXThreadMonitorPanel(this);
153: Fit();
154: }
155:
156: // デストラクタ
157: WXThreadMonitorWindow::~WXThreadMonitorWindow()
158: {
159: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.