forked from Green-Sky/tomato
		
	implement stream default src/sink
This commit is contained in:
		@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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 (...) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user