Preserve desktop catalogue watches across chat selection
This commit is contained in:
1 parent
4fa9d474ab
commit
94697c1af0
2 files changed
+23
-14
No files matched your search
@@ -1,5 +1,7 @@
|
||||
#include "stream_bridge.h"
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
extern "C" {
|
||||
#include "../../../lib/debug_config.h"
|
||||
@@ -15,17 +17,22 @@ struct Bridge {
|
||||
std::mutex lock; // Ограничивает lifetime managers для callers GUI/workers.
|
||||
UTUN_INSTANCE* inst = nullptr;
|
||||
posted_task* pending = nullptr;
|
||||
uint64_t watch = 0;
|
||||
bool watchPending = false;
|
||||
std::map<uint64_t, uint64_t> watches;
|
||||
std::set<uint64_t> watchChanges;
|
||||
stream_viewers* viewers = nullptr;
|
||||
stream_publisher* publisher = nullptr;
|
||||
} bridge;
|
||||
|
||||
void watch(void*) {
|
||||
std::lock_guard<std::mutex> guard(bridge.lock);
|
||||
bridge.pending = nullptr; bridge.watchPending = false;
|
||||
if (stream_watch_sources(bridge.inst, bridge.watch) != STREAM_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop source watch failed group=%llx", (unsigned long long)bridge.watch);
|
||||
bridge.pending = nullptr;
|
||||
for (auto owner : bridge.watchChanges) {
|
||||
uint64_t group = bridge.watches.at(owner);
|
||||
if (stream_watch_sources(bridge.inst, group, owner) != STREAM_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop source watch failed group=%llx", (unsigned long long)group);
|
||||
if (!group) bridge.watches.erase(owner);
|
||||
}
|
||||
bridge.watchChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,11 +46,11 @@ bool gui_stream_attach(UTUN_INSTANCE* inst) {
|
||||
stream_publisher_destroy(bridge.publisher); bridge.publisher = nullptr; return false;
|
||||
}
|
||||
bridge.inst = inst;
|
||||
if (bridge.watchPending) {
|
||||
bridge.watchPending = false;
|
||||
if (stream_watch_sources(inst, bridge.watch) != STREAM_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop initial source watch failed group=%llx", (unsigned long long)bridge.watch);
|
||||
for (const auto& [owner, group] : bridge.watches) {
|
||||
if (stream_watch_sources(inst, group, owner) != STREAM_OK)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop initial source watch failed group=%llx", (unsigned long long)group);
|
||||
}
|
||||
bridge.watchChanges.clear();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop stream bridge attached"); return true;
|
||||
}
|
||||
|
||||
@@ -51,14 +58,15 @@ void gui_stream_detach(UTUN_INSTANCE* inst) {
|
||||
std::lock_guard<std::mutex> guard(bridge.lock);
|
||||
if (!inst || bridge.inst != inst) return;
|
||||
if (bridge.pending) uasync_cancel_post(inst->ua, bridge.pending);
|
||||
stream_watch_sources(inst, 0); bridge.pending = nullptr;
|
||||
for (const auto& [owner, group] : bridge.watches) stream_watch_sources(inst, 0, owner);
|
||||
bridge.pending = nullptr;
|
||||
stream_viewers_destroy(bridge.viewers); bridge.viewers = nullptr;
|
||||
stream_publisher_destroy(bridge.publisher); bridge.publisher = nullptr;
|
||||
bridge.inst = nullptr; bridge.watchPending = bridge.watch != 0;
|
||||
bridge.inst = nullptr; bridge.watchChanges.clear();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop stream bridge detached");
|
||||
}
|
||||
|
||||
bool gui_stream_watch(uint64_t group) {
|
||||
bool gui_stream_watch(uint64_t group, uint64_t owner) {
|
||||
std::lock_guard<std::mutex> guard(bridge.lock);
|
||||
if (bridge.inst && !bridge.pending) {
|
||||
auto* task = static_cast<posted_task*>(u_calloc(1, sizeof(posted_task)));
|
||||
@@ -66,7 +74,7 @@ bool gui_stream_watch(uint64_t group) {
|
||||
task->callback = watch; bridge.pending = task;
|
||||
uasync_post_reserved(bridge.inst->ua, task);
|
||||
}
|
||||
bridge.watch = group; bridge.watchPending = true; return true;
|
||||
bridge.watches[owner] = group; bridge.watchChanges.insert(owner); return true;
|
||||
}
|
||||
|
||||
bool gui_stream_open(uint64_t id, uint64_t group, uint64_t source, uint64_t epoch) {
|
||||
|
||||
@@ -23,7 +23,8 @@ struct StreamRecord {
|
||||
|
||||
bool gui_stream_attach(UTUN_INSTANCE* inst);
|
||||
void gui_stream_detach(UTUN_INSTANCE* inst);
|
||||
bool gui_stream_watch(uint64_t group);
|
||||
/* owner=0 — выбранный чат; окно многопросмотра держит свой ненулевой owner. group=0 снимает только его. */
|
||||
bool gui_stream_watch(uint64_t group, uint64_t owner = 0);
|
||||
bool gui_stream_open(uint64_t id, uint64_t group, uint64_t source, uint64_t epoch);
|
||||
void gui_stream_stop(uint64_t id);
|
||||
bool gui_stream_pull(uint64_t id, StreamRecord& record, int64_t position = -1,
|
||||
|
||||
Reference in new issue
Block a user