|
|
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.