improve streams also throw os events
This commit is contained in:
parent
4d5d708d6d
commit
d0eeef2b94
@ -32,18 +32,5 @@ namespace Content1::Components {
|
|||||||
entt::dense_set<Contact3> participants;
|
entt::dense_set<Contact3> participants;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReadHeadHint {
|
|
||||||
// points to the first byte we want
|
|
||||||
// this is just a hint, that can be set from outside
|
|
||||||
// to guide the sequential "piece picker" strategy
|
|
||||||
// the strategy *should* set this to the first byte we dont yet have
|
|
||||||
uint64_t offset_into_file {0u};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // Content::Components
|
} // Content::Components
|
||||||
|
|
||||||
// TODO: i have no idea
|
|
||||||
struct RawFile2ReadFromContentFactoryI {
|
|
||||||
virtual std::shared_ptr<File2I> open(ObjectHandle h) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
@ -274,15 +274,19 @@ DebugToxCall::~DebugToxCall(void) {
|
|||||||
|
|
||||||
for (auto& [fid, call] : _calls) {
|
for (auto& [fid, call] : _calls) {
|
||||||
if (static_cast<bool>(call.incoming_vsrc)) {
|
if (static_cast<bool>(call.incoming_vsrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_vsrc);
|
||||||
call.incoming_vsrc.destroy();
|
call.incoming_vsrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.incoming_asrc)) {
|
if (static_cast<bool>(call.incoming_asrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_asrc);
|
||||||
call.incoming_asrc.destroy();
|
call.incoming_asrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_vsink)) {
|
if (static_cast<bool>(call.outgoing_vsink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_vsink);
|
||||||
call.outgoing_vsink.destroy();
|
call.outgoing_vsink.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_asink)) {
|
if (static_cast<bool>(call.outgoing_asink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_asink);
|
||||||
call.outgoing_asink.destroy();
|
call.outgoing_asink.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,14 +379,16 @@ float DebugToxCall::render(void) {
|
|||||||
auto new_vsink = std::make_unique<ToxAVCallVideoSink>(_toxav, fid);
|
auto new_vsink = std::make_unique<ToxAVCallVideoSink>(_toxav, fid);
|
||||||
call.outgoing_vsink.emplace<ToxAVCallVideoSink*>(new_vsink.get());
|
call.outgoing_vsink.emplace<ToxAVCallVideoSink*>(new_vsink.get());
|
||||||
call.outgoing_vsink.emplace<Components::FrameStream2Sink<SDLVideoFrame>>(std::move(new_vsink));
|
call.outgoing_vsink.emplace<Components::FrameStream2Sink<SDLVideoFrame>>(std::move(new_vsink));
|
||||||
call.outgoing_vsink.emplace<Components::StreamSink>("ToxAV friend call video", std::string{entt::type_name<SDLVideoFrame>::value()});
|
call.outgoing_vsink.emplace<Components::StreamSink>(Components::StreamSink::create<SDLVideoFrame>("ToxAV friend call video"));
|
||||||
|
_os.throwEventConstruct(call.outgoing_vsink);
|
||||||
}
|
}
|
||||||
call.outgoing_asink = {_os.registry(), _os.registry().create()};
|
call.outgoing_asink = {_os.registry(), _os.registry().create()};
|
||||||
{
|
{
|
||||||
auto new_asink = std::make_unique<ToxAVCallAudioSink>(_toxav, fid);
|
auto new_asink = std::make_unique<ToxAVCallAudioSink>(_toxav, fid);
|
||||||
call.outgoing_asink.emplace<ToxAVCallAudioSink*>(new_asink.get());
|
call.outgoing_asink.emplace<ToxAVCallAudioSink*>(new_asink.get());
|
||||||
call.outgoing_asink.emplace<Components::FrameStream2Sink<AudioFrame>>(std::move(new_asink));
|
call.outgoing_asink.emplace<Components::FrameStream2Sink<AudioFrame>>(std::move(new_asink));
|
||||||
call.outgoing_asink.emplace<Components::StreamSink>("ToxAV friend call audio", std::string{entt::type_name<AudioFrame>::value()});
|
call.outgoing_asink.emplace<Components::StreamSink>(Components::StreamSink::create<AudioFrame>("ToxAV friend call audio"));
|
||||||
|
_os.throwEventConstruct(call.outgoing_asink);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create sources
|
// create sources
|
||||||
@ -392,7 +398,8 @@ float DebugToxCall::render(void) {
|
|||||||
auto new_vsrc = std::make_unique<SDLVideoFrameStream2MultiSource>();
|
auto new_vsrc = std::make_unique<SDLVideoFrameStream2MultiSource>();
|
||||||
call.incoming_vsrc.emplace<SDLVideoFrameStream2MultiSource*>(new_vsrc.get());
|
call.incoming_vsrc.emplace<SDLVideoFrameStream2MultiSource*>(new_vsrc.get());
|
||||||
call.incoming_vsrc.emplace<Components::FrameStream2Source<SDLVideoFrame>>(std::move(new_vsrc));
|
call.incoming_vsrc.emplace<Components::FrameStream2Source<SDLVideoFrame>>(std::move(new_vsrc));
|
||||||
call.incoming_vsrc.emplace<Components::StreamSource>("ToxAV friend call video", std::string{entt::type_name<SDLVideoFrame>::value()});
|
call.incoming_vsrc.emplace<Components::StreamSource>(Components::StreamSource::create<SDLVideoFrame>("ToxAV friend call video"));
|
||||||
|
_os.throwEventConstruct(call.incoming_vsrc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (call.incoming_a) {
|
if (call.incoming_a) {
|
||||||
@ -401,7 +408,8 @@ float DebugToxCall::render(void) {
|
|||||||
auto new_asrc = std::make_unique<AudioFrameStream2MultiSource>();
|
auto new_asrc = std::make_unique<AudioFrameStream2MultiSource>();
|
||||||
call.incoming_asrc.emplace<AudioFrameStream2MultiSource*>(new_asrc.get());
|
call.incoming_asrc.emplace<AudioFrameStream2MultiSource*>(new_asrc.get());
|
||||||
call.incoming_asrc.emplace<Components::FrameStream2Source<AudioFrame>>(std::move(new_asrc));
|
call.incoming_asrc.emplace<Components::FrameStream2Source<AudioFrame>>(std::move(new_asrc));
|
||||||
call.incoming_asrc.emplace<Components::StreamSource>("ToxAV friend call audio", std::string{entt::type_name<AudioFrame>::value()});
|
call.incoming_asrc.emplace<Components::StreamSource>(Components::StreamSource::create<AudioFrame>("ToxAV friend call audio"));
|
||||||
|
_os.throwEventConstruct(call.incoming_asrc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,15 +426,19 @@ float DebugToxCall::render(void) {
|
|||||||
|
|
||||||
// TODO: stream manager disconnectAll()
|
// TODO: stream manager disconnectAll()
|
||||||
if (static_cast<bool>(call.incoming_vsrc)) {
|
if (static_cast<bool>(call.incoming_vsrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_vsrc);
|
||||||
call.incoming_vsrc.destroy();
|
call.incoming_vsrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.incoming_asrc)) {
|
if (static_cast<bool>(call.incoming_asrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_asrc);
|
||||||
call.incoming_asrc.destroy();
|
call.incoming_asrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_vsink)) {
|
if (static_cast<bool>(call.outgoing_vsink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_vsink);
|
||||||
call.outgoing_vsink.destroy();
|
call.outgoing_vsink.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_asink)) {
|
if (static_cast<bool>(call.outgoing_asink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_asink);
|
||||||
call.outgoing_asink.destroy();
|
call.outgoing_asink.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,15 +480,19 @@ bool DebugToxCall::onEvent(const Events::FriendCallState& e) {
|
|||||||
(call.state & TOXAV_FRIEND_CALL_STATE_ERROR) != 0
|
(call.state & TOXAV_FRIEND_CALL_STATE_ERROR) != 0
|
||||||
) {
|
) {
|
||||||
if (static_cast<bool>(call.incoming_vsrc)) {
|
if (static_cast<bool>(call.incoming_vsrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_vsrc);
|
||||||
call.incoming_vsrc.destroy();
|
call.incoming_vsrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.incoming_asrc)) {
|
if (static_cast<bool>(call.incoming_asrc)) {
|
||||||
|
_os.throwEventDestroy(call.incoming_asrc);
|
||||||
call.incoming_asrc.destroy();
|
call.incoming_asrc.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_vsink)) {
|
if (static_cast<bool>(call.outgoing_vsink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_vsink);
|
||||||
call.outgoing_vsink.destroy();
|
call.outgoing_vsink.destroy();
|
||||||
}
|
}
|
||||||
if (static_cast<bool>(call.outgoing_asink)) {
|
if (static_cast<bool>(call.outgoing_asink)) {
|
||||||
|
_os.throwEventDestroy(call.outgoing_asink);
|
||||||
call.outgoing_asink.destroy();
|
call.outgoing_asink.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ DebugVideoTap::DebugVideoTap(ObjectStore2& os, StreamManager& sm, TextureUploade
|
|||||||
std::move(dvts)
|
std::move(dvts)
|
||||||
);
|
);
|
||||||
|
|
||||||
_tap.emplace<Components::StreamSink>("DebugVideoTap", std::string{entt::type_name<SDLVideoFrame>::value()});
|
_tap.emplace<Components::StreamSink>(Components::StreamSink::create<SDLVideoFrame>("DebugVideoTap"));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
_os.registry().destroy(_tap);
|
_os.registry().destroy(_tap);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,9 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
|
|||||||
std::make_unique<SDLVideoCameraContent>()
|
std::make_unique<SDLVideoCameraContent>()
|
||||||
);
|
);
|
||||||
|
|
||||||
vsrc.emplace<Components::StreamSource>("WebCam", std::string{entt::type_name<SDLVideoFrame>::value()});
|
vsrc.emplace<Components::StreamSource>(Components::StreamSource::create<SDLVideoFrame>("WebCam"));
|
||||||
|
|
||||||
|
os.throwEventConstruct(vsrc);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
os.registry().destroy(vsrc);
|
os.registry().destroy(vsrc);
|
||||||
}
|
}
|
||||||
@ -176,7 +178,9 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
|
|||||||
std::make_unique<SDLAudioOutputDeviceDefaultSink>()
|
std::make_unique<SDLAudioOutputDeviceDefaultSink>()
|
||||||
);
|
);
|
||||||
|
|
||||||
asink.emplace<Components::StreamSink>("LoudSpeaker", std::string{entt::type_name<AudioFrame>::value()});
|
asink.emplace<Components::StreamSink>(Components::StreamSink::create<AudioFrame>("LoudSpeaker"));
|
||||||
|
|
||||||
|
os.throwEventConstruct(asink);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
os.registry().destroy(asink);
|
os.registry().destroy(asink);
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,26 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class StreamManager;
|
||||||
|
|
||||||
namespace Components {
|
namespace Components {
|
||||||
struct StreamSource {
|
struct StreamSource {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string frame_type_name;
|
std::string frame_type_name;
|
||||||
// TODO: connect fn
|
|
||||||
|
std::function<bool(StreamManager&, Object, Object, bool)> connect_fn;
|
||||||
|
|
||||||
|
template<typename FrameType>
|
||||||
|
static StreamSource create(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StreamSink {
|
struct StreamSink {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string frame_type_name;
|
std::string frame_type_name;
|
||||||
// TODO: connect fn
|
|
||||||
|
template<typename FrameType>
|
||||||
|
static StreamSink create(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FrameType>
|
template<typename FrameType>
|
||||||
@ -102,8 +111,6 @@ class StreamManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: default typed sources and sinks
|
|
||||||
|
|
||||||
// stream type is FrameStream2I<FrameType>
|
// stream type is FrameStream2I<FrameType>
|
||||||
// TODO: improve this design
|
// TODO: improve this design
|
||||||
// src and sink need to be a FrameStream2MultiStream<FrameType>
|
// src and sink need to be a FrameStream2MultiStream<FrameType>
|
||||||
@ -135,14 +142,6 @@ class StreamManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK:
|
|
||||||
if (!h_src.all_of<Components::StreamSource>()) {
|
|
||||||
h_src.emplace<Components::StreamSource>("", std::string{entt::type_name<FrameType>::value()});
|
|
||||||
}
|
|
||||||
if (!h_sink.all_of<Components::StreamSink>()) {
|
|
||||||
h_sink.emplace<Components::StreamSink>("", std::string{entt::type_name<FrameType>::value()});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& src_stream = h_src.get<Components::FrameStream2Source<FrameType>>();
|
auto& src_stream = h_src.get<Components::FrameStream2Source<FrameType>>();
|
||||||
auto& sink_stream = h_sink.get<Components::FrameStream2Sink<FrameType>>();
|
auto& sink_stream = h_sink.get<Components::FrameStream2Sink<FrameType>>();
|
||||||
|
|
||||||
@ -195,6 +194,43 @@ class StreamManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool connect(Object src, Object sink, bool threaded = true) {
|
||||||
|
auto h_src = _os.objectHandle(src);
|
||||||
|
auto h_sink = _os.objectHandle(sink);
|
||||||
|
if (!static_cast<bool>(h_src) || !static_cast<bool>(h_sink)) {
|
||||||
|
// an object does not exist
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get src and sink comps
|
||||||
|
if (!h_src.all_of<Components::StreamSource>()) {
|
||||||
|
// src not stream source
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!h_sink.all_of<Components::StreamSink>()) {
|
||||||
|
// sink not stream sink
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& ssrc = h_src.get<Components::StreamSource>();
|
||||||
|
const auto& ssink = h_sink.get<Components::StreamSink>();
|
||||||
|
|
||||||
|
// compare type
|
||||||
|
if (ssrc.frame_type_name != ssink.frame_type_name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// always fail in debug mode
|
||||||
|
assert(static_cast<bool>(ssrc.connect_fn));
|
||||||
|
if (!static_cast<bool>(ssrc.connect_fn)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use connect fn from src
|
||||||
|
return ssrc.connect_fn(*this, src, sink, threaded);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename StreamType>
|
template<typename StreamType>
|
||||||
bool disconnect(Object src, Object sink) {
|
bool disconnect(Object src, Object sink) {
|
||||||
auto res = std::find_if(
|
auto res = std::find_if(
|
||||||
@ -258,3 +294,27 @@ class StreamManager {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace Components {
|
||||||
|
|
||||||
|
// we require the complete sm type here
|
||||||
|
template<typename FrameType>
|
||||||
|
StreamSource StreamSource::create(const std::string& name) {
|
||||||
|
return StreamSource{
|
||||||
|
name,
|
||||||
|
std::string{entt::type_name<FrameType>::value()},
|
||||||
|
+[](StreamManager& sm, Object src, Object sink, bool threaded) {
|
||||||
|
return sm.connect<FrameType>(src, sink, threaded);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FrameType>
|
||||||
|
StreamSink StreamSink::create(const std::string& name) {
|
||||||
|
return StreamSink{
|
||||||
|
name,
|
||||||
|
std::string{entt::type_name<FrameType>::value()},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Components
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
#include "./stream_manager_ui.hpp"
|
#include "./stream_manager_ui.hpp"
|
||||||
|
|
||||||
#include "./content/sdl_video_frame_stream2.hpp"
|
|
||||||
#include "./content/audio_stream.hpp"
|
|
||||||
|
|
||||||
#include <solanaceae/object_store/object_store.hpp>
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
@ -42,7 +39,7 @@ void StreamManagerUI::render(void) {
|
|||||||
|
|
||||||
// by fametype ??
|
// by fametype ??
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader("Sources")) {
|
if (ImGui::CollapsingHeader("Sources", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
// list sources
|
// list sources
|
||||||
if (ImGui::BeginTable("sources_and_sinks", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersInnerV)) {
|
if (ImGui::BeginTable("sources_and_sinks", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersInnerV)) {
|
||||||
ImGui::TableSetupColumn("id");
|
ImGui::TableSetupColumn("id");
|
||||||
@ -65,7 +62,34 @@ void StreamManagerUI::render(void) {
|
|||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (ImGui::SmallButton("->")) {
|
if (ImGui::SmallButton("->")) {
|
||||||
// TODO: list type sinks
|
ImGui::OpenPopup("src_connect");
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("src_connect")) {
|
||||||
|
if (ImGui::BeginMenu("connect to")) {
|
||||||
|
for (const auto& [oc_sink, s_sink] : _os.registry().view<Components::StreamSink>().each()) {
|
||||||
|
if (s_sink.frame_type_name != ss.frame_type_name) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushID(entt::to_integral(oc_sink));
|
||||||
|
|
||||||
|
std::string sink_label {"src "};
|
||||||
|
sink_label += std::to_string(entt::to_integral(entt::to_entity(oc_sink)));
|
||||||
|
sink_label += " (";
|
||||||
|
sink_label += s_sink.name;
|
||||||
|
sink_label += ")[";
|
||||||
|
sink_label += s_sink.frame_type_name;
|
||||||
|
sink_label += "]";
|
||||||
|
if (ImGui::MenuItem(sink_label.c_str())) {
|
||||||
|
_sm.connect(oc, oc_sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
@ -78,7 +102,7 @@ void StreamManagerUI::render(void) {
|
|||||||
}
|
}
|
||||||
} // sources header
|
} // sources header
|
||||||
|
|
||||||
if (ImGui::CollapsingHeader("Sinks")) {
|
if (ImGui::CollapsingHeader("Sinks", ImGuiTreeNodeFlags_DefaultOpen)) {
|
||||||
// list sinks
|
// list sinks
|
||||||
if (ImGui::BeginTable("sources_and_sinks", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersInnerV)) {
|
if (ImGui::BeginTable("sources_and_sinks", 4, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersInnerV)) {
|
||||||
ImGui::TableSetupColumn("id");
|
ImGui::TableSetupColumn("id");
|
||||||
@ -89,8 +113,6 @@ void StreamManagerUI::render(void) {
|
|||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
for (const auto& [oc, ss] : _os.registry().view<Components::StreamSink>().each()) {
|
for (const auto& [oc, ss] : _os.registry().view<Components::StreamSink>().each()) {
|
||||||
//ImGui::Text("sink %d (%s)[%s]", entt::to_integral(entt::to_entity(oc)), ss.name.c_str(), ss.frame_type_name.c_str());
|
|
||||||
|
|
||||||
ImGui::PushID(entt::to_integral(oc));
|
ImGui::PushID(entt::to_integral(oc));
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
@ -102,10 +124,11 @@ void StreamManagerUI::render(void) {
|
|||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (ImGui::SmallButton("->")) {
|
if (ImGui::SmallButton("->")) {
|
||||||
// TODO: list type sinks
|
ImGui::OpenPopup("sink_connect");
|
||||||
}
|
}
|
||||||
if (ImGui::BeginPopupContextItem("sink_connect")) {
|
// ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings
|
||||||
if (ImGui::BeginMenu("connect video", ss.frame_type_name == entt::type_name<SDLVideoFrame>::value())) {
|
if (ImGui::BeginPopup("sink_connect")) {
|
||||||
|
if (ImGui::BeginMenu("connect to")) {
|
||||||
for (const auto& [oc_src, s_src] : _os.registry().view<Components::StreamSource>().each()) {
|
for (const auto& [oc_src, s_src] : _os.registry().view<Components::StreamSource>().each()) {
|
||||||
if (s_src.frame_type_name != ss.frame_type_name) {
|
if (s_src.frame_type_name != ss.frame_type_name) {
|
||||||
continue;
|
continue;
|
||||||
@ -121,32 +144,7 @@ void StreamManagerUI::render(void) {
|
|||||||
source_label += s_src.frame_type_name;
|
source_label += s_src.frame_type_name;
|
||||||
source_label += "]";
|
source_label += "]";
|
||||||
if (ImGui::MenuItem(source_label.c_str())) {
|
if (ImGui::MenuItem(source_label.c_str())) {
|
||||||
_sm.connect<SDLVideoFrame>(oc_src, oc);
|
_sm.connect(oc_src, oc);
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::PopID();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::BeginMenu("connect audio", ss.frame_type_name == entt::type_name<AudioFrame>::value())) {
|
|
||||||
for (const auto& [oc_src, s_src] : _os.registry().view<Components::StreamSource>().each()) {
|
|
||||||
if (s_src.frame_type_name != ss.frame_type_name) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::PushID(entt::to_integral(oc_src));
|
|
||||||
|
|
||||||
std::string source_label {"src "};
|
|
||||||
source_label += std::to_string(entt::to_integral(entt::to_entity(oc_src)));
|
|
||||||
source_label += " (";
|
|
||||||
source_label += s_src.name;
|
|
||||||
source_label += ")[";
|
|
||||||
source_label += s_src.frame_type_name;
|
|
||||||
source_label += "]";
|
|
||||||
if (ImGui::MenuItem(source_label.c_str())) {
|
|
||||||
_sm.connect<AudioFrame>(oc_src, oc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
Loading…
Reference in New Issue
Block a user