message texture cache + message image loader (no inline images yet)
This commit is contained in:
		| @@ -31,6 +31,8 @@ add_executable(tomato | ||||
| 	./texture_cache.cpp | ||||
| 	./tox_avatar_loader.hpp | ||||
| 	./tox_avatar_loader.cpp | ||||
| 	./message_image_loader.hpp | ||||
| 	./message_image_loader.cpp | ||||
| 	./sdl_clipboard_utils.hpp | ||||
| 	./sdl_clipboard_utils.cpp | ||||
| 	./file_selector.hpp | ||||
|   | ||||
| @@ -27,7 +27,7 @@ ChatGui4::ChatGui4( | ||||
| 	RegistryMessageModel& rmm, | ||||
| 	Contact3Registry& cr, | ||||
| 	TextureUploaderI& tu | ||||
| ) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu) { | ||||
| ) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu) { | ||||
| } | ||||
|  | ||||
| void ChatGui4::render(void) { | ||||
|   | ||||
| @@ -6,6 +6,7 @@ | ||||
| #include "./texture_uploader.hpp" | ||||
| #include "./texture_cache.hpp" | ||||
| #include "./tox_avatar_loader.hpp" | ||||
| #include "./message_image_loader.hpp" | ||||
| #include "./file_selector.hpp" | ||||
|  | ||||
| #include <vector> | ||||
| @@ -18,7 +19,8 @@ class ChatGui4 { | ||||
|  | ||||
| 	ToxAvatarLoader _tal; | ||||
| 	TextureCache<void*, Contact3, ToxAvatarLoader> _contact_tc; | ||||
| 	//TextureCache<Message3Handle> _msg_tc; | ||||
| 	MessageImageLoader _mil; | ||||
| 	TextureCache<void*, Message3Handle, MessageImageLoader> _msg_tc; | ||||
|  | ||||
| 	FileSelector _fss; | ||||
|  | ||||
|   | ||||
							
								
								
									
										70
									
								
								src/message_image_loader.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/message_image_loader.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| #include "./message_image_loader.hpp" | ||||
|  | ||||
| #include "./image_loader_sdl_bmp.hpp" | ||||
| #include "./image_loader_stb.hpp" | ||||
| #include "./image_loader_webp.hpp" | ||||
|  | ||||
| #include <solanaceae/message3/components.hpp> | ||||
|  | ||||
| #include <iostream> | ||||
| #include <fstream> | ||||
| #include <cassert> | ||||
| #include <vector> | ||||
|  | ||||
| MessageImageLoader::MessageImageLoader(void) { | ||||
| 	_image_loaders.push_back(std::make_unique<ImageLoaderSDLBMP>()); | ||||
| 	_image_loaders.push_back(std::make_unique<ImageLoaderWebP>()); | ||||
| 	_image_loaders.push_back(std::make_unique<ImageLoaderSTB>()); | ||||
| } | ||||
|  | ||||
| std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Message3Handle m) { | ||||
| 	if (!static_cast<bool>(m)) { | ||||
| 		return std::nullopt; | ||||
| 	} | ||||
|  | ||||
| 	if (m.all_of<Message::Components::Transfer::FileInfoLocal>()) { | ||||
| 		const auto& file_list = m.get<Message::Components::Transfer::FileInfoLocal>().file_list; | ||||
| 		assert(!file_list.empty()); | ||||
| 		const auto& file_path = file_list.front(); | ||||
|  | ||||
| 		std::ifstream file(file_path, std::ios::binary); | ||||
| 		if (file.is_open()) { | ||||
| 			std::vector<uint8_t> tmp_buffer; | ||||
| 			while (file.good()) { | ||||
| 				auto ch = file.get(); | ||||
| 				if (ch == EOF) { | ||||
| 					break; | ||||
| 				} else { | ||||
| 					tmp_buffer.push_back(ch); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			// try all loaders after another | ||||
| 			for (auto& il : _image_loaders) { | ||||
| 				auto res = il->loadFromMemoryRGBA(tmp_buffer.data(), tmp_buffer.size()); | ||||
| 				if (res.frames.empty() || res.height == 0 || res.width == 0) { | ||||
| 					continue; | ||||
| 				} | ||||
|  | ||||
| 				TextureEntry new_entry; | ||||
| 				new_entry.timestamp_last_rendered = getNowMS(); | ||||
| 				new_entry.current_texture = 0; | ||||
| 				for (const auto& [ms, data] : res.frames) { | ||||
| 					const auto n_t = tu.uploadRGBA(data.data(), res.width, res.height); | ||||
| 					new_entry.textures.push_back(n_t); | ||||
| 					new_entry.frame_duration.push_back(ms); | ||||
| 				} | ||||
|  | ||||
| 				new_entry.width = res.width; | ||||
| 				new_entry.height = res.height; | ||||
|  | ||||
| 				std::cout << "MIL: loaded image file " << file_path << "\n"; | ||||
|  | ||||
| 				return new_entry; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return std::nullopt; | ||||
| } | ||||
|  | ||||
							
								
								
									
										27
									
								
								src/message_image_loader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/message_image_loader.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <solanaceae/message3/registry_message_model.hpp> | ||||
|  | ||||
| #include "./image_loader.hpp" | ||||
| #include "./texture_cache.hpp" | ||||
|  | ||||
| #include <optional> | ||||
|  | ||||
| class MessageImageLoader { | ||||
| 	std::vector<std::unique_ptr<ImageLoaderI>> _image_loaders; | ||||
|  | ||||
| 	public: | ||||
| 		MessageImageLoader(void); | ||||
| 		std::optional<TextureEntry> load(TextureUploaderI& tu, Message3Handle c); | ||||
| }; | ||||
|  | ||||
| // TODO: move to rmm | ||||
| template<> | ||||
| struct std::hash<Message3Handle> { | ||||
| 	std::size_t operator()(Message3Handle const& m) const noexcept { | ||||
| 		const std::size_t h1 = reinterpret_cast<std::size_t>(m.registry()); | ||||
| 		const std::size_t h2 = entt::to_integral(m.entity()); | ||||
| 		return (h1 << 3) ^ (h2 * 11400714819323198485llu); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user