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