aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2026-02-10 12:27:00 +0100
committerDan Engelbrecht <[email protected]>2026-02-10 12:27:00 +0100
commit49b2c5aea6daadda6b3fc5edc2dff59bae3caad6 (patch)
treeb3c4d42fb2ce1d091bee5c717ab78a3f36e77012
parentrefactor/cleanup (diff)
downloadzen-de/download-feedback-api.tar.xz
zen-de/download-feedback-api.zip
handle exception while UI is opende/download-feedback-api
-rw-r--r--src/zen/cmds/view_cmd.cpp65
-rw-r--r--src/zen/imgui_ui.cpp12
-rw-r--r--src/zen/imgui_ui.h3
3 files changed, 65 insertions, 15 deletions
diff --git a/src/zen/cmds/view_cmd.cpp b/src/zen/cmds/view_cmd.cpp
index 8d81a6680..d43a712c9 100644
--- a/src/zen/cmds/view_cmd.cpp
+++ b/src/zen/cmds/view_cmd.cpp
@@ -173,19 +173,23 @@ namespace {
const uint64_t CurrentTimeUs = m_CurrentTimeUs.load();
if (CurrentTimeUs != m_LastRenderTimeUs)
{
- if (CurrentTimeUs < m_LastRenderTimeUs)
+ while (CurrentTimeUs < m_LastRenderTimeUs && m_LastRenderEventIndex > 0)
{
- // Slow! This will playback all state from the start if we go backwards...
- RwLock::ExclusiveLockScope _(m_Lock);
- ResetSequenceState();
- m_LastRenderTimeUs = 0;
- m_LastRenderEventIndex = 0;
+ if (m_Events[m_LastRenderEventIndex - 1].Header.TimestampUs() >= CurrentTimeUs)
+ {
+ RemoveEventFromState(m_Events[m_LastRenderEventIndex]);
+ m_LastRenderEventIndex--;
+ }
+ else
+ {
+ break;
+ }
}
while (m_LastRenderTimeUs < CurrentTimeUs && m_LastRenderEventIndex < m_Events.size())
{
if (m_Events[m_LastRenderEventIndex].Header.TimestampUs() <= CurrentTimeUs)
{
- UpdateStateWithEvent(m_Events[m_LastRenderEventIndex]);
+ AddEventToState(m_Events[m_LastRenderEventIndex]);
m_LastRenderEventIndex++;
}
else
@@ -193,10 +197,38 @@ namespace {
break;
}
}
+ m_LastRenderTimeUs = CurrentTimeUs;
+ }
+ }
+
+ void RemoveEventFromState(const UpdateFolderEventDiskStream::Event& Event)
+ {
+ switch (Event.Header.EventType)
+ {
+ case UpdateFolderEventDiskStream::Event::EventType::WroteSequence:
+ {
+ ChunkSequenceStatus& Sequence = m_RenderSequenceStatues[Event.Payload.WroteSequence.RemoteSequenceIndex];
+ ZEN_ASSERT(!Sequence.Completed);
+ Sequence.RemoveCompletedRange(
+ ChunkSequenceStatus::Range{Event.Payload.WroteSequence.Offset, Event.Payload.WroteSequence.Length});
+ }
+ break;
+ case UpdateFolderEventDiskStream::Event::EventType::CompletedSequence:
+ {
+ ChunkSequenceStatus& Sequence = m_RenderSequenceStatues[Event.Payload.CompletedSequence.RemoteSequenceIndex];
+ ZEN_ASSERT(Sequence.Completed);
+ Sequence.Completed = false;
+ }
+ break;
+ case UpdateFolderEventDiskStream::Event::EventType::WriteComplete:
+ break;
+ default:
+ // TODO
+ break;
}
}
- void UpdateStateWithEvent(const UpdateFolderEventDiskStream::Event& Event)
+ void AddEventToState(const UpdateFolderEventDiskStream::Event& Event)
{
switch (Event.Header.EventType)
{
@@ -314,6 +346,8 @@ ViewCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
throw OptionParseException(fmt::format("Unknown input format for '{}'", m_InputStream), m_Options.help());
}
+ std::atomic<bool> CloseUIFlag = false;
+
Event UiClosed;
std::thread UIThread = OpenImGuiWindow(
@@ -321,14 +355,23 @@ ViewCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv)
720,
UI->Title(),
[&UI](int display_w, int display_h) { UI->Render(display_w, display_h); },
- [&UiClosed]() { UiClosed.Set(); });
-
- UI->Read(m_InputStream);
+ [&UiClosed]() { UiClosed.Set(); },
+ [&CloseUIFlag]() { return CloseUIFlag.load(); });
auto CloseUI = MakeGuard([&]() {
UiClosed.Wait();
UIThread.join();
});
+
+ try
+ {
+ UI->Read(m_InputStream);
+ }
+ catch (const std::exception&)
+ {
+ CloseUIFlag.store(true);
+ throw;
+ }
}
} // namespace zen
diff --git a/src/zen/imgui_ui.cpp b/src/zen/imgui_ui.cpp
index 14c64829f..508532377 100644
--- a/src/zen/imgui_ui.cpp
+++ b/src/zen/imgui_ui.cpp
@@ -32,9 +32,15 @@ OpenImGuiWindow(int Width,
int Height,
std::string_view Title,
std::function<void(int display_w, int display_h)>&& UICallback,
- std::function<void()>&& OnClosed)
+ std::function<void()>&& OnClosed,
+ std::function<bool()>&& ShouldExit)
{
- return std::thread([Width, Height, Title = std::string(Title), UICallback = std::move(UICallback), OnClosed = std::move(OnClosed)]() {
+ return std::thread([Width,
+ Height,
+ Title = std::string(Title),
+ UICallback = std::move(UICallback),
+ OnClosed = std::move(OnClosed),
+ ShouldExit = std::move(ShouldExit)]() {
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
return 1;
@@ -89,7 +95,7 @@ OpenImGuiWindow(int Width,
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
- while (!glfwWindowShouldClose(window))
+ while (!ShouldExit() && !glfwWindowShouldClose(window))
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
diff --git a/src/zen/imgui_ui.h b/src/zen/imgui_ui.h
index 59a394d9c..47c57e6ac 100644
--- a/src/zen/imgui_ui.h
+++ b/src/zen/imgui_ui.h
@@ -32,6 +32,7 @@ std::thread OpenImGuiWindow(int Width,
int Height,
std::string_view Title,
std::function<void(int display_w, int display_h)>&& UICallback,
- std::function<void()>&& OnClosed);
+ std::function<void()>&& OnClosed,
+ std::function<bool()>&& ShouldExit);
} // namespace zen