forked from Green-Sky/tomato
avatar sending, uses self in avatar dir
also fix cwd in file selector
This commit is contained in:
parent
99a92c0f04
commit
3a929569ee
@ -69,6 +69,8 @@ target_sources(tomato PUBLIC
|
|||||||
|
|
||||||
./tox_avatar_manager.hpp
|
./tox_avatar_manager.hpp
|
||||||
./tox_avatar_manager.cpp
|
./tox_avatar_manager.cpp
|
||||||
|
./tox_avatar_sender.hpp
|
||||||
|
./tox_avatar_sender.cpp
|
||||||
|
|
||||||
./media_meta_info_loader.hpp
|
./media_meta_info_loader.hpp
|
||||||
./media_meta_info_loader.cpp
|
./media_meta_info_loader.cpp
|
||||||
|
@ -16,7 +16,7 @@ void FileSelector::reset(void) {
|
|||||||
|
|
||||||
FileSelector::FileSelector(void) {
|
FileSelector::FileSelector(void) {
|
||||||
try {
|
try {
|
||||||
_current_file_path = std::filesystem::current_path();
|
_current_file_path = std::filesystem::current_path() / "";
|
||||||
} catch (std::filesystem::filesystem_error const& ex) {
|
} catch (std::filesystem::filesystem_error const& ex) {
|
||||||
std::cerr << "FS: exception creating _current_file_path: " << ex.what() << "\n";
|
std::cerr << "FS: exception creating _current_file_path: " << ex.what() << "\n";
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_,
|
|||||||
#endif
|
#endif
|
||||||
theme(theme_),
|
theme(theme_),
|
||||||
mmil(rmm),
|
mmil(rmm),
|
||||||
tam(os, cs, conf),
|
tam(os, cs, conf, tc),
|
||||||
|
tas(os, cs, rmm),
|
||||||
sdlrtu(renderer_),
|
sdlrtu(renderer_),
|
||||||
tal(cs, os),
|
tal(cs, os),
|
||||||
contact_tc(tal, sdlrtu),
|
contact_tc(tal, sdlrtu),
|
||||||
@ -604,6 +605,7 @@ Screen* MainScreen::tick(float time_delta, bool& quit) {
|
|||||||
const float fo_interval = tffom.tick(time_delta);
|
const float fo_interval = tffom.tick(time_delta);
|
||||||
|
|
||||||
tam.iterate(); // compute
|
tam.iterate(); // compute
|
||||||
|
tas.iterate(time_delta);
|
||||||
|
|
||||||
const float pm_interval = pm.tick(time_delta); // compute
|
const float pm_interval = pm.tick(time_delta); // compute
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "./media_meta_info_loader.hpp"
|
#include "./media_meta_info_loader.hpp"
|
||||||
#include "./tox_avatar_manager.hpp"
|
#include "./tox_avatar_manager.hpp"
|
||||||
|
#include "./tox_avatar_sender.hpp"
|
||||||
|
|
||||||
#include "./sdlrenderer_texture_uploader.hpp"
|
#include "./sdlrenderer_texture_uploader.hpp"
|
||||||
#include "./texture_cache.hpp"
|
#include "./texture_cache.hpp"
|
||||||
@ -88,6 +89,7 @@ struct MainScreen final : public Screen {
|
|||||||
|
|
||||||
MediaMetaInfoLoader mmil;
|
MediaMetaInfoLoader mmil;
|
||||||
ToxAvatarManager tam;
|
ToxAvatarManager tam;
|
||||||
|
ToxAvatarSender tas;
|
||||||
|
|
||||||
SDLRendererTextureUploader sdlrtu;
|
SDLRendererTextureUploader sdlrtu;
|
||||||
//OpenGLTextureUploader ogltu;
|
//OpenGLTextureUploader ogltu;
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <solanaceae/tox_contacts/components.hpp>
|
#include <solanaceae/tox_contacts/components.hpp>
|
||||||
|
|
||||||
#include <solanaceae/util/utils.hpp>
|
#include <solanaceae/util/utils.hpp>
|
||||||
|
#include <solanaceae/file/file2.hpp>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
@ -33,8 +34,9 @@ namespace Components {
|
|||||||
ToxAvatarManager::ToxAvatarManager(
|
ToxAvatarManager::ToxAvatarManager(
|
||||||
ObjectStore2& os,
|
ObjectStore2& os,
|
||||||
ContactStore4I& cs,
|
ContactStore4I& cs,
|
||||||
ConfigModelI& conf
|
ConfigModelI& conf,
|
||||||
) : _os(os), _os_sr(_os.newSubRef(this)), _cs(cs), _conf(conf), _sb_tcs(os) {
|
ToxI& t
|
||||||
|
) : _os(os), _os_sr(_os.newSubRef(this)), _cs(cs), _conf(conf), _t(t), _sb_tcs(os) {
|
||||||
_os_sr
|
_os_sr
|
||||||
.subscribe(ObjectStore_Event::object_construct)
|
.subscribe(ObjectStore_Event::object_construct)
|
||||||
.subscribe(ObjectStore_Event::object_update)
|
.subscribe(ObjectStore_Event::object_update)
|
||||||
@ -126,6 +128,20 @@ void ToxAvatarManager::addAvatarFileToContact(const Contact4 c, const ToxKey& ke
|
|||||||
std::filesystem::file_size(file_path)
|
std::filesystem::file_size(file_path)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{ // toxhash for tox file id, so the remote can optimize cached files
|
||||||
|
auto file = o.get<ObjComp::Ephemeral::BackendFile2>().ptr->file2(o, StorageBackendIFile2::FILE2_READ);
|
||||||
|
if (file) {
|
||||||
|
auto file_buf = file->read(o.get<ObjComp::F::SingleInfo>().file_size);
|
||||||
|
// HACK: tox interface needs bytespan
|
||||||
|
if (file_buf.isOwning()) {
|
||||||
|
o.emplace_or_replace<ObjComp::Tox::FileID>(_t.toxHash(file_buf._data_owner));
|
||||||
|
} else {
|
||||||
|
// TODO: tox bytespan !!
|
||||||
|
o.emplace_or_replace<ObjComp::Tox::FileID>(_t.toxHash(std::vector<uint8_t>(file_buf.cbegin(), file_buf.cend())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_os.throwEventConstruct(o);
|
_os.throwEventConstruct(o);
|
||||||
|
|
||||||
// avatar file "png" exists
|
// avatar file "png" exists
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <solanaceae/object_store/object_store.hpp>
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
#include <solanaceae/contact/fwd.hpp>
|
#include <solanaceae/contact/fwd.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_interface.hpp>
|
||||||
|
|
||||||
#include "./backends/std_fs.hpp"
|
#include "./backends/std_fs.hpp"
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ class ToxAvatarManager : public ObjectStoreEventI {
|
|||||||
ObjectStore2::SubscriptionReference _os_sr;
|
ObjectStore2::SubscriptionReference _os_sr;
|
||||||
ContactStore4I& _cs;
|
ContactStore4I& _cs;
|
||||||
ConfigModelI& _conf;
|
ConfigModelI& _conf;
|
||||||
|
ToxI& _t;
|
||||||
|
|
||||||
Backends::STDFS _sb_tcs;
|
Backends::STDFS _sb_tcs;
|
||||||
|
|
||||||
@ -32,7 +34,8 @@ class ToxAvatarManager : public ObjectStoreEventI {
|
|||||||
ToxAvatarManager(
|
ToxAvatarManager(
|
||||||
ObjectStore2& os,
|
ObjectStore2& os,
|
||||||
ContactStore4I& cs,
|
ContactStore4I& cs,
|
||||||
ConfigModelI& conf
|
ConfigModelI& conf,
|
||||||
|
ToxI& t
|
||||||
);
|
);
|
||||||
|
|
||||||
void iterate(void);
|
void iterate(void);
|
||||||
|
215
src/tox_avatar_sender.cpp
Normal file
215
src/tox_avatar_sender.cpp
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
#include "./tox_avatar_sender.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
#include <solanaceae/contact/contact_store_events.hpp>
|
||||||
|
#include <solanaceae/tox_contacts/components.hpp>
|
||||||
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
|
#include <solanaceae/object_store/meta_components.hpp>
|
||||||
|
#include <solanaceae/object_store/meta_components_file.hpp>
|
||||||
|
#include <solanaceae/tox_messages/obj_components.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace Components {
|
||||||
|
struct TagAvatarOffered {};
|
||||||
|
} // Components
|
||||||
|
|
||||||
|
bool ToxAvatarSender::checkContact(ContactHandle4 c) {
|
||||||
|
// check if tox friend and not sent
|
||||||
|
if (!c.all_of<
|
||||||
|
Contact::Components::ToxFriendEphemeral,
|
||||||
|
Contact::Components::ConnectionState
|
||||||
|
>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (c.any_of<Components::TagAvatarOffered>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is (not) self
|
||||||
|
if (c.all_of<Contact::Components::TagSelfStrong>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c.all_of<Contact::Components::Self>()) {
|
||||||
|
std::cout << "TAS warning: contact has no self\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto self_c = _cs.contactHandle(c.get<Contact::Components::Self>().self);
|
||||||
|
if (!static_cast<bool>(self_c)) {
|
||||||
|
std::cerr << "TAS error: invalid self\n";
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// self has avatar (obj)
|
||||||
|
if (!self_c.all_of<Contact::Components::AvatarObj>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxAvatarSender::inQueue(ContactHandle4 c) const {
|
||||||
|
return std::find_if(_queue.cbegin(), _queue.cend(), [&c](const Entry& e) { return e.c == c; }) != _queue.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxAvatarSender::addToQueue(ContactHandle4 c) {
|
||||||
|
assert(!inQueue(c));
|
||||||
|
_queue.push_back({
|
||||||
|
c,
|
||||||
|
c.get<Contact::Components::ConnectionState>().state
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxAvatarSender::sendAvatar(ContactHandle4 c) {
|
||||||
|
std::cout << "TAS: sending self avatar to " << entt::to_integral(c.entity()) << "\n";
|
||||||
|
|
||||||
|
if (!c.all_of<Contact::Components::Self>()) {
|
||||||
|
std::cout << "TAS warning: contact has no self\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto self_c = _cs.contactHandle(c.get<Contact::Components::Self>().self);
|
||||||
|
if (!static_cast<bool>(self_c)) {
|
||||||
|
std::cerr << "TAS error: invalid self\n";
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self_c.all_of<Contact::Components::AvatarObj>()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ao = self_c.get<Contact::Components::AvatarObj>().obj;
|
||||||
|
|
||||||
|
// .... ?
|
||||||
|
// duplicate object?
|
||||||
|
// a single object can only ever be one transfer (meh)
|
||||||
|
// TODO: make object multi transfer-able (enforce)
|
||||||
|
auto self_o = _os.objectHandle(ao);
|
||||||
|
if (!static_cast<bool>(self_o)) {
|
||||||
|
std::cerr << "TAS error: self avatar obj not real?\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// TODO: move to tox avatar specific backend
|
||||||
|
// HACK: manual clone
|
||||||
|
// using self_o meta backend newObject() should emplace the file backend too
|
||||||
|
auto new_o = self_o.get<ObjComp::Ephemeral::BackendMeta>().ptr->newObject(ByteSpan{}, false);
|
||||||
|
assert(new_o);
|
||||||
|
|
||||||
|
if (self_o.all_of<ObjComp::ID>()) {
|
||||||
|
new_o.emplace_or_replace<ObjComp::ID>(self_o.get<ObjComp::ID>());
|
||||||
|
}
|
||||||
|
if (self_o.all_of<ObjComp::F::SingleInfo>()) {
|
||||||
|
new_o.emplace_or_replace<ObjComp::F::SingleInfo>(self_o.get<ObjComp::F::SingleInfo>());
|
||||||
|
}
|
||||||
|
if (self_o.all_of<ObjComp::F::SingleInfoLocal>()) {
|
||||||
|
new_o.emplace_or_replace<ObjComp::F::SingleInfoLocal>(self_o.get<ObjComp::F::SingleInfoLocal>());
|
||||||
|
}
|
||||||
|
if (self_o.all_of<ObjComp::F::TagLocalHaveAll>()) {
|
||||||
|
new_o.emplace_or_replace<ObjComp::F::TagLocalHaveAll>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// tox avatar
|
||||||
|
new_o.emplace_or_replace<ObjComp::Tox::FileKind>(uint64_t(1));
|
||||||
|
|
||||||
|
_os.throwEventConstruct(new_o); // ?
|
||||||
|
|
||||||
|
if (!_rmm.sendFileObj(c, new_o)) {
|
||||||
|
std::cerr << "TAS error: failed to send avatar file obj\n";
|
||||||
|
_os.throwEventDestroy(new_o);
|
||||||
|
new_o.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
c.emplace_or_replace<Components::TagAvatarOffered>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ToxAvatarSender::ToxAvatarSender(ObjectStore2& os, ContactStore4I& cs, RegistryMessageModelI& rmm) :
|
||||||
|
_os(os),
|
||||||
|
_cs(cs),
|
||||||
|
_cs_sr(cs.newSubRef(this)),
|
||||||
|
_rmm(rmm),
|
||||||
|
_rmm_sr(_rmm.newSubRef(this))
|
||||||
|
{
|
||||||
|
_cs_sr
|
||||||
|
.subscribe(ContactStore4_Event::contact_construct)
|
||||||
|
.subscribe(ContactStore4_Event::contact_update)
|
||||||
|
.subscribe(ContactStore4_Event::contact_destroy)
|
||||||
|
;
|
||||||
|
|
||||||
|
_rmm_sr
|
||||||
|
.subscribe(RegistryMessageModel_Event::send_file_obj)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxAvatarSender::iterate(float delta) {
|
||||||
|
for (auto it = _queue.begin(); it != _queue.end();) {
|
||||||
|
it->timer -= delta;
|
||||||
|
if (it->timer <= 0.f) {
|
||||||
|
sendAvatar(it->c);
|
||||||
|
it = _queue.erase(it);
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxAvatarSender::onEvent(const ContactStore::Events::Contact4Construct& e) {
|
||||||
|
if (!static_cast<bool>(e.e)) {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkContact(e.e)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.e.get<Contact::Components::ConnectionState>().state == Contact::Components::ConnectionState::disconnected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
addToQueue(e.e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxAvatarSender::onEvent(const ContactStore::Events::Contact4Update& e) {
|
||||||
|
if (!static_cast<bool>(e.e)) {
|
||||||
|
assert(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkContact(e.e)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto it = std::find_if(_queue.begin(), _queue.end(), [c = e.e](const Entry& en) { return en.c == c; });
|
||||||
|
if (it != _queue.end()) {
|
||||||
|
// check if connections state changed and reset timer
|
||||||
|
const auto current_state = e.e.get<Contact::Components::ConnectionState>().state;
|
||||||
|
if (current_state == Contact::Components::ConnectionState::disconnected) {
|
||||||
|
_queue.erase(it);
|
||||||
|
} else if (it->ls != current_state) {
|
||||||
|
// state changed, reset timer
|
||||||
|
it->timer = 21.33f;
|
||||||
|
}
|
||||||
|
} else if (e.e.get<Contact::Components::ConnectionState>().state != Contact::Components::ConnectionState::disconnected) {
|
||||||
|
addToQueue(e.e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxAvatarSender::onEvent(const ContactStore::Events::Contact4Destory& e) {
|
||||||
|
// remove from queue
|
||||||
|
// queue is assumed to be short
|
||||||
|
auto it = std::find_if(_queue.begin(), _queue.end(), [c = e.e](const Entry& en) { return en.c == c; });
|
||||||
|
if (it != _queue.end()) {
|
||||||
|
_queue.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
51
src/tox_avatar_sender.hpp
Normal file
51
src/tox_avatar_sender.hpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "solanaceae/contact/fwd.hpp"
|
||||||
|
#include <solanaceae/object_store/fwd.hpp>
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
|
||||||
|
#include <entt/entity/registry.hpp>
|
||||||
|
#include <entt/entity/handle.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
class ToxAvatarSender : public ContactStore4EventI, public RegistryMessageModelEventI {
|
||||||
|
ObjectStore2& _os;
|
||||||
|
ContactStore4I& _cs;
|
||||||
|
ContactStore4I::SubscriptionReference _cs_sr;
|
||||||
|
RegistryMessageModelI& _rmm;
|
||||||
|
RegistryMessageModelI::SubscriptionReference _rmm_sr;
|
||||||
|
|
||||||
|
struct Entry {
|
||||||
|
ContactHandle4 c;
|
||||||
|
Contact::Components::ConnectionState::State ls;
|
||||||
|
float timer {23.122f};
|
||||||
|
};
|
||||||
|
std::vector<Entry> _queue;
|
||||||
|
|
||||||
|
bool checkContact(ContactHandle4 c);
|
||||||
|
bool inQueue(ContactHandle4 c) const;
|
||||||
|
void addToQueue(ContactHandle4 c);
|
||||||
|
|
||||||
|
void sendAvatar(ContactHandle4 c);
|
||||||
|
|
||||||
|
public:
|
||||||
|
ToxAvatarSender(
|
||||||
|
ObjectStore2& os,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
);
|
||||||
|
|
||||||
|
void iterate(float delta);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool onEvent(const ContactStore::Events::Contact4Construct&) override;
|
||||||
|
bool onEvent(const ContactStore::Events::Contact4Update&) override;
|
||||||
|
bool onEvent(const ContactStore::Events::Contact4Destory&) override;
|
||||||
|
};
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user