refactor(MobileService): Auto load personal vehicles, modernized code & improved caching (#195)
This commit is contained in:
parent
740a4d48cf
commit
7ac3632553
@ -2,37 +2,35 @@
|
|||||||
#include "fiber_pool.hpp"
|
#include "fiber_pool.hpp"
|
||||||
#include "natives.hpp"
|
#include "natives.hpp"
|
||||||
#include "script.hpp"
|
#include "script.hpp"
|
||||||
#include "thread_pool.hpp"
|
|
||||||
#include "util/mobile.hpp"
|
#include "util/mobile.hpp"
|
||||||
|
|
||||||
namespace big
|
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<Hash*>();
|
m_hash = *vehicle_idx.at(66).as<Hash*>();
|
||||||
m_state_bitfield = vehicle_idx.at(103).as<int*>();
|
m_state_bitfield = vehicle_idx.at(103).as<int*>();
|
||||||
|
|
||||||
m_name = HUD::GET_LABEL_TEXT_(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(m_hash));
|
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);
|
return m_name + "##" + std::to_string(m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash PersonalVehicle::get_hash()
|
Hash personal_vehicle::get_hash() const
|
||||||
{
|
{
|
||||||
return m_hash;
|
return m_hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PersonalVehicle::get_id()
|
int personal_vehicle::get_id() const
|
||||||
{
|
{
|
||||||
return m_id;
|
return m_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PersonalVehicle::summon()
|
void personal_vehicle::summon() const
|
||||||
{
|
{
|
||||||
mobile::mechanic::summon_vehicle_by_index(m_id);
|
mobile::mechanic::summon_vehicle_by_index(m_id);
|
||||||
}
|
}
|
||||||
@ -47,38 +45,58 @@ namespace big
|
|||||||
g_mobile_service = nullptr;
|
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()
|
void mobile_service::register_vehicles()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < *mobile::vehicle_global.as<int*>(); i++)
|
const auto array_size = *mobile::vehicle_global.as<int*>();
|
||||||
|
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);
|
auto veh_idx_global = mobile::vehicle_global.at(i, 142);
|
||||||
|
|
||||||
Hash hash = *veh_idx_global.at(66).as<Hash*>();
|
const auto hash = *veh_idx_global.at(66).as<Hash*>();
|
||||||
auto& it = m_pv_lookup.find(i);
|
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))
|
if (STREAMING::IS_MODEL_A_VEHICLE(hash))
|
||||||
{
|
{
|
||||||
auto veh = std::make_unique<PersonalVehicle>(i, veh_idx_global);
|
auto veh = std::make_unique<personal_vehicle>(i, veh_idx_global);
|
||||||
|
|
||||||
if (it != m_pv_lookup.end())
|
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();
|
it->second = veh->get_display_name();
|
||||||
m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh));
|
m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pv_lookup.emplace(i, veh->get_display_name());
|
m_pv_lookup.emplace(i, veh->get_display_name()); // update lookup table
|
||||||
m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh));
|
m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh)); // add new vehicle
|
||||||
|
|
||||||
continue;
|
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_personal_vehicles.erase(it->second);
|
||||||
m_pv_lookup.erase(i);
|
m_pv_lookup.erase(i);
|
||||||
|
@ -4,7 +4,7 @@ namespace big
|
|||||||
{
|
{
|
||||||
class script_global;
|
class script_global;
|
||||||
|
|
||||||
class PersonalVehicle
|
class personal_vehicle final
|
||||||
{
|
{
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
int m_id;
|
int m_id;
|
||||||
@ -12,28 +12,37 @@ namespace big
|
|||||||
int* m_state_bitfield;
|
int* m_state_bitfield;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PersonalVehicle(int idx, script_global vehicle_idx);
|
personal_vehicle(int idx, script_global vehicle_idx);
|
||||||
|
|
||||||
std::string get_display_name();
|
[[nodiscard]] std::string get_display_name() const;
|
||||||
Hash get_hash();
|
[[nodiscard]] Hash get_hash() const;
|
||||||
int get_id();
|
[[nodiscard]] int get_id() const;
|
||||||
|
|
||||||
void summon();
|
void summon() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class mobile_service
|
class mobile_service final
|
||||||
{
|
{
|
||||||
|
std::map<std::string, std::unique_ptr<personal_vehicle>> m_personal_vehicles;
|
||||||
|
std::map<int, std::string> m_pv_lookup;
|
||||||
|
|
||||||
|
std::chrono::time_point<std::chrono::steady_clock> m_last_update;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mobile_service();
|
mobile_service();
|
||||||
~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<std::string, std::unique_ptr<personal_vehicle>>& personal_vehicles()
|
||||||
|
{ return m_personal_vehicles; }
|
||||||
|
void refresh_personal_vehicles();
|
||||||
void register_vehicles();
|
void register_vehicles();
|
||||||
|
|
||||||
std::map<std::string, std::unique_ptr<PersonalVehicle>> m_personal_vehicles;
|
|
||||||
std::map<int, std::string> m_pv_lookup;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class mobile_service;
|
|
||||||
inline mobile_service* g_mobile_service{};
|
inline mobile_service* g_mobile_service{};
|
||||||
}
|
}
|
@ -35,29 +35,28 @@ namespace big
|
|||||||
std::transform(lower_search.begin(), lower_search.end(), lower_search.begin(), tolower);
|
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 }))
|
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;
|
const auto& label = it.first;
|
||||||
auto& personal_veh = it.second;
|
const auto& personal_veh = it.second;
|
||||||
|
|
||||||
std::string lower = label.c_str();
|
auto lower = label;
|
||||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||||
|
|
||||||
if (lower.find(lower_search) != std::string::npos)
|
if (lower.find(lower_search) != std::string::npos)
|
||||||
{
|
{
|
||||||
if (ImGui::Selectable(
|
if (ImGui::Selectable(label.c_str(), personal_veh->get_id() == personal_veh_idx))
|
||||||
label.c_str(),
|
|
||||||
personal_veh->get_id() == mobile::util::get_current_personal_vehicle()
|
|
||||||
))
|
|
||||||
{
|
{
|
||||||
strcpy(search, "");
|
strcpy(search, "");
|
||||||
lower_search = search;
|
lower_search = search;
|
||||||
|
|
||||||
g_fiber_pool->queue_job([&personal_veh] {
|
g_fiber_pool->queue_job([&personal_veh] {
|
||||||
personal_veh->summon();
|
personal_veh->summon();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,14 +67,10 @@ namespace big
|
|||||||
ImGui::EndGroup();
|
ImGui::EndGroup();
|
||||||
|
|
||||||
ImGui::BeginGroup();
|
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::Checkbox("Spawn in Vehicle", &g->vehicle.pv_teleport_into);
|
||||||
|
|
||||||
|
ImGui::EndGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user