Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimization Handling (part 3) and Remove big use eVehicleTypes #3848

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

G-Moris
Copy link
Contributor

@G-Moris G-Moris commented Nov 8, 2024

Continuation of PR - #3580;
Removed the frequent useless use of eVehicleTypes.

Client/game_sa/CHandlingEntrySA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CHandlingManagerSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CHandlingEntrySA.h Outdated Show resolved Hide resolved
Client/game_sa/CHandlingManagerSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CHandlingManagerSA.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/CHandlingManager.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/CHandlingManager.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/CHandlingManager.cpp Outdated Show resolved Hide resolved
Server/mods/deathmatch/logic/CHandlingManager.h Outdated Show resolved Hide resolved
@Fernando-A-Rocha
Copy link
Contributor

Good initiative! 😀

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 9, 2024

@TracerDS Hello. Maybe I should add WriteDebugEvent to some events?

@TracerDS
Copy link
Contributor

TracerDS commented Nov 9, 2024

@TracerDS Hello. Maybe I should add WriteDebugEvent to some events?

what for

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 9, 2024

@TracerDS Hello. Maybe I should add WriteDebugEvent to some events?

what for

For try-catch

Example:

void CHandlingEntrySA::Recalculate() noexcept
{
    // Real GTA class?
    if (!m_HandlingSA)
        return;

    try
    {
        // Copy our stored field to GTA's
        memcpy(m_HandlingSA.get(), &m_Handling, sizeof(m_Handling));
        ((void(_stdcall*)(tHandlingDataSA*))FUNC_HandlingDataMgr_ConvertDataToGameUnits)(m_HandlingSA.get());
    }
    catch (...)
    {
        WriteDebugEvent("Failed recalculate vehicle handling!");
    }
}

@TracerDS
Copy link
Contributor

TracerDS commented Nov 9, 2024

@TracerDS Hello. Maybe I should add WriteDebugEvent to some events?

what for

For try-catch

Example:

void CHandlingEntrySA::Recalculate() noexcept
{
    // Real GTA class?
    if (!m_HandlingSA)
        return;

    try
    {
        // Copy our stored field to GTA's
        memcpy(m_HandlingSA.get(), &m_Handling, sizeof(m_Handling));
        ((void(_stdcall*)(tHandlingDataSA*))FUNC_HandlingDataMgr_ConvertDataToGameUnits)(m_HandlingSA.get());
    }
    catch (...)
    {
        WriteDebugEvent("Failed recalculate vehicle handling!");
    }
}

No need.
In this case that try catch is kinda meh. Only ConvertDataToGameUnits could potentially throw but judging from the name it shouldnt

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 9, 2024

@TracerDS Would it be worth making AddVehicle return std::unique_ptr?

@TracerDS
Copy link
Contributor

TracerDS commented Nov 9, 2024

@TracerDS Would it be worth making AddVehicle return std::unique_ptr?

if it returns raw pointer then yes

Client/game_sa/CModelInfoSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CModelInfoSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CModelInfoSA.cpp Outdated Show resolved Hide resolved
@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

@TracerDS Do you like the idea of refining the function this way?

CHandlingEntry* CHandlingManager::GetModelHandlingData(std::uint32_t model) const noexcept
{
    // Within range?
    if (!CVehicleManager::IsValidModel(model))
        return nullptr;

    auto entries = m_ModelEntries.find(model);
    if (entries == m_ModelEntries.end())
    {
        // Get our Handling ID
        eHandlingTypes eHandling = GetHandlingID(model);

        auto entry = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
        entries = m_ModelEntries.emplace(model, std::move(entry)).first;
    }

    return entries->second.get();
}

@TracerDS
Copy link
Contributor

TracerDS commented Nov 10, 2024

@TracerDS Do you like the idea of refining the function this way?

CHandlingEntry* CHandlingManager::GetModelHandlingData(std::uint32_t model) const noexcept
{
    // Within range?
    if (!CVehicleManager::IsValidModel(model))
        return nullptr;

    auto entries = m_ModelEntries.find(model);
    if (entries == m_ModelEntries.end())
    {
        // Get our Handling ID
        eHandlingTypes eHandling = GetHandlingID(model);

        auto entry = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
        entries = m_ModelEntries.emplace(model, std::move(entry)).first;
    }

    return entries->second.get();
}

I very much do not like the std::move(entry) on an unique_ptr. Btw thats not a refactor but a huge change how GetModelHandlingData fetches data.

this is pretty bad because it will always construct entry, even if insertion fails

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

@TracerDS Do you like the idea of refining the function this way?

CHandlingEntry* CHandlingManager::GetModelHandlingData(std::uint32_t model) const noexcept
{
    // Within range?
    if (!CVehicleManager::IsValidModel(model))
        return nullptr;

    auto entries = m_ModelEntries.find(model);
    if (entries == m_ModelEntries.end())
    {
        // Get our Handling ID
        eHandlingTypes eHandling = GetHandlingID(model);

        auto entry = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
        entries = m_ModelEntries.emplace(model, std::move(entry)).first;
    }

    return entries->second.get();
}

I very much do not like the std::move(entry) on an unique_ptr. Btw thats not a refactor but a huge change how GetModelHandlingData fetches data.

this is pretty bad because it will always construct entry, even if insertion fails

@TracerDS Do you like the idea of refining the function this way?

CHandlingEntry* CHandlingManager::GetModelHandlingData(std::uint32_t model) const noexcept
{
    // Within range?
    if (!CVehicleManager::IsValidModel(model))
        return nullptr;

    auto entries = m_ModelEntries.find(model);
    if (entries == m_ModelEntries.end())
    {
        // Get our Handling ID
        eHandlingTypes eHandling = GetHandlingID(model);

        auto entry = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
        entries = m_ModelEntries.emplace(model, std::move(entry)).first;
    }

    return entries->second.get();
}

I very much do not like the std::move(entry) on an unique_ptr. Btw thats not a refactor but a huge change how GetModelHandlingData fetches data.

this is pretty bad because it will always construct entry, even if insertion fails

std::move transfers the owner to m_ModelEntries, at least I don't see anything wrong or risky in this. Can set a condition with the "entry" check

@TracerDS
Copy link
Contributor

std::move transfers the owner to m_ModelEntries, at least I don't see anything wrong or risky in this. Can set a condition with the "entry" check

No. std::move doesnt "move" anything.

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

std::move transfers the owner to m_ModelEntries, at least I don't see anything wrong or risky in this. Can set a condition with the "entry" check

No. std::move doesnt "move" anything.

It transfers ownership, as I know

@TracerDS
Copy link
Contributor

TracerDS commented Nov 10, 2024

It transfers ownership, as I know

No. It only converts the value to rvalue. Thats all. If the value is already a rvalue then the conversion does nothing.
It only marks the value can be transferred but does not automatically move the ownership.

This is the basic implementation of std::move:

template <typename T>
typename remove_reference<T>::type&& move(T&& arg)
{
  return static_cast<typename remove_reference<T>::type&&>(arg);
}

Lets format it into int only:

template<class T> struct remove_reference { typedef T type; };
template<class T> struct remove_reference<T&> { typedef T type; };
template<class T> struct remove_reference<T&&> { typedef T type; };

inline
int&& move(int&& arg)
{
  return static_cast<int&&>(arg);
}

As you can see no transfer is done by move manually.

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

As you can see no transfer is done by move manually.

Is that better?

// Get our Handling ID
eHandlingTypes eHandling = GetHandlingID(model);

m_ModelEntries[model] = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
if (!m_ModelEntries[model])
    return nullptr;

entries = m_ModelEntries.find(model);

@TracerDS
Copy link
Contributor

Is that better?

// Get our Handling ID
eHandlingTypes eHandling = GetHandlingID(model);

m_ModelEntries[model] = std::make_unique<CHandlingEntry>(&m_OriginalHandlingData[eHandling]);
if (!m_ModelEntries[model])
    return nullptr;

entries = m_ModelEntries.find(model);

Yes

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

Yes

Is it possible to change to this?

// Original handling data
static std::unordered_map<std::size_t, tHandlingData>                   m_OriginalHandlingData;
static std::unordered_map<std::size_t, std::unique_ptr<CHandlingEntry>> m_OriginalEntries;

// Model handling data
static std::unordered_map<std::size_t, std::unique_ptr<CHandlingEntry>> m_ModelEntries;
static std::unordered_map<std::size_t, bool>                            m_bModelHandlingChanged;

static std::map<std::string, eHandlingProperty> m_HandlingNames;

@TracerDS
Copy link
Contributor

// Original handling data
static std::unordered_map<std::size_t, tHandlingData>                   m_OriginalHandlingData;
static std::unordered_map<std::size_t, std::unique_ptr<CHandlingEntry>> m_OriginalEntries;

// Model handling data
static std::unordered_map<std::size_t, std::unique_ptr<CHandlingEntry>> m_ModelEntries;
static std::unordered_map<std::size_t, bool>                            m_bModelHandlingChanged;

static std::map<std::string, eHandlingProperty> m_HandlingNames;

what are the original declarations?

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

what are the original declarations?

std::unordered_map will help us for a more dynamic and convenient use

    std::map<std::string, eHandlingProperty> m_HandlingNames;
    
    // Original handling data unaffected by handling.cfg changes
    static SFixedArray<tHandlingData, HT_MAX> m_OriginalHandlingData;

    // Array with the original handling entries
    static SFixedArray<std::unique_ptr<CHandlingEntry>, HT_MAX> m_OriginalEntries;

    // Array with the model handling entries
    static SFixedArray<std::unique_ptr<CHandlingEntry>, HT_MAX> m_ModelEntries;

    SFixedArray<bool, HT_MAX> m_bModelHandlingChanged;

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

@TracerDS

How do you like the idea of putting common initializers {} for variables in the CTransmissionSAInterface and tHandlingDataSA structures?

@TracerDS
Copy link
Contributor

I dont think its needed. After all, we are taking values from gtasa memory pool; it will be initialized by gta at some point.

@G-Moris
Copy link
Contributor Author

G-Moris commented Nov 10, 2024

I dont think its needed. After all, we are taking values from gtasa memory pool; it will be initialized by gta at some point.

Should add an IsAllocatedInArchive check to CModelInfoSA::IsVehicle?

@TracerDS
Copy link
Contributor

Do whatever you think is necessary

Client/game_sa/CModelInfoSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CPoolsSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CCamSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CGameSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CGameSA.cpp Outdated Show resolved Hide resolved
Client/game_sa/CGameSA.h Outdated Show resolved Hide resolved
Client/game_sa/CGameSA.h Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants