diff --git a/external/solanaceae_contact b/external/solanaceae_contact index e2917c4..0a03fc4 160000 --- a/external/solanaceae_contact +++ b/external/solanaceae_contact @@ -1 +1 @@ -Subproject commit e2917c497c91f91f8febcd1f43e462fad8359305 +Subproject commit 0a03fc48b62b8e7127ffbf1b7f3ccb98f70b1e90 diff --git a/external/solanaceae_message3 b/external/solanaceae_message3 index e55fb46..2a3828b 160000 --- a/external/solanaceae_message3 +++ b/external/solanaceae_message3 @@ -1 +1 @@ -Subproject commit e55fb46027f16a1bc078f797ae9fcc7609d15659 +Subproject commit 2a3828b30d7ec5fb9e7c8a8a82d1be66e040ea74 diff --git a/external/solanaceae_message_serializer b/external/solanaceae_message_serializer index 491c309..c284e07 160000 --- a/external/solanaceae_message_serializer +++ b/external/solanaceae_message_serializer @@ -1 +1 @@ -Subproject commit 491c30988e572fa172481ea77db300afcf0236ef +Subproject commit c284e0779e69618f0524acba67849801cbb5a5d7 diff --git a/external/solanaceae_object_store b/external/solanaceae_object_store index 0ba56d4..241a0c0 160000 --- a/external/solanaceae_object_store +++ b/external/solanaceae_object_store @@ -1 +1 @@ -Subproject commit 0ba56d428fb5e700a00cf016d368c21143c46857 +Subproject commit 241a0c0906f75555218a04b99259b51b0c0c25a4 diff --git a/external/solanaceae_tox b/external/solanaceae_tox index dd7eb27..24bbf2a 160000 --- a/external/solanaceae_tox +++ b/external/solanaceae_tox @@ -1 +1 @@ -Subproject commit dd7eb2702f3844085f3cd8495db1e1a087afd724 +Subproject commit 24bbf2a3381de3e2a7c06c035eb0b19467c2a6b5 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 39de9fc..fce7be3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -167,6 +167,7 @@ target_compile_features(tomato PUBLIC cxx_std_17) target_link_libraries(tomato PUBLIC solanaceae_util solanaceae_contact + solanaceae_contact_impl solanaceae_message3 solanaceae_message_serializer diff --git a/src/bitset_image_loader.hpp b/src/bitset_image_loader.hpp index 59a1101..348df86 100644 --- a/src/bitset_image_loader.hpp +++ b/src/bitset_image_loader.hpp @@ -1,16 +1,20 @@ #pragma once #include -#include +#include #include #include "./texture_cache.hpp" +#include +#include +#include + #include struct ObjectContactSub final { ObjectHandle o; - Contact3 c{entt::null}; + Contact4 c{entt::null}; }; template<> diff --git a/src/chat_gui/contact_list.cpp b/src/chat_gui/contact_list.cpp index 8640a28..4d06b77 100644 --- a/src/chat_gui/contact_list.cpp +++ b/src/chat_gui/contact_list.cpp @@ -18,7 +18,7 @@ void renderAvatar( const Theme& th, ContactTextureCache& contact_tc, - const Contact3Handle c, + const ContactHandle4 c, ImVec2 box ) { // deploy dummy of same size and check visibility @@ -53,7 +53,7 @@ void renderAvatar( bool renderContactBig( const Theme& th, ContactTextureCache& contact_tc, - const Contact3Handle c, + const ContactHandle4 c, int line_height, const bool unread, const bool selectable, diff --git a/src/chat_gui/contact_list.hpp b/src/chat_gui/contact_list.hpp index 2180f71..3aaf998 100644 --- a/src/chat_gui/contact_list.hpp +++ b/src/chat_gui/contact_list.hpp @@ -4,7 +4,7 @@ #include "./theme.hpp" -#include +#include enum class ThemeCol_Contact { request_incoming, @@ -25,7 +25,7 @@ enum class ThemeCol_Contact { void renderAvatar( const Theme& th, ContactTextureCache& contact_tc, - const Contact3Handle c, + const ContactHandle4 c, ImVec2 box ); @@ -39,7 +39,7 @@ void renderAvatar( bool renderContactBig( const Theme& th, ContactTextureCache& contact_tc, - const Contact3Handle c, + const ContactHandle4 c, int line_height = 3, const bool unread = false, const bool selectable = false, diff --git a/src/chat_gui/texture_cache_defs.hpp b/src/chat_gui/texture_cache_defs.hpp index fc360b3..1e7254c 100644 --- a/src/chat_gui/texture_cache_defs.hpp +++ b/src/chat_gui/texture_cache_defs.hpp @@ -7,7 +7,7 @@ #include "../message_image_loader.hpp" #include "../bitset_image_loader.hpp" -using ContactTextureCache = TextureCache; +using ContactTextureCache = TextureCache; using MessageTextureCache = TextureCache; using BitsetTextureCache = TextureCache; diff --git a/src/chat_gui4.cpp b/src/chat_gui4.cpp index c4e735d..cf71f0c 100644 --- a/src/chat_gui4.cpp +++ b/src/chat_gui4.cpp @@ -1,11 +1,15 @@ #include "./chat_gui4.hpp" +#include + +#include +#include + #include #include #include #include #include -#include #include "./frame_streams/voip_model.hpp" @@ -182,7 +186,7 @@ ChatGui4::ChatGui4( ConfigModelI& conf, ObjectStore2& os, RegistryMessageModelI& rmm, - Contact3Registry& cr, + ContactStore4I& cs, TextureUploaderI& tu, ContactTextureCache& contact_tc, MessageTextureCache& msg_tc, @@ -192,7 +196,7 @@ ChatGui4::ChatGui4( _os(os), _os_sr(_os.newSubRef(this)), _rmm(rmm), - _cr(cr), + _cs(cs), _contact_tc(contact_tc), _msg_tc(msg_tc), _b_tc(_bil, tu), @@ -250,22 +254,23 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused ImGui::SameLine(); if (_selected_contact) { + auto& cr = _cs.registry(); const std::string chat_label = "chat " + std::to_string(entt::to_integral(*_selected_contact)); - const std::vector* sub_contacts = nullptr; - if (_cr.all_of(*_selected_contact)) { - sub_contacts = &_cr.get(*_selected_contact).subs; + const std::vector* sub_contacts = nullptr; + if (cr.all_of(*_selected_contact)) { + sub_contacts = &cr.get(*_selected_contact).subs; } - const bool highlight_private {!_cr.all_of(*_selected_contact)}; + const bool highlight_private {!cr.all_of(*_selected_contact)}; if (ImGui::BeginChild(chat_label.c_str(), {0, 0}, ImGuiChildFlags_Border, ImGuiWindowFlags_MenuBar)) { if (ImGui::BeginMenuBar()) { // check if contact has voip model // use activesessioncomp instead? - if (_cr.all_of(*_selected_contact)) { + if (cr.all_of(*_selected_contact)) { if (ImGui::BeginMenu("VoIP")) { - auto* voip_model = _cr.get(*_selected_contact); + auto* voip_model = cr.get(*_selected_contact); std::vector contact_sessions; std::vector acceptable_sessions; @@ -362,9 +367,9 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused ImGui::SeparatorText("tox"); // TODO: cheese it and rename to copy id? - if (_cr.all_of(*_selected_contact)) { + if (cr.all_of(*_selected_contact)) { if (ImGui::MenuItem("copy ngc chatid")) { - const auto& chat_id = _cr.get(*_selected_contact).chat_id.data; + const auto& chat_id = cr.get(*_selected_contact).chat_id.data; const auto chat_id_str = bin2hex(std::vector{chat_id.begin(), chat_id.end()}); ImGui::SetClipboardText(chat_id_str.c_str()); } @@ -375,10 +380,10 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused ImGui::EndMenuBar(); } - renderContactBig(_theme, _contact_tc, {_cr, *_selected_contact}, 3, false, false, false); + renderContactBig(_theme, _contact_tc, {cr, *_selected_contact}, 3, false, false, false); ImGui::Separator(); - if (sub_contacts != nullptr && !_cr.all_of(*_selected_contact) && _cr.all_of(*_selected_contact)) { + if (sub_contacts != nullptr && !cr.all_of(*_selected_contact) && cr.all_of(*_selected_contact)) { if (!sub_contacts->empty()) { if (ImGui::BeginChild("subcontacts", {TEXT_BASE_WIDTH * 18.f, -100.f}, true)) { ImGui::Text("subs: %zu", sub_contacts->size()); @@ -386,8 +391,8 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused for (const auto& c : *sub_contacts) { // TODO: can a sub be selected? no //if (renderSubContactListContact(c, _selected_contact.has_value() && *_selected_contact == c)) { - if (renderContactBig(_theme, _contact_tc, {_cr, c}, 1)) { - _text_input_buffer.insert(0, (_cr.all_of(c) ? _cr.get(c).name : "") + ": "); + if (renderContactBig(_theme, _contact_tc, {cr, c}, 1)) { + _text_input_buffer.insert(0, (cr.all_of(c) ? cr.get(c).name : "") + ": "); } } } @@ -396,14 +401,14 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused } } - const bool request_incoming = _cr.all_of(*_selected_contact); - const bool request_outgoing = _cr.all_of(*_selected_contact); + const bool request_incoming = cr.all_of(*_selected_contact); + const bool request_outgoing = cr.all_of(*_selected_contact); if (request_incoming || request_outgoing) { // TODO: theming ImGui::PushStyleColor(ImGuiCol_ChildBg, {0.90f, 0.70f, 0.00f, 0.32f}); if (ImGui::BeginChild("request", {0, TEXT_BASE_HEIGHT*6.1f}, true, ImGuiWindowFlags_NoScrollbar)) { if (request_incoming) { - const auto& ri = _cr.get(*_selected_contact); + const auto& ri = cr.get(*_selected_contact); ImGui::TextUnformatted("You got a request to add this contact."); static std::string self_name = _conf.get_string("tox", "name").value_or("default_tomato"); @@ -423,7 +428,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused } if (ImGui::Button("Accept")) { - _cr.get(*_selected_contact)->acceptRequest(*_selected_contact, self_name, password); + cr.get(*_selected_contact)->acceptRequest(*_selected_contact, self_name, password); password.clear(); } ImGui::SameLine(); @@ -540,11 +545,11 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused // name if (ImGui::TableNextColumn()) { const float img_y {TEXT_BASE_HEIGHT - ImGui::GetStyle().FramePadding.y*2}; - renderAvatar(_theme, _contact_tc, {_cr, c_from.c}, {img_y, img_y}); + renderAvatar(_theme, _contact_tc, {cr, c_from.c}, {img_y, img_y}); ImGui::SameLine(0.f, ImGui::GetStyle().ItemSpacing.x*0.5f); - if (_cr.all_of(c_from.c)) { - ImGui::TextUnformatted(_cr.get(c_from.c).name.c_str()); + if (cr.all_of(c_from.c)) { + ImGui::TextUnformatted(cr.get(c_from.c).name.c_str()); } else { ImGui::TextUnformatted(""); } @@ -581,7 +586,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused } // highlight self - if (_cr.any_of(c_from.c)) { + if (cr.any_of(c_from.c)) { ImU32 cell_bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.7f, 0.3f, 0.20f)); ImGui::TableSetBgColor(ImGuiTableBgTarget_CellBg, cell_bg_color); } else { @@ -593,7 +598,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused std::optional row_bg; // private group message - if (highlight_private && _cr.any_of(c_to.c)) { + if (highlight_private && cr.any_of(c_to.c)) { const ImVec4 priv_msg_hi_col = ImVec4(0.5f, 0.2f, 0.5f, 0.35f); ImU32 row_bg_color = ImGui::GetColorU32(priv_msg_hi_col); ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg1, row_bg_color); @@ -652,13 +657,13 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused size_t other_contacts {0}; for (const auto& [c, syned_ts] : list) { - if (_cr.all_of(c)) { + if (cr.all_of(c)) { //synced_by_text += "\n sself(!)"; // makes no sense continue; - } else if (_cr.all_of(c)) { + } else if (cr.all_of(c)) { synced_by_text += "\n wself"; // TODO: add name? } else { - synced_by_text += "\n >" + (_cr.all_of(c) ? _cr.get(c).name : ""); + synced_by_text += "\n >" + (cr.all_of(c) ? cr.get(c).name : ""); } other_contacts += 1; const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1; @@ -694,13 +699,13 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); for (const auto& [c, syned_ts] : list) { - if (_cr.all_of(c)) { + if (cr.all_of(c)) { //synced_by_text += "\n sself(!)"; // makes no sense continue; - } else if (_cr.all_of(c)) { + } else if (cr.all_of(c)) { synced_by_text += "\n wself"; } else { - synced_by_text += "\n >" + (_cr.all_of(c) ? _cr.get(c).name : ""); + synced_by_text += "\n >" + (cr.all_of(c) ? cr.get(c).name : ""); } const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1; synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)"; @@ -786,15 +791,15 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused _rmm.throwEventConstruct(cg_view.end); } // else? we do nothing? } else { - bool begin_created {false}; + bool begincreated {false}; if (!static_cast(cg_view.begin)) { cg_view.begin = {msg_reg, msg_reg.create()}; - begin_created = true; + begincreated = true; } - bool end_created {false}; + bool endcreated {false}; if (!static_cast(cg_view.end)) { cg_view.end = {msg_reg, msg_reg.create()}; - end_created = true; + endcreated = true; } cg_view.begin.emplace_or_replace(cg_view.end); cg_view.end.emplace_or_replace(cg_view.begin); @@ -803,7 +808,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused auto& old_begin_ts = cg_view.begin.get_or_emplace().ts; if (old_begin_ts != message_view_newest.get().ts) { old_begin_ts = message_view_newest.get().ts; - if (begin_created) { + if (begincreated) { std::cout << "CG: created view begin ts with " << old_begin_ts << "\n"; _rmm.throwEventConstruct(cg_view.begin); } else { @@ -817,7 +822,7 @@ float ChatGui4::render(float time_delta, bool window_hidden, bool window_focused auto& old_end_ts = cg_view.end.get_or_emplace().ts; if (old_end_ts != message_view_oldest.get().ts) { old_end_ts = message_view_oldest.get().ts; - if (end_created) { + if (endcreated) { std::cout << "CG: created view end ts with " << old_end_ts << "\n"; _rmm.throwEventConstruct(cg_view.end); } else { @@ -990,7 +995,7 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) { ); if (ImGui::BeginPopupContextItem("##text")) { if (ImGui::MenuItem("quote")) { - //text_buffer.insert(0, (_cr.all_of(c) ? _cr.get(c).name : "") + ": "); + //text_buffer.insert(0, (cr.all_of(c) ? cr.get(c).name : "") + ": "); if (!_text_input_buffer.empty()) { _text_input_buffer += "\n"; } @@ -1050,7 +1055,7 @@ void ChatGui4::renderMessageBodyText(Message3Registry& reg, const Message3 e) { if (ImGui::BeginPopupContextItem("##text")) { if (ImGui::MenuItem("quote")) { - //text_buffer.insert(0, (_cr.all_of(c) ? _cr.get(c).name : "") + ": "); + //text_buffer.insert(0, (cr.all_of(c) ? cr.get(c).name : "") + ": "); if (!_text_input_buffer.empty()) { _text_input_buffer += "\n"; } @@ -1429,15 +1434,16 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) { } if (ImGui::BeginMenu("forward", local_have_all)) { - for (const auto& c : _cr.view()) { + auto& cr = _cs.registry(); + for (const auto& c : cr.view()) { // filter - if (_cr.any_of(c)) { + if (cr.any_of(c)) { continue; } // TODO: check for contact capability // or just error popup?/noti/toast - if (renderContactBig(_theme, _contact_tc, {_cr, c}, 1, false, true, false)) { + if (renderContactBig(_theme, _contact_tc, {cr, c}, 1, false, true, false)) { // TODO: try object interface first instead, then fall back to send with SingleInfoLocal //_rmm.sendFileObj(c, o); std::filesystem::path path = o.get().file_path; @@ -1530,17 +1536,19 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) { ImGui::TextDisabled("msgid:%u", reg.get(e).id); } + const auto& cr = _cs.registry(); + if (reg.all_of(e)) { std::string synced_by_text {"syncedBy:"}; const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); for (const auto& [c, syned_ts] : reg.get(e).ts) { - if (_cr.all_of(c)) { + if (cr.all_of(c)) { synced_by_text += "\n sself"; - } else if (_cr.all_of(c)) { + } else if (cr.all_of(c)) { synced_by_text += "\n wself"; } else { - synced_by_text += "\n >" + (_cr.all_of(c) ? _cr.get(c).name : ""); + synced_by_text += "\n >" + (cr.all_of(c) ? cr.get(c).name : ""); } const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1; synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)"; @@ -1555,12 +1563,12 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) { const int64_t now_ts_s = int64_t(getTimeMS() / 1000u); for (const auto& [c, syned_ts] : reg.get(e).ts) { - if (_cr.all_of(c)) { + if (cr.all_of(c)) { synced_by_text += "\n sself"; // required (except when synced externally) - } else if (_cr.all_of(c)) { + } else if (cr.all_of(c)) { synced_by_text += "\n wself"; } else { - synced_by_text += "\n >" + (_cr.all_of(c) ? _cr.get(c).name : ""); + synced_by_text += "\n >" + (cr.all_of(c) ? cr.get(c).name : ""); } const int64_t seconds_ago = (int64_t(syned_ts / 1000u) - now_ts_s) * -1; synced_by_text += " (" + std::to_string(seconds_ago) + "sec ago)"; @@ -1572,8 +1580,9 @@ void ChatGui4::renderMessageExtra(Message3Registry& reg, const Message3 e) { void ChatGui4::renderContactList(void) { if (ImGui::BeginChild("contacts", {TEXT_BASE_WIDTH*35, 0})) { + auto& cr = _cs.registry(); //for (const auto& c : _cm.getBigContacts()) { - for (const auto& c : _cr.view()) { + for (const auto& c : cr.view()) { const bool selected = _selected_contact.has_value() && *_selected_contact == c; // TODO: is there a better way? @@ -1585,7 +1594,7 @@ void ChatGui4::renderContactList(void) { } } - if (renderContactBig(_theme, _contact_tc, {_cr, c}, 2, has_unread, true, selected)) { + if (renderContactBig(_theme, _contact_tc, {cr, c}, 2, has_unread, true, selected)) { _selected_contact = c; } } @@ -1593,10 +1602,12 @@ void ChatGui4::renderContactList(void) { ImGui::EndChild(); } -bool ChatGui4::renderContactListContactSmall(const Contact3 c, const bool selected) const { +bool ChatGui4::renderContactListContactSmall(const Contact4 c, const bool selected) const { std::string label; - label += (_cr.all_of(c) ? _cr.get(c).name.c_str() : ""); + const auto& cr = _cs.registry(); + + label += (cr.all_of(c) ? cr.get(c).name.c_str() : ""); label += "###"; label += std::to_string(entt::to_integral(c)); diff --git a/src/chat_gui4.hpp b/src/chat_gui4.hpp index b5f5d18..379b1a0 100644 --- a/src/chat_gui4.hpp +++ b/src/chat_gui4.hpp @@ -28,7 +28,7 @@ class ChatGui4 : public ObjectStoreEventI { ObjectStore2& _os; ObjectStoreEventProviderI::SubscriptionReference _os_sr; RegistryMessageModelI& _rmm; - Contact3Registry& _cr; + ContactStore4I& _cs; ContactTextureCache& _contact_tc; MessageTextureCache& _msg_tc; @@ -41,7 +41,7 @@ class ChatGui4 : public ObjectStoreEventI { SendImagePopup _sip; // TODO: refactor this to allow multiple open contacts - std::optional _selected_contact; + std::optional _selected_contact; // TODO: per contact std::string _text_input_buffer; @@ -63,7 +63,7 @@ class ChatGui4 : public ObjectStoreEventI { ConfigModelI& conf, ObjectStore2& os, RegistryMessageModelI& rmm, - Contact3Registry& cr, + ContactStore4I& cs, TextureUploaderI& tu, ContactTextureCache& contact_tc, MessageTextureCache& msg_tc, @@ -84,7 +84,7 @@ class ChatGui4 : public ObjectStoreEventI { void renderMessageExtra(Message3Registry& reg, const Message3 e); void renderContactList(void); - bool renderContactListContactSmall(const Contact3 c, const bool selected) const; + bool renderContactListContactSmall(const Contact4 c, const bool selected) const; //bool renderSubContactListContact(const Contact3 c, const bool selected) const; void pasteFile(const char* mime_type); diff --git a/src/frame_streams/voip_model.hpp b/src/frame_streams/voip_model.hpp index 573085f..2691550 100644 --- a/src/frame_streams/voip_model.hpp +++ b/src/frame_streams/voip_model.hpp @@ -1,8 +1,13 @@ #pragma once -#include +#include #include +#include +#include + +#include + struct VoIPModelI; namespace Components::VoIP { @@ -11,7 +16,7 @@ namespace Components::VoIP { // getting called or invited by struct Incoming { - Contact3 c{entt::null}; + Contact4 c{entt::null}; }; struct DefaultConfig { @@ -37,7 +42,7 @@ namespace Components::VoIP { }; struct SessionContact { - Contact3 c{entt::null}; + Contact4 c{entt::null}; }; struct StreamSources { @@ -65,7 +70,7 @@ struct VoIPModelI { // - default stream sources/sinks ? // - enable a/v ? -> done on connecting to sources // returns object tieing together the VoIP session - virtual ObjectHandle enter(const Contact3 c, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)c,(void)defaults; return {}; } + virtual ObjectHandle enter(const Contact4 c, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)c,(void)defaults; return {}; } // accept/join an invite to a session virtual bool accept(ObjectHandle session, const Components::VoIP::DefaultConfig& defaults = {true, true, true, true}) { (void)session,(void)defaults; return false; } diff --git a/src/main_screen.cpp b/src/main_screen.cpp index 8bd2113..0b9c3b7 100644 --- a/src/main_screen.cpp +++ b/src/main_screen.cpp @@ -36,33 +36,33 @@ static std::unique_ptr constructSystemTray(SimpleConfigModel& conf, MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_, Theme& theme_, std::string save_path, std::string save_password, std::string new_username, std::vector plugins) : renderer(renderer_), conf(conf_), - rmm(cr), - msnj{cr, os, {}, {}}, + rmm(cs), + msnj{cs, os, {}, {}}, mts(rmm), sm(os), tc(conf, save_path, save_password), tel(tc, std::cout), tpi(tc.getTox()), ad(tc), - tcm(cr, tc, tc), - tmm(rmm, cr, tcm, tc, tc), - ttm(rmm, cr, tcm, tc, tc, os), - tffom(cr, rmm, tcm, tc, tc), + tcm(cs, tc, tc), + tmm(rmm, cs, tcm, tc, tc), + ttm(rmm, cs, tcm, tc, tc, os), + tffom(cs, rmm, tcm, tc, tc), #if TOMATO_TOX_AV tav(tc.getTox()), - tavvoip(os, tav, cr, tcm), + tavvoip(os, tav, cs, tcm), #endif theme(theme_), mmil(rmm), - tam(/*rmm, */ os, cr, conf), + tam(/*rmm, */ os, cs, conf), sdlrtu(renderer_), - tal(cr), + tal(cs), contact_tc(tal, sdlrtu), mil(), msg_tc(mil, sdlrtu), st(constructSystemTray(conf, SDL_GetRenderWindow(renderer_))), - si(rmm, cr, SDL_GetRenderWindow(renderer_), st.get()), - cg(conf, os, rmm, cr, sdlrtu, contact_tc, msg_tc, theme), + si(rmm, cs, SDL_GetRenderWindow(renderer_), st.get()), + cg(conf, os, rmm, cs, sdlrtu, contact_tc, msg_tc, theme), sw(conf), osui(os), tuiu(tc, conf, &tpi), @@ -95,7 +95,7 @@ MainScreen::MainScreen(const SimpleConfigModel& conf_, SDL_Renderer* renderer_, g_provideInstance("ObjectStore2", "host", &os); g_provideInstance("ConfigModelI", "host", &conf); - g_provideInstance("Contact3Registry", "1", "host", &cr); + g_provideInstance("ContactStore4I", "host", &cs); g_provideInstance("RegistryMessageModelI", "host", &rmm); g_provideInstance("MessageSerializerNJ", "host", &msnj); @@ -386,12 +386,13 @@ Screen* MainScreen::render(float time_delta, bool&) { // TODO: move this somewhere else!!! // needs both tal and tc <.< - if (!cr.storage().empty()) { // handle force-reloads for avatars - std::vector to_purge; - cr.view().each([&to_purge](const Contact3 c) { + // TODO: move this code to events + if (!cs.registry().storage().empty()) { // handle force-reloads for avatars + std::vector to_purge; + cs.registry().view().each([&to_purge](const Contact4 c) { to_purge.push_back(c); }); - cr.remove(to_purge.cbegin(), to_purge.cend()); + cs.registry().remove(to_purge.cbegin(), to_purge.cend()); contact_tc.invalidate(to_purge); } // ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE diff --git a/src/main_screen.hpp b/src/main_screen.hpp index 64ab280..990ae04 100644 --- a/src/main_screen.hpp +++ b/src/main_screen.hpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -60,7 +60,7 @@ struct MainScreen final : public Screen { ObjectStore2 os; SimpleConfigModel conf; - Contact3Registry cr; + ContactStore4Impl cs; RegistryMessageModelImpl rmm; MessageSerializerNJ msnj; MessageTimeSort mts; diff --git a/src/os_comps.hpp b/src/os_comps.hpp index 078de72..c0f9d71 100644 --- a/src/os_comps.hpp +++ b/src/os_comps.hpp @@ -2,7 +2,7 @@ #include -#include +#include #include @@ -13,7 +13,7 @@ namespace ObjectStore::Components { namespace File { struct TransferStatsSeparated { - entt::dense_map stats; + entt::dense_map stats; }; } // File diff --git a/src/status_indicator.cpp b/src/status_indicator.cpp index 2e52d41..a87cd71 100644 --- a/src/status_indicator.cpp +++ b/src/status_indicator.cpp @@ -1,5 +1,7 @@ #include "./status_indicator.hpp" +#include + #include #include @@ -36,12 +38,12 @@ void StatusIndicator::updateState(State state) { StatusIndicator::StatusIndicator( RegistryMessageModelI& rmm, - Contact3Registry& cr, + ContactStore4I& cs, SDL_Window* main_window, SystemTray* tray ) : _rmm(rmm), - _cr(cr), + _cs(cs), _main_window(main_window), _tray(tray) { @@ -55,7 +57,7 @@ void StatusIndicator::render(float delta) { _cooldown = 1.f; // once a second bool has_unread = false; - for (const auto& c : _cr.view()) { + for (const auto& c : _cs.registry().view()) { // maybe cache mm? if (const auto* mm = _rmm.get(c); mm != nullptr) { if (const auto* unread_storage = mm->storage(); unread_storage != nullptr && !unread_storage->empty()) { diff --git a/src/status_indicator.hpp b/src/status_indicator.hpp index dbb009b..a52d4c1 100644 --- a/src/status_indicator.hpp +++ b/src/status_indicator.hpp @@ -10,7 +10,7 @@ class StatusIndicator { RegistryMessageModelI& _rmm; - Contact3Registry& _cr; + ContactStore4I& _cs; SDL_Window* _main_window; SystemTray* _tray; @@ -28,7 +28,7 @@ class StatusIndicator { public: StatusIndicator( RegistryMessageModelI& rmm, - Contact3Registry& cr, + ContactStore4I& cs, SDL_Window* main_window, SystemTray* tray = nullptr ); diff --git a/src/tox_avatar_loader.cpp b/src/tox_avatar_loader.cpp index 595fe5d..370bfd9 100644 --- a/src/tox_avatar_loader.cpp +++ b/src/tox_avatar_loader.cpp @@ -4,11 +4,13 @@ #include "./image_loader_qoi.hpp" #include "./image_loader_webp.hpp" #include "./image_loader_sdl_image.hpp" -#include "texture_uploader.hpp" +#include #include #include +#include + #include #include @@ -16,7 +18,7 @@ #include #include -ToxAvatarLoader::ToxAvatarLoader(Contact3Registry& cr) : _cr(cr) { +ToxAvatarLoader::ToxAvatarLoader(ContactStore4I& cs) : _cs(cs) { _image_loaders.push_back(std::make_unique()); _image_loaders.push_back(std::make_unique()); _image_loaders.push_back(std::make_unique()); @@ -115,13 +117,14 @@ static std::vector generateToxIdenticon(const ToxKey& key) { return pixels; } -TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) { - if (!_cr.valid(c)) { +TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact4 c) { + const auto& cr = _cs.registry(); + if (!cr.valid(c)) { return {std::nullopt}; } - if (_cr.all_of(c)) { - const auto& a_m = _cr.get(c); + if (cr.all_of(c)) { + const auto& a_m = cr.get(c); TextureEntry new_entry; new_entry.timestamp_last_rendered = getTimeMS(); @@ -139,8 +142,8 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) { return {new_entry}; } - if (_cr.all_of(c)) { - const auto& a_f = _cr.get(c); + if (cr.all_of(c)) { + const auto& a_f = cr.get(c); std::ifstream file(a_f.file_path, std::ios::binary); if (file.is_open()) { @@ -180,7 +183,7 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) { } } // continues if loading img fails - if (!_cr.any_of< + if (!cr.any_of< Contact::Components::ToxFriendPersistent, Contact::Components::ToxGroupPersistent, Contact::Components::ToxGroupPeerPersistent, @@ -190,16 +193,16 @@ TextureLoaderResult ToxAvatarLoader::load(TextureUploaderI& tu, Contact3 c) { } std::vector pixels; - if (_cr.all_of(c)) { - pixels = generateToxIdenticon(_cr.get(c).key); - } else if (_cr.all_of(c)) { - pixels = generateToxIdenticon(_cr.get(c).chat_id); - } else if (_cr.all_of(c)) { - pixels = generateToxIdenticon(_cr.get(c).peer_key); - } else if (_cr.all_of(c)) { + if (cr.all_of(c)) { + pixels = generateToxIdenticon(cr.get(c).key); + } else if (cr.all_of(c)) { + pixels = generateToxIdenticon(cr.get(c).chat_id); + } else if (cr.all_of(c)) { + pixels = generateToxIdenticon(cr.get(c).peer_key); + } else if (cr.all_of(c)) { // TODO: should we really use toxidenticons for other protocols? // (this is required for self) - auto id_copy = _cr.get(c).data; + auto id_copy = cr.get(c).data; id_copy.resize(32); pixels = generateToxIdenticon(id_copy); } diff --git a/src/tox_avatar_loader.hpp b/src/tox_avatar_loader.hpp index 87d95fb..39c71f8 100644 --- a/src/tox_avatar_loader.hpp +++ b/src/tox_avatar_loader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include "./image_loader.hpp" #include "./texture_cache.hpp" @@ -8,12 +8,12 @@ #include class ToxAvatarLoader { - Contact3Registry& _cr; + ContactStore4I& _cs; std::vector> _image_loaders; public: - ToxAvatarLoader(Contact3Registry& cr); - TextureLoaderResult load(TextureUploaderI& tu, Contact3 c); + ToxAvatarLoader(ContactStore4I& cr); + TextureLoaderResult load(TextureUploaderI& tu, Contact4 c); }; diff --git a/src/tox_avatar_manager.cpp b/src/tox_avatar_manager.cpp index c39f13d..dbc054f 100644 --- a/src/tox_avatar_manager.cpp +++ b/src/tox_avatar_manager.cpp @@ -4,6 +4,8 @@ #include +#include + //#include #include // for comp transfer tox filekind (TODO: generalize -> content system?) @@ -29,11 +31,10 @@ namespace Components { } ToxAvatarManager::ToxAvatarManager( - //RegistryMessageModel& rmm, ObjectStore2& os, - Contact3Registry& cr, + ContactStore4I& cs, ConfigModelI& conf -) : /*_rmm(rmm)*/ _os(os), _os_sr(_os.newSubRef(this)), _cr(cr), _conf(conf) { +) : _os(os), _os_sr(_os.newSubRef(this)), _cs(cs), _conf(conf) { _os_sr .subscribe(ObjectStore_Event::object_construct) .subscribe(ObjectStore_Event::object_update) @@ -53,11 +54,11 @@ ToxAvatarManager::ToxAvatarManager( { // scan tox contacts for cached avatars // old sts says pubkey.png - _cr.view().each([this](auto c, const Contact::Components::ToxFriendPersistent& tox_pers) { + _cs.registry().view().each([this](auto c, const Contact::Components::ToxFriendPersistent& tox_pers) { addAvatarFileToContact(c, tox_pers.key); }); - _cr.view().each([this](auto c, const Contact::Components::ToxGroupPersistent& tox_pers) { + _cs.registry().view().each([this](auto c, const Contact::Components::ToxGroupPersistent& tox_pers) { addAvatarFileToContact(c, tox_pers.chat_id); }); @@ -92,20 +93,25 @@ std::string ToxAvatarManager::getAvatarPath(const ToxKey& key) const { return file_path.generic_u8string(); } -void ToxAvatarManager::addAvatarFileToContact(const Contact3 c, const ToxKey& key) { +void ToxAvatarManager::addAvatarFileToContact(const Contact4 c, const ToxKey& key) { const auto file_path = getAvatarPath(key); if (std::filesystem::is_regular_file(file_path)) { // avatar file png file exists - _cr.emplace_or_replace(c, file_path); - _cr.emplace_or_replace(c); + _cs.registry().emplace_or_replace(c, file_path); + _cs.registry().emplace_or_replace(c); + + _cs.throwEventUpdate(c); } } -void ToxAvatarManager::clearAvatarFromContact(const Contact3 c) { - if (_cr.all_of(c)) { - std::filesystem::remove(_cr.get(c).file_path); - _cr.remove(c); - _cr.emplace_or_replace(c); +void ToxAvatarManager::clearAvatarFromContact(const Contact4 c) { + auto& cr = _cs.registry(); + if (cr.all_of(c)) { + std::filesystem::remove(cr.get(c).file_path); + cr.remove(c); + cr.emplace_or_replace(c); + + _cs.throwEventUpdate(c); } } diff --git a/src/tox_avatar_manager.hpp b/src/tox_avatar_manager.hpp index 7863b44..776c788 100644 --- a/src/tox_avatar_manager.hpp +++ b/src/tox_avatar_manager.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -15,7 +15,7 @@ struct ToxKey; class ToxAvatarManager : public ObjectStoreEventI { ObjectStore2& _os; ObjectStore2::SubscriptionReference _os_sr; - Contact3Registry& _cr; + ContactStore4I& _cs; ConfigModelI& _conf; struct AcceptEntry { @@ -27,7 +27,7 @@ class ToxAvatarManager : public ObjectStoreEventI { public: ToxAvatarManager( ObjectStore2& os, - Contact3Registry& cr, + ContactStore4I& cs, ConfigModelI& conf ); @@ -36,8 +36,8 @@ class ToxAvatarManager : public ObjectStoreEventI { protected: // TODO: become backend and work in objects instead std::string getAvatarPath(const ToxKey& key) const; - void addAvatarFileToContact(const Contact3 c, const ToxKey& key); - void clearAvatarFromContact(const Contact3 c); + void addAvatarFileToContact(const Contact4 c, const ToxKey& key); + void clearAvatarFromContact(const Contact4 c); void checkObj(ObjectHandle o); protected: // os diff --git a/src/tox_friend_faux_offline_messaging.cpp b/src/tox_friend_faux_offline_messaging.cpp index 0c4ce98..91c2dff 100644 --- a/src/tox_friend_faux_offline_messaging.cpp +++ b/src/tox_friend_faux_offline_messaging.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -27,12 +28,12 @@ namespace Contact::Components { } // Contact::Components ToxFriendFauxOfflineMessaging::ToxFriendFauxOfflineMessaging( - Contact3Registry& cr, + ContactStore4I& cs, RegistryMessageModelI& rmm, ToxContactModel2& tcm, ToxI& t, ToxEventProviderI& tep -) : _cr(cr), _rmm(rmm), _tcm(tcm), _t(t), _tep_sr(tep.newSubRef(this)) { +) : _cs(cs), _rmm(rmm), _tcm(tcm), _t(t), _tep_sr(tep.newSubRef(this)) { _tep_sr.subscribe(Tox_Event_Type::TOX_EVENT_FRIEND_CONNECTION_STATUS); } @@ -47,36 +48,40 @@ float ToxFriendFauxOfflineMessaging::tick(float time_delta) { const uint64_t ts_now = getTimeMS(); + auto& cr = _cs.registry(); + // check ALL // for each online tox friend uint64_t min_next_attempt_ts {std::numeric_limits::max()}; - _cr.view() - .each([this, &min_next_attempt_ts, ts_now](const Contact3 c, const auto& tfe, const auto& cs) { + cr.view() + .each([this, &cr, &min_next_attempt_ts, ts_now](const Contact4 c, const auto& tfe, const auto& cs) { if (cs.state == Contact::Components::ConnectionState::disconnected) { // cleanup - if (_cr.all_of(c)) { - _cr.remove(c); + if (cr.all_of(c)) { + // TODO: figure out if we want to throw update here + cr.remove(c); auto* mr = static_cast(_rmm).get(c); if (mr != nullptr) { mr->storage().clear(); } } } else { - if (!_cr.all_of(c)) { + if (!cr.all_of(c)) { if (false) { // has unsent messages - const auto& nsa = _cr.emplace(c, ts_now + uint64_t(_delay_after_cc*1000)); // wait before first message is sent + const auto& nsa = cr.emplace(c, ts_now + uint64_t(_delay_after_cc*1000)); // wait before first message is sent min_next_attempt_ts = std::min(min_next_attempt_ts, nsa.ts); } } else { auto ret = doFriendMessageCheck(c, tfe); if (ret == dfmc_Ret::SENT_THIS_TICK) { - const auto ts = _cr.get(c).ts = ts_now + uint64_t(_delay_inbetween*1000); + const auto ts = cr.get(c).ts = ts_now + uint64_t(_delay_inbetween*1000); min_next_attempt_ts = std::min(min_next_attempt_ts, ts); } else if (ret == dfmc_Ret::TOO_SOON) { // TODO: set to _delay_inbetween? prob expensive for no good reason - min_next_attempt_ts = std::min(min_next_attempt_ts, _cr.get(c).ts); + min_next_attempt_ts = std::min(min_next_attempt_ts, cr.get(c).ts); } else { - _cr.remove(c); + // TODO: figure out if we want to throw update here + cr.remove(c); } } } @@ -96,7 +101,7 @@ float ToxFriendFauxOfflineMessaging::tick(float time_delta) { return _interval_timer; } -ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe) { +ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact4 c, const Contact::Components::ToxFriendEphemeral& tfe) { // walk all messages and check if // unacked message // timeouts for exising unacked messages expired (send) @@ -109,11 +114,13 @@ ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendM const uint64_t ts_now = getTimeMS(); - if (!_cr.all_of(c)) { + const auto& cr = _cs.registry(); + + if (!cr.all_of(c)) { return dfmc_Ret::NO_MSG; // error } - const auto self_c = _cr.get(c).self; + const auto self_c = cr.get(c).self; // filter for unconfirmed messages @@ -222,7 +229,8 @@ bool ToxFriendFauxOfflineMessaging::onToxEvent(const Tox_Event_Friend_Connection return false; } - _cr.emplace_or_replace(c, getTimeMS() + uint64_t(_delay_after_cc*1000)); // wait before first message is sent + // TODO: should we throw update? + _cs.registry().emplace_or_replace(c, getTimeMS() + uint64_t(_delay_after_cc*1000)); // wait before first message is sent _interval_timer = 0.f; diff --git a/src/tox_friend_faux_offline_messaging.hpp b/src/tox_friend_faux_offline_messaging.hpp index b13ebff..575294b 100644 --- a/src/tox_friend_faux_offline_messaging.hpp +++ b/src/tox_friend_faux_offline_messaging.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include // fwd @@ -14,7 +14,7 @@ namespace Contact::Components { // resends unconfirmed messages. // timers get reset on connection changes, and send order is preserved. class ToxFriendFauxOfflineMessaging : public ToxEventI { - Contact3Registry& _cr; + ContactStore4I& _cs; RegistryMessageModelI& _rmm; ToxContactModel2& _tcm; ToxI& _t; @@ -29,7 +29,7 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI { public: ToxFriendFauxOfflineMessaging( - Contact3Registry& cr, + ContactStore4I& cs, RegistryMessageModelI& rmm, ToxContactModel2& tcm, ToxI& t, @@ -47,7 +47,7 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI { // only called for online friends // returns true if a message was sent // dont call this too often - dfmc_Ret doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe); + dfmc_Ret doFriendMessageCheck(const Contact4 c, const Contact::Components::ToxFriendEphemeral& tfe); protected: bool onToxEvent(const Tox_Event_Friend_Connection_Status* e) override;