From 7ac3632553efd54adefc6070230074c0e41551a2 Mon Sep 17 00:00:00 2001 From: Yimura Date: Tue, 10 May 2022 19:02:30 +0200 Subject: [PATCH] refactor(MobileService): Auto load personal vehicles, modernized code & improved caching (#195) --- BigBaseV2/src/services/mobile_service.cpp | 60 +++++++++++++++-------- BigBaseV2/src/services/mobile_service.hpp | 33 ++++++++----- BigBaseV2/src/views/self/view_mobile.cpp | 27 +++++----- 3 files changed, 71 insertions(+), 49 deletions(-) diff --git a/BigBaseV2/src/services/mobile_service.cpp b/BigBaseV2/src/services/mobile_service.cpp index d7fdf1db..a3ae4d96 100644 --- a/BigBaseV2/src/services/mobile_service.cpp +++ b/BigBaseV2/src/services/mobile_service.cpp @@ -2,37 +2,35 @@ #include "fiber_pool.hpp" #include "natives.hpp" #include "script.hpp" -#include "thread_pool.hpp" #include "util/mobile.hpp" namespace big { - PersonalVehicle::PersonalVehicle(int idx, script_global vehicle_idx) + personal_vehicle::personal_vehicle(int idx, script_global vehicle_idx) + : m_id(idx) { - m_id = idx; - m_hash = *vehicle_idx.at(66).as(); m_state_bitfield = vehicle_idx.at(103).as(); m_name = HUD::GET_LABEL_TEXT_(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(m_hash)); } - std::string PersonalVehicle::get_display_name() + std::string personal_vehicle::get_display_name() const { return m_name + "##" + std::to_string(m_id); } - Hash PersonalVehicle::get_hash() + Hash personal_vehicle::get_hash() const { return m_hash; } - int PersonalVehicle::get_id() + int personal_vehicle::get_id() const { return m_id; } - void PersonalVehicle::summon() + void personal_vehicle::summon() const { mobile::mechanic::summon_vehicle_by_index(m_id); } @@ -47,38 +45,58 @@ namespace big g_mobile_service = nullptr; } + void mobile_service::refresh_personal_vehicles() + { + const auto now = std::chrono::high_resolution_clock::now(); + if (now - m_last_update < 10s) return; + + g_fiber_pool->queue_job([this] + { + register_vehicles(); + }); + } + void mobile_service::register_vehicles() { - for (int i = 0; i < *mobile::vehicle_global.as(); i++) + const auto array_size = *mobile::vehicle_global.as(); + for (int i = 0; i < array_size; i++) { - script::get_current()->yield(); + if (i % 100 == 0) + script::get_current()->yield(); auto veh_idx_global = mobile::vehicle_global.at(i, 142); - Hash hash = *veh_idx_global.at(66).as(); - auto& it = m_pv_lookup.find(i); + const auto hash = *veh_idx_global.at(66).as(); + const auto& it = m_pv_lookup.find(i); + const auto exists = it != m_pv_lookup.end(); + // double check if model is a vehicle if (STREAMING::IS_MODEL_A_VEHICLE(hash)) { - auto veh = std::make_unique(i, veh_idx_global); - - if (it != m_pv_lookup.end()) + auto veh = std::make_unique(i, veh_idx_global); + + if (exists) { - m_personal_vehicles.erase(it->second); + // vehicle name is no longer the same, update the vehicle at that index + if (veh->get_display_name() != it->second) + { + m_personal_vehicles.erase(it->second); - it->second = veh->get_display_name(); - m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh)); + it->second = veh->get_display_name(); + m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh)); + } continue; } - m_pv_lookup.emplace(i, veh->get_display_name()); - m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh)); + m_pv_lookup.emplace(i, veh->get_display_name()); // update lookup table + m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh)); // add new vehicle continue; } - if (it != m_pv_lookup.end()) + // vehicle existed at some point but no longer does + if (exists) { m_personal_vehicles.erase(it->second); m_pv_lookup.erase(i); diff --git a/BigBaseV2/src/services/mobile_service.hpp b/BigBaseV2/src/services/mobile_service.hpp index 5020b0f5..481b0577 100644 --- a/BigBaseV2/src/services/mobile_service.hpp +++ b/BigBaseV2/src/services/mobile_service.hpp @@ -4,7 +4,7 @@ namespace big { class script_global; - class PersonalVehicle + class personal_vehicle final { std::string m_name; int m_id; @@ -12,28 +12,37 @@ namespace big int* m_state_bitfield; public: - PersonalVehicle(int idx, script_global vehicle_idx); + personal_vehicle(int idx, script_global vehicle_idx); - std::string get_display_name(); - Hash get_hash(); - int get_id(); + [[nodiscard]] std::string get_display_name() const; + [[nodiscard]] Hash get_hash() const; + [[nodiscard]] int get_id() const; - void summon(); + void summon() const; }; - class mobile_service + class mobile_service final { + std::map> m_personal_vehicles; + std::map m_pv_lookup; + + std::chrono::time_point m_last_update; + public: mobile_service(); ~mobile_service(); + mobile_service(const mobile_service&) = delete; + mobile_service(mobile_service&&) noexcept = delete; + mobile_service& operator=(const mobile_service&) = delete; + mobile_service& operator=(mobile_service&&) noexcept = delete; + + std::map>& personal_vehicles() + { return m_personal_vehicles; } + void refresh_personal_vehicles(); void register_vehicles(); - std::map> m_personal_vehicles; - std::map m_pv_lookup; - }; - - class mobile_service; + inline mobile_service* g_mobile_service{}; } \ No newline at end of file diff --git a/BigBaseV2/src/views/self/view_mobile.cpp b/BigBaseV2/src/views/self/view_mobile.cpp index 75faeb1b..f60b5513 100644 --- a/BigBaseV2/src/views/self/view_mobile.cpp +++ b/BigBaseV2/src/views/self/view_mobile.cpp @@ -35,29 +35,28 @@ namespace big std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower); } + g_mobile_service->refresh_personal_vehicles(); if (ImGui::ListBoxHeader("##personal_veh_list", { 400.f, 500.f })) { - for (auto& it : g_mobile_service->m_personal_vehicles) + const auto personal_veh_idx = mobile::util::get_current_personal_vehicle(); + for (const auto& it : g_mobile_service->personal_vehicles()) { - std::string label = it.first; - auto& personal_veh = it.second; + const auto& label = it.first; + const auto& personal_veh = it.second; - std::string lower = label.c_str(); + auto lower = label; std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower); if (lower.find(lower_search) != std::string::npos) { - if (ImGui::Selectable( - label.c_str(), - personal_veh->get_id() == mobile::util::get_current_personal_vehicle() - )) + if (ImGui::Selectable(label.c_str(), personal_veh->get_id() == personal_veh_idx)) { strcpy(search, ""); lower_search = search; g_fiber_pool->queue_job([&personal_veh] { personal_veh->summon(); - }); + }); } } } @@ -68,14 +67,10 @@ namespace big ImGui::EndGroup(); ImGui::BeginGroup(); - - if (ImGui::Button("Load/Reload Personal Vehicles")) - { - g_fiber_pool->queue_job([] { - g_mobile_service->register_vehicles(); - }); - } + ImGui::Checkbox("Spawn in Vehicle", &g->vehicle.pv_teleport_into); + + ImGui::EndGroup(); } } \ No newline at end of file