From 3da5872df889fa68ea395bef156e30aa2c960e81 Mon Sep 17 00:00:00 2001 From: Green Sky Date: Sat, 3 Feb 2024 01:05:50 +0100 Subject: [PATCH] fix tffom and have it actually functioning --- src/tox_friend_faux_offline_messaging.cpp | 77 +++++++++++++++-------- src/tox_friend_faux_offline_messaging.hpp | 9 ++- 2 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/tox_friend_faux_offline_messaging.cpp b/src/tox_friend_faux_offline_messaging.cpp index ca93336d..dcd960ec 100644 --- a/src/tox_friend_faux_offline_messaging.cpp +++ b/src/tox_friend_faux_offline_messaging.cpp @@ -10,6 +10,8 @@ #include #include +//#include + namespace Message::Components { struct LastSendAttempt { uint64_t ts {0}; @@ -29,15 +31,17 @@ ToxFriendFauxOfflineMessaging::ToxFriendFauxOfflineMessaging( ToxI& t, ToxEventProviderI& tep ) : _cr(cr), _rmm(rmm), _tcm(tcm), _t(t), _tep(tep) { + _tep.subscribe(this, Tox_Event_Type::TOX_EVENT_FRIEND_CONNECTION_STATUS); } float ToxFriendFauxOfflineMessaging::tick(float time_delta) { - // hard limit interval to once per minute - _interval_timer += time_delta; - if (_interval_timer < 1.f * 60.f) { - return std::max(60.f - _interval_timer, 0.001f); // TODO: min next timer + _interval_timer -= time_delta; + if (_interval_timer > 0.f) { + return std::max(_interval_timer, 0.001f); // TODO: min next timer } - _interval_timer = 0.f; + // interval ~ once per minute + _interval_timer = 60.f; + const uint64_t ts_now = Message::getTimeMS(); @@ -50,37 +54,47 @@ float ToxFriendFauxOfflineMessaging::tick(float time_delta) { // cleanup if (_cr.all_of(c)) { _cr.remove(c); + auto* mr = static_cast(_rmm).get(c); + if (mr != nullptr) { + mr->storage().clear(); + } } } else { if (!_cr.all_of(c)) { - 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& next_attempt = _cr.get(c).ts; - - if (doFriendMessageCheck(c, tfe)) { - next_attempt = ts_now + uint64_t(_delay_inbetween*1000); + 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 + 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); + 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); + } else { + _cr.remove(c); } - - min_next_attempt_ts = std::min(min_next_attempt_ts, next_attempt); } } }); if (min_next_attempt_ts <= ts_now) { // we (probably) sent this iterate - _interval_timer = 60.f - 0.1f; // TODO: ugly magic - return 0.1f; + _interval_timer = 0.1f; // TODO: ugly magic } else if (min_next_attempt_ts == std::numeric_limits::max()) { // nothing to sync or all offline that need syncing - return 60.f; // TODO: ugly magic } else { - // TODO: ugly magic - return _interval_timer = 60.f - std::min(60.f, (min_next_attempt_ts - ts_now) / 1000.f); + _interval_timer = std::min(_interval_timer, (min_next_attempt_ts - ts_now) / 1000.f); } + + //std::cout << "TFFOM: iterate (i:" << _interval_timer << ")\n"; + + return _interval_timer; } -bool ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe) { +ToxFriendFauxOfflineMessaging::dfmc_Ret ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe) { // walk all messages and check if // unacked message // timeouts for exising unacked messages expired (send) @@ -88,7 +102,7 @@ bool ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const auto* mr = static_cast(_rmm).get(c); if (mr == nullptr) { // no messages - return false; + return dfmc_Ret::NO_MSG; } const uint64_t ts_now = Message::getTimeMS(); @@ -98,6 +112,7 @@ bool ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const // we assume sorted // ("reverse" iteration <.<) auto msg_view = mr->view(); + bool valid_unsent {false}; // we search for the oldest, not too recently sent, unconfirmed message for (auto it = msg_view.rbegin(), view_end = msg_view.rend(); it != view_end; it++) { const Message3 msg = *it; @@ -119,6 +134,12 @@ bool ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const continue; // skip } + if (mr->get(msg).c != c) { + continue; // not outbound (in private) + } + + valid_unsent = true; + uint64_t msg_ts = msg_view.get(msg).ts; if (mr->all_of(msg)) { msg_ts = mr->get(msg).ts; @@ -155,12 +176,17 @@ bool ToxFriendFauxOfflineMessaging::doFriendMessageCheck(const Contact3 c, const } // else error // we sent our message, no point further iterating - return true; + return dfmc_Ret::SENT_THIS_TICK; } - // TODO: somehow cleanup lsa + if (!valid_unsent) { + // somehow cleanup lsa + mr->storage().clear(); + //std::cout << "TFFOM: all sent, deleting lsa\n"; + return dfmc_Ret::NO_MSG; + } - return false; + return dfmc_Ret::TOO_SOON; } bool ToxFriendFauxOfflineMessaging::onToxEvent(const Tox_Event_Friend_Connection_Status* e) { @@ -180,8 +206,7 @@ bool ToxFriendFauxOfflineMessaging::onToxEvent(const Tox_Event_Friend_Connection _cr.emplace_or_replace(c, Message::getTimeMS() + uint64_t(_delay_after_cc*1000)); // wait before first message is sent - // TODO: ugly magic - _interval_timer = 60.f - 0.1f; + _interval_timer = 0.f; return false; } diff --git a/src/tox_friend_faux_offline_messaging.hpp b/src/tox_friend_faux_offline_messaging.hpp index 4829216d..200e8272 100644 --- a/src/tox_friend_faux_offline_messaging.hpp +++ b/src/tox_friend_faux_offline_messaging.hpp @@ -24,7 +24,7 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI { // TODO: increase timer? const float _delay_after_cc {4.5f}; - const float _delay_inbetween {0.3f}; + const float _delay_inbetween {1.3f}; const float _delay_retry {10.f}; // retry sending after 10s public: @@ -39,10 +39,15 @@ class ToxFriendFauxOfflineMessaging : public ToxEventI { float tick(float time_delta); private: + enum class dfmc_Ret { + TOO_SOON, + SENT_THIS_TICK, + NO_MSG, + }; // only called for online friends // returns true if a message was sent // dont call this too often - bool doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe); + dfmc_Ret doFriendMessageCheck(const Contact3 c, const Contact::Components::ToxFriendEphemeral& tfe); protected: bool onToxEvent(const Tox_Event_Friend_Connection_Status* e) override;