#include "./re_announce_systems.hpp" #include "./components.hpp" #include #include #include #include #include namespace Systems { void re_announce( ObjectRegistry& os_reg, Contact3Registry& cr, NGCEXTEventProvider& neep, const float delta ) { std::vector to_remove; os_reg.view().each([&os_reg, &cr, &neep, &to_remove, delta](Object ov, Components::ReAnnounceTimer& rat) { ObjectHandle o{os_reg, ov}; // if paused -> remove if (o.all_of()) { to_remove.push_back(ov); return; } // if not downloading or info incomplete -> remove if (!o.all_of()) { to_remove.push_back(ov); assert(false && "transfer in broken state"); return; } if (o.get().have_all) { // transfer done, we stop announcing to_remove.push_back(ov); return; } // update all timers rat.timer -= delta; // send announces if (rat.timer <= 0.f) { rat.reset(); // exponential back-off std::vector announce_id; const uint32_t file_kind = static_cast(NGCFT1_file_kind::HASH_SHA1_INFO); for (size_t i = 0; i < sizeof(file_kind); i++) { announce_id.push_back((file_kind>>(i*8)) & 0xff); } assert(o.all_of()); const auto& info_hash = o.get().hash; announce_id.insert(announce_id.cend(), info_hash.cbegin(), info_hash.cend()); for (const auto cv : o.get().targets) { if (cr.all_of(cv)) { // private ? const auto [group_number, peer_number] = cr.get(cv); neep.send_pc1_announce(group_number, peer_number, announce_id.data(), announce_id.size()); } else if (cr.all_of(cv)) { // public const auto group_number = cr.get(cv).group_number; neep.send_all_pc1_announce(group_number, announce_id.data(), announce_id.size()); } else { assert(false && "we dont know how to announce to this target"); } } } }); for (const auto ov : to_remove) { os_reg.remove(ov); // we keep the annouce target list around (if it exists) // TODO: should we make the target list more generic? } // TODO: how to handle unpause? } } // Systems