refactor file from messages to objects (#27)

* part 1 move files from messages to objects tomato - did not touch chat_gui yet, but image loaders and other stuff
* part 1.1
* part 2, mostly chatgui - also ngcft1 behind the scenes
* part 3 - port over rest, except for avatar_manager, which is effectivly disabled
* fix surface missused causing bmp loader to crash
* fixing small issues and small forward refactor
This commit is contained in:
Erik Scholz
2024-07-31 18:10:52 +02:00
committed by GitHub
parent f27d178b78
commit 2abf09ac06
17 changed files with 621 additions and 348 deletions

View File

@@ -8,10 +8,15 @@
#include <solanaceae/message3/components.hpp>
#include "./os_comps.hpp"
#include <solanaceae/object_store/object_store.hpp>
#include <solanaceae/file/file2.hpp>
#include <entt/entity/entity.hpp>
#include <iostream>
#include <fstream>
#include <cassert>
#include <vector>
// fwd
namespace Message {
@@ -34,51 +39,88 @@ std::optional<TextureEntry> MessageImageLoader::load(TextureUploaderI& tu, Messa
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();
if (!m.all_of<Message::Components::MessageFileObject>()) {
// not a file message
return std::nullopt;
}
const auto& o = m.get<Message::Components::MessageFileObject>().o;
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 = Message::getTimeMS();
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;
}
}
if (!static_cast<bool>(o)) {
std::cerr << "MIL error: invalid object in file message\n";
return std::nullopt;
}
std::cerr << "MIL: failed to load message\n";
if (!o.all_of<ObjComp::Ephemeral::Backend, ObjComp::F::SingleInfo>()) {
std::cerr << "MIL error: object missing backend (?)\n";
return std::nullopt;
}
// TODO: handle collections
const auto file_size = o.get<ObjComp::F::SingleInfo>().file_size;
if (file_size > 50*1024*1024) {
std::cerr << "MIL error: image file too large\n";
return std::nullopt;
}
if (file_size == 0) {
std::cerr << "MIL warning: empty file\n";
return std::nullopt;
}
if (!o.all_of<ObjComp::F::TagLocalHaveAll>()) {
// not ready yet
return std::nullopt;
}
auto* file_backend = o.get<ObjComp::Ephemeral::Backend>().ptr;
if (file_backend == nullptr) {
std::cerr << "MIL error: object backend nullptr\n";
return std::nullopt;
}
auto file2 = file_backend->file2(o, StorageBackendI::FILE2_READ);
if (!file2 || !file2->isGood() || !file2->can_read) {
std::cerr << "MIL error: creating file2 from object via backendI\n";
return std::nullopt;
}
auto read_data = file2->read(file_size, 0);
if (read_data.ptr == nullptr) {
std::cerr << "MMIL error: reading from file2 returned nullptr\n";
return std::nullopt;
}
if (read_data.size != file_size) {
std::cerr << "MIL error: reading from file2 size missmatch, should be " << file_size << ", is " << read_data.size << "\n";
return std::nullopt;
}
// try all loaders after another
for (auto& il : _image_loaders) {
auto res = il->loadFromMemoryRGBA(read_data.ptr, read_data.size);
if (res.frames.empty() || res.height == 0 || res.width == 0) {
continue;
}
TextureEntry new_entry;
new_entry.timestamp_last_rendered = Message::getTimeMS();
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 o:" << /*file_path*/ entt::to_integral(o.entity()) << "\n";
return new_entry;
}
std::cerr << "MIL error: failed to load message (unhandled format)\n";
return std::nullopt;
}