implement stream default src/sink

This commit is contained in:
Green Sky 2024-09-28 19:16:57 +02:00
parent 248b00dafb
commit 3d8deb310e
No known key found for this signature in database
4 changed files with 100 additions and 2 deletions

View File

@ -27,7 +27,11 @@ StreamManager::Connection::Connection(
}
}
StreamManager::StreamManager(ObjectStore2& os) : _os(os) {}
StreamManager::StreamManager(ObjectStore2& os) : _os(os) {
_os.subscribe(this, ObjectStore_Event::object_construct);
//_os.subscribe(this, ObjectStore_Event::object_update);
_os.subscribe(this, ObjectStore_Event::object_destroy);
}
StreamManager::~StreamManager(void) {
// stop all connetions
@ -137,3 +141,66 @@ float StreamManager::tick(float) {
return 2.f; // TODO: 2sec makes mainthread connections unusable
}
bool StreamManager::onEvent(const ObjectStore::Events::ObjectConstruct& e) {
if (!e.e.any_of<Components::StreamSink, Components::StreamSource>()) {
return false;
}
// update default targets
if (e.e.all_of<Components::TagDefaultTarget>()) {
if (e.e.all_of<Components::StreamSource>()) {
_default_sources[e.e.get<Components::StreamSource>().frame_type_name] = e.e;
} else { // sink
_default_sinks[e.e.get<Components::StreamSink>().frame_type_name] = e.e;
}
}
// connect to default
// only ever do this on new objects
if (e.e.all_of<Components::TagConnectToDefault>()) {
if (e.e.all_of<Components::StreamSource>()) {
auto it_d_sink = _default_sinks.find(e.e.get<Components::StreamSource>().frame_type_name);
if (it_d_sink != _default_sinks.cend()) {
// TODO: threaded
connect(e.e, it_d_sink->second);
}
} else { // sink
auto it_d_src = _default_sources.find(e.e.get<Components::StreamSink>().frame_type_name);
if (it_d_src != _default_sources.cend()) {
// TODO: threaded
connect(e.e, it_d_src->second);
}
}
}
return false;
}
bool StreamManager::onEvent(const ObjectStore::Events::ObjectUpdate&) {
// what do we do here?
return false;
}
bool StreamManager::onEvent(const ObjectStore::Events::ObjectDestory& e) {
// typeless
for (auto it = _default_sources.cbegin(); it != _default_sources.cend();) {
if (it->second == e.e) {
it = _default_sources.erase(it);
} else {
it++;
}
}
for (auto it = _default_sinks.cbegin(); it != _default_sinks.cend();) {
if (it->second == e.e) {
it = _default_sinks.erase(it);
} else {
it++;
}
}
// TODO: destroy connections
// TODO: auto reconnect default following devices if another default exists
return false;
}

View File

@ -7,6 +7,7 @@
#include "./frame_stream2.hpp"
#include <unordered_map>
#include <vector>
#include <memory>
#include <algorithm>
@ -18,6 +19,14 @@
class StreamManager;
namespace Components {
// mark a source or sink as the(a) default
struct TagDefaultTarget {};
// mark a source/sink as to be connected to a default sink/source
// of the same type
struct TagConnectToDefault {};
struct StreamSource {
std::string name;
std::string frame_type_name;
@ -45,7 +54,7 @@ namespace Components {
} // Components
class StreamManager {
class StreamManager : protected ObjectStoreEventI {
friend class StreamManagerUI; // TODO: make this go away
ObjectStore2& _os;
@ -82,6 +91,9 @@ class StreamManager {
};
std::vector<std::unique_ptr<Connection>> _connections;
std::unordered_map<std::string, Object> _default_sources;
std::unordered_map<std::string, Object> _default_sinks;
public:
StreamManager(ObjectStore2& os);
virtual ~StreamManager(void);
@ -95,6 +107,11 @@ class StreamManager {
// do we need the time delta?
float tick(float);
protected:
bool onEvent(const ObjectStore::Events::ObjectConstruct&) override;
bool onEvent(const ObjectStore::Events::ObjectUpdate&) override;
bool onEvent(const ObjectStore::Events::ObjectDestory&) override;
};
// template impls

View File

@ -152,6 +152,7 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
);
asrc.emplace<Components::StreamSource>(Components::StreamSource::create<AudioFrame2>("SDL Audio Default Recording Device"));
asrc.emplace<Components::TagDefaultTarget>();
os.throwEventConstruct(asrc);
} catch (...) {
@ -166,6 +167,7 @@ MainScreen::MainScreen(SimpleConfigModel&& conf_, SDL_Renderer* renderer_, Theme
);
asink.emplace<Components::StreamSink>(Components::StreamSink::create<AudioFrame2>("SDL Audio Default Playback Device"));
asink.emplace<Components::TagDefaultTarget>();
os.throwEventConstruct(asink);
} catch (...) {

View File

@ -56,6 +56,12 @@ void StreamManagerUI::render(void) {
ImGui::TableNextColumn();
ImGui::Text("%d", entt::to_integral(entt::to_entity(oc)));
if (_os.registry().all_of<Components::TagDefaultTarget>(oc)) {
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::GetColorU32(ImVec4{0.6f, 0.f, 0.6f, 0.25f}));
} else if (_os.registry().all_of<Components::TagDefaultTarget>(oc)) {
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::GetColorU32(ImVec4{0.6f, 0.6f, 0.f, 0.25f}));
}
const auto *ssrc = _os.registry().try_get<Components::StreamSource>(oc);
ImGui::TableNextColumn();
ImGui::TextUnformatted(ssrc!=nullptr?ssrc->name.c_str():"none");
@ -118,6 +124,12 @@ void StreamManagerUI::render(void) {
ImGui::TableNextColumn();
ImGui::Text("%d", entt::to_integral(entt::to_entity(oc)));
if (_os.registry().all_of<Components::TagDefaultTarget>(oc)) {
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::GetColorU32(ImVec4{0.6f, 0.f, 0.6f, 0.25f}));
} else if (_os.registry().all_of<Components::TagDefaultTarget>(oc)) {
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, ImGui::GetColorU32(ImVec4{0.6f, 0.6f, 0.f, 0.25f}));
}
const auto *ssink = _os.registry().try_get<Components::StreamSink>(oc);
ImGui::TableNextColumn();
ImGui::TextUnformatted(ssink!=nullptr?ssink->name.c_str():"none");