improved perfs and event management
This commit is contained in:
1 parent
667ed0c100
commit
bb99be5889
17 files changed
+626
-59
No files matched your search
+70
-6
@@ -1892,8 +1892,13 @@ gboolean layout_probe_step(gpointer user) {
|
||||
|
||||
gboolean enable_all_probe(gpointer user) {
|
||||
App* a = static_cast<App*>(user);
|
||||
for (std::size_t i = 0; i < a->model->signals().size(); ++i) {
|
||||
a->model->set_signal_enabled(i, true);
|
||||
// In one call, the way a restored session does it: enabling them one at a time re-plans
|
||||
// the buffer per signal, so a probe that did that would not be measuring the path a real
|
||||
// start takes (and `[gen]` would read a burst that the application no longer produces).
|
||||
{
|
||||
std::vector<std::size_t> all(a->model->signals().size());
|
||||
for (std::size_t i = 0; i < all.size(); ++i) all[i] = i;
|
||||
a->model->set_signals_enabled(all, true);
|
||||
}
|
||||
int row = 0;
|
||||
int slot = 0;
|
||||
@@ -1908,8 +1913,12 @@ gboolean enable_all_probe(gpointer user) {
|
||||
}
|
||||
}
|
||||
a->relayout_pending = true;
|
||||
std::fprintf(stderr, "[enable-all-probe] %zu channel(s) enabled and assigned to plots\n",
|
||||
a->model->channel_count());
|
||||
// The startup notice comes with the reading, because it is the window's only answer to "why is
|
||||
// nothing happening yet": it is set as the window is presented, before the first CONFIG can take
|
||||
// the model's mutex, and it names the buffer being planned. An empty `notice` here is the window
|
||||
// that used to come up silent while a large buffer was allocated.
|
||||
std::fprintf(stderr, "[enable-all-probe] %zu channel(s) enabled and assigned to plots, notice='%s'\n",
|
||||
a->model->channel_count(), a->notice.c_str());
|
||||
std::fflush(stderr);
|
||||
// Then switch one off through its own switch in the signal list: a disabled signal must leave the plots,
|
||||
// not sit there drawing nothing in a slot a live one could take. Late enough that a math probe armed behind
|
||||
@@ -3158,6 +3167,40 @@ gboolean events_probe_step(gpointer user) {
|
||||
}
|
||||
|
||||
if (a->dbg_events_step == 1) {
|
||||
// The preview's repair, measured before anything else reads the pane: the newest event's picture
|
||||
// is deleted and the pane refreshed, so the row that comes back proves the pane draws it again
|
||||
// from the samples rather than showing a blank. The stored geometry is read back too, because the
|
||||
// defect this fixes was a readable *file* that was too short to read -- `strip_h * signals` says
|
||||
// the picture grew with the signal count, a fixed 160 says it did not.
|
||||
const std::vector<EventRecord> before = a->event_store->list();
|
||||
if (!before.empty()) {
|
||||
const std::string bmp = a->event_store->dir() + "/" + before.front().stem + ".bmp";
|
||||
::remove(bmp.c_str());
|
||||
// The decoded picture has to go with the file: the cache answers by path and would hand back
|
||||
// the texture of a file that is no longer there, so the refresh would never reach the repair.
|
||||
if (EventThumbCache* cache = event_thumb_cache(*a)) {
|
||||
for (auto& entry : *cache) {
|
||||
if (entry.second != nullptr) g_object_unref(entry.second);
|
||||
}
|
||||
cache->clear();
|
||||
}
|
||||
refresh_events_pane(*a);
|
||||
int w = -1;
|
||||
int h = -1;
|
||||
if (std::FILE* f = std::fopen(bmp.c_str(), "rb"); f != nullptr) {
|
||||
unsigned char head[26] = {};
|
||||
if (std::fread(head, 1, sizeof(head), f) == sizeof(head)) {
|
||||
w = int(head[18]) | int(head[19]) << 8 | int(head[20]) << 16;
|
||||
h = int(head[22]) | int(head[23]) << 8 | int(head[24]) << 16;
|
||||
}
|
||||
std::fclose(f);
|
||||
}
|
||||
const bool drawn = a->events_thumb != nullptr &&
|
||||
gtk_picture_get_paintable(GTK_PICTURE(a->events_thumb)) != nullptr;
|
||||
std::fprintf(stderr, "[events] preview redrawn: signals=%zu stored=%dx%d row_drawn=%d\n",
|
||||
before.front().signals, w, h, drawn ? 1 : 0);
|
||||
std::fflush(stderr);
|
||||
}
|
||||
const std::vector<EventRecord> records = a->event_store->list();
|
||||
std::fprintf(stderr, "[events] dir=%s n=%zu", a->event_store->dir().c_str(), records.size());
|
||||
if (!records.empty()) {
|
||||
@@ -3185,6 +3228,18 @@ gboolean events_probe_step(gpointer user) {
|
||||
// "framed" from "untouched".
|
||||
apply_time_window(*a, 0.5);
|
||||
GtkListBoxRow* row = gtk_list_box_get_row_at_index(GTK_LIST_BOX(a->events_list), 0);
|
||||
// Selected *and* remembered, because what the activation must not do is rebuild the list:
|
||||
// a selection the user made for a comparison, and the row object itself, are what a
|
||||
// rebuild silently discarded. Two rows, so the reading after the click can say the
|
||||
// selection survived rather than merely that something is selected.
|
||||
if (row != nullptr) gtk_list_box_select_row(GTK_LIST_BOX(a->events_list), row);
|
||||
if (GtkListBoxRow* second = gtk_list_box_get_row_at_index(GTK_LIST_BOX(a->events_list), 1)) {
|
||||
gtk_list_box_select_row(GTK_LIST_BOX(a->events_list), second);
|
||||
}
|
||||
a->dbg_events_row0 = row;
|
||||
GList* chosen = gtk_list_box_get_selected_rows(GTK_LIST_BOX(a->events_list));
|
||||
a->dbg_events_selected = int(g_list_length(chosen));
|
||||
g_list_free(chosen);
|
||||
if (row != nullptr) g_signal_emit_by_name(a->events_list, "row-activated", row);
|
||||
}
|
||||
// One layout pass before the picture is measured: a widget created a moment ago has no
|
||||
@@ -3198,10 +3253,18 @@ gboolean events_probe_step(gpointer user) {
|
||||
// is set, so a non-null one says nothing about whether anything is on screen.
|
||||
const bool picture = a->events_thumb != nullptr &&
|
||||
gtk_picture_get_paintable(GTK_PICTURE(a->events_thumb)) != nullptr;
|
||||
// The row *object*, not its index: a rebuilt list has a row 0 too, so only identity tells a
|
||||
// list that was left alone from one that was torn down and refilled under the user's scroll.
|
||||
const bool rows_kept =
|
||||
a->dbg_events_row0 != nullptr &&
|
||||
gtk_list_box_get_row_at_index(GTK_LIST_BOX(a->events_list), 0) == a->dbg_events_row0;
|
||||
GList* still = gtk_list_box_get_selected_rows(GTK_LIST_BOX(a->events_list));
|
||||
const int selected_now = int(g_list_length(still));
|
||||
g_list_free(still);
|
||||
std::fprintf(stderr,
|
||||
"[events] activated row0: replaying=%d pane=%d pane_w=%d pane_box=%d tick=%d "
|
||||
"window=%.3f axis=[%.3f,%.3f] marker=%.3f "
|
||||
"thumbnail=%d thumb_size=%dx%d thumb_visible=%d\n",
|
||||
"thumbnail=%d thumb_size=%dx%d thumb_visible=%d rows_kept=%d selected=%d/%d\n",
|
||||
a->replaying ? 1 : 0,
|
||||
a->events_revealer != nullptr && gtk_widget_get_visible(a->events_revealer) ? 1 : 0,
|
||||
a->events_divider != nullptr ? gtk_paned_get_position(GTK_PANED(a->events_divider))
|
||||
@@ -3226,7 +3289,8 @@ gboolean events_probe_step(gpointer user) {
|
||||
picture ? 1 : 0,
|
||||
a->events_thumb != nullptr ? gtk_widget_get_width(a->events_thumb) : -1,
|
||||
a->events_thumb != nullptr ? gtk_widget_get_height(a->events_thumb) : -1,
|
||||
a->events_thumb != nullptr && gtk_widget_get_mapped(a->events_thumb) ? 1 : 0);
|
||||
a->events_thumb != nullptr && gtk_widget_get_mapped(a->events_thumb) ? 1 : 0,
|
||||
rows_kept ? 1 : 0, selected_now, a->dbg_events_selected);
|
||||
std::fflush(stderr);
|
||||
events_probe_next(*a, 2, 1200);
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
Reference in new issue
Block a user