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) { | StreamManager::~StreamManager(void) { | ||||||
| 	// stop all connetions | 	// stop all connetions | ||||||
| @@ -137,3 +141,66 @@ float StreamManager::tick(float) { | |||||||
| 	return 2.f; // TODO: 2sec makes mainthread connections unusable | 	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 "./frame_stream2.hpp" | ||||||
|  |  | ||||||
|  | #include <unordered_map> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
| @@ -18,6 +19,14 @@ | |||||||
| class StreamManager; | class StreamManager; | ||||||
|  |  | ||||||
| namespace Components { | 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 { | 	struct StreamSource { | ||||||
| 		std::string name; | 		std::string name; | ||||||
| 		std::string frame_type_name; | 		std::string frame_type_name; | ||||||
| @@ -45,7 +54,7 @@ namespace Components { | |||||||
| } // Components | } // Components | ||||||
|  |  | ||||||
|  |  | ||||||
| class StreamManager { | class StreamManager : protected ObjectStoreEventI { | ||||||
| 	friend class StreamManagerUI; // TODO: make this go away | 	friend class StreamManagerUI; // TODO: make this go away | ||||||
| 	ObjectStore2& _os; | 	ObjectStore2& _os; | ||||||
|  |  | ||||||
| @@ -82,6 +91,9 @@ class StreamManager { | |||||||
| 	}; | 	}; | ||||||
| 	std::vector<std::unique_ptr<Connection>> _connections; | 	std::vector<std::unique_ptr<Connection>> _connections; | ||||||
|  |  | ||||||
|  | 	std::unordered_map<std::string, Object> _default_sources; | ||||||
|  | 	std::unordered_map<std::string, Object> _default_sinks; | ||||||
|  |  | ||||||
| 	public: | 	public: | ||||||
| 		StreamManager(ObjectStore2& os); | 		StreamManager(ObjectStore2& os); | ||||||
| 		virtual ~StreamManager(void); | 		virtual ~StreamManager(void); | ||||||
| @@ -95,6 +107,11 @@ class StreamManager { | |||||||
|  |  | ||||||
| 		// do we need the time delta? | 		// do we need the time delta? | ||||||
| 		float tick(float); | 		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 | // 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::StreamSource>(Components::StreamSource::create<AudioFrame2>("SDL Audio Default Recording Device")); | ||||||
|  | 				asrc.emplace<Components::TagDefaultTarget>(); | ||||||
|  |  | ||||||
| 				os.throwEventConstruct(asrc); | 				os.throwEventConstruct(asrc); | ||||||
| 			} catch (...) { | 			} 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::StreamSink>(Components::StreamSink::create<AudioFrame2>("SDL Audio Default Playback Device")); | ||||||
|  | 				asink.emplace<Components::TagDefaultTarget>(); | ||||||
|  |  | ||||||
| 				os.throwEventConstruct(asink); | 				os.throwEventConstruct(asink); | ||||||
| 			} catch (...) { | 			} catch (...) { | ||||||
|   | |||||||
| @@ -56,6 +56,12 @@ void StreamManagerUI::render(void) { | |||||||
| 					ImGui::TableNextColumn(); | 					ImGui::TableNextColumn(); | ||||||
| 					ImGui::Text("%d", entt::to_integral(entt::to_entity(oc))); | 					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); | 					const auto *ssrc = _os.registry().try_get<Components::StreamSource>(oc); | ||||||
| 					ImGui::TableNextColumn(); | 					ImGui::TableNextColumn(); | ||||||
| 					ImGui::TextUnformatted(ssrc!=nullptr?ssrc->name.c_str():"none"); | 					ImGui::TextUnformatted(ssrc!=nullptr?ssrc->name.c_str():"none"); | ||||||
| @@ -118,6 +124,12 @@ void StreamManagerUI::render(void) { | |||||||
| 					ImGui::TableNextColumn(); | 					ImGui::TableNextColumn(); | ||||||
| 					ImGui::Text("%d", entt::to_integral(entt::to_entity(oc))); | 					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); | 					const auto *ssink = _os.registry().try_get<Components::StreamSink>(oc); | ||||||
| 					ImGui::TableNextColumn(); | 					ImGui::TableNextColumn(); | ||||||
| 					ImGui::TextUnformatted(ssink!=nullptr?ssink->name.c_str():"none"); | 					ImGui::TextUnformatted(ssink!=nullptr?ssink->name.c_str():"none"); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user