Refactor emulator status reporting (and fix the statusbar doesn't update bug)
[lsnes.git] / src / platform / wxwidgets / status.cpp
blob589dbef8949ce8b7290abd1645491236aec763ce
1 #include "core/emustatus.hpp"
2 #include "core/window.hpp"
3 #include "platform/wxwidgets/platform.hpp"
4 #include "platform/wxwidgets/window_status.hpp"
5 #include "platform/wxwidgets/window_mainwindow.hpp"
6 #include "library/string.hpp"
7 #include "library/minmax.hpp"
8 #include <iostream>
10 #define STATWIDTH 40
11 #define MAXSTATUS 15
13 namespace
15 std::string string_pad(const std::string& x, size_t width)
17 if(x.length() >= width)
18 return x;
19 std::string y = x;
20 y.append(width - y.length(), ' ');
21 return y;
25 wxwin_status::panel::panel(wxWindow* _parent, wxWindow* focuswin, unsigned lines)
26 : text_framebuffer_panel(_parent, STATWIDTH, lines ? lines : MAXSTATUS, wxID_ANY, focuswin)
28 watch_flag = 0;
31 wxwin_status::wxwin_status(int flag, const std::string& title)
32 : wxFrame(NULL, wxID_ANY, towxstring(title), wxDefaultPosition, wxSize(-1, -1),
33 wxMINIMIZE_BOX | wxRESIZE_BORDER | wxSYSTEM_MENU | wxCAPTION | wxCLIP_CHILDREN)
35 wxBoxSizer* top_s = new wxBoxSizer(wxVERTICAL);
36 top_s->Add(spanel = new wxwin_status::panel(this, NULL, MAXSTATUS), 1, wxGROW);
37 spanel->set_watch_flag(flag);
38 top_s->SetSizeHints(this);
39 SetSizer(top_s);
40 Fit();
43 wxwin_status::~wxwin_status()
47 namespace
49 void register_entry(size_t& count, size_t& width, const std::string& text)
51 width = max(width, text_framebuffer::text_width(text));
52 count++;
55 void show_entry(text_framebuffer_panel& tp, bool& sofar, size_t& line, size_t width, const std::string& name,
56 const std::u32string& text)
58 size_t n = tp.write(name, width + 1, 0, line, 0, 0xFFFFFF);
59 tp.write(text, 0, n, line++, 0, 0xFFFFFF);
60 sofar = true;
63 void draw_split(text_framebuffer_panel& tp, size_t& line)
65 auto s = tp.get_characters();
66 for(unsigned i = 0; i < s.first; i++)
67 tp.write(U"\u2500", 0, i, line, 0, 0xFFFFFF);
68 line++;
71 int num_nonzeroes() { return 0; }
72 template<typename T, typename... U> int num_nonzeroes(T hd, U... tl) {
73 return (hd ? 1 : 0) + num_nonzeroes(tl...);
75 template<typename... T> bool one_nonzero(T... args) { return (num_nonzeroes(args...) == 1); }
78 void wxwin_status::panel::prepare_paint()
80 clear();
82 auto& newstatus = lsnes_status.get_read();
83 try {
84 bool entry_so_far = false;
85 size_t mem_width = 0;
86 size_t oth_width = 0;
87 size_t lua_width = 0;
88 size_t mem_count = 0;
89 size_t oth_count = 0;
90 size_t lua_count = 0;
91 bool single = false;
92 for(auto& i : newstatus.mvars) register_entry(mem_count, mem_width, i.first);
93 if(newstatus.rtc_valid) register_entry(oth_count, oth_width, "RTC");
94 for(size_t j = 0; j < newstatus.inputs.size(); j++)
95 register_entry(oth_count, oth_width, (stringfmt() << "P" << (j + 1)).str());
96 for(auto& i : newstatus.lvars) register_entry(lua_count, lua_width, i.first);
98 if(watch_flag < 0) {
99 oth_count = 0;
100 lua_count = 0;
102 if(watch_flag > 0)
103 mem_count = 0;
104 single = one_nonzero(mem_count, oth_count, lua_count);
106 regex_results r;
107 size_t p = 0;
108 if(mem_count) {
109 if(entry_so_far) draw_split(*this, p);
110 if(!single) write("Memory watches:", 0, 0, p++, 0, 0xFFFFFF);
111 for(auto i : newstatus.mvars) show_entry(*this, entry_so_far, p, mem_width, i.first,
112 i.second);
115 if(oth_count) {
116 if(entry_so_far) draw_split(*this, p);
117 if(!single) write("Status:", 0, 0, p++, 0, 0xFFFFFF);
118 if(newstatus.rtc_valid) show_entry(*this, entry_so_far, p, oth_width, "RTC", newstatus.rtc);
119 for(size_t j = 0; j < newstatus.inputs.size(); j++)
120 show_entry(*this, entry_so_far, p, oth_width, (stringfmt() << "P" << (j + 1)).str(),
121 newstatus.inputs[j]);
124 if(lua_count) {
125 if(entry_so_far) draw_split(*this, p);
126 if(!single) write("From Lua:", 0, 0, p++, 0, 0xFFFFFF);
127 for(auto i : newstatus.lvars) show_entry(*this, entry_so_far, p, lua_width, i.first,
128 i.second);
130 } catch(...) {
132 lsnes_status.put_read();
135 void wxwin_status::notify_update() throw()
137 spanel->request_paint();
140 bool wxwin_status::ShouldPreventAppExit() const
142 return false;