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

Create a all loaded objects of type iterator/function #2406

Open
duncanspumpkin opened this issue Apr 6, 2024 · 2 comments
Open

Create a all loaded objects of type iterator/function #2406

duncanspumpkin opened this issue Apr 6, 2024 · 2 comments
Labels

Comments

@duncanspumpkin
Copy link
Contributor

We use the following in a lot of places:

for (uint8_t i = 0; i < ObjectManager::getMaxObjects(ObjectType::cargo); i++)
{
    auto cargo = ObjectManager::get<CargoObject>(i);
    if (cargo == nullptr)
        continue;

    // ...
}

Where cargo is just any particular type. We should make a helper method to handle this such as:

    // Calls function on every loaded object of TObject type
    // parameters of Visitor are TObject&, LoadedObjectId
    template<typename TObject, typename Visitor>
    void visitLoadedObjects(Visitor&& func)
    {
        static_assert(getMaxObjects(T::kObjectType) != 1);
        for (LoadedObjectId i = 0U; i < getMaxObjects(TObject::kObjectType); ++i)
        {
            auto* obj = get<TObject>(i);
            if (obj != nullptr)
            {
                func(*obj, i);
            }
        }
    }

   visitLoadedObjects<CargoObject>([](const CargoObject& cargo, LoadedObjectId i){
       // ...
   });

Now this works perfectly fine and would help but should we maybe make an iterator version so we could do:

const auto numCargos = std::count(std::begin(LoadedObjects<CargoObject>), std::end(LoadedObjects<CargoObject>), 0);

for (auto& cargo : LoadedObjects<CargoObject>)
{
    // ...
}

One thing with the iterator approach i'm not sure how you could get the index. So maybe it doesn't work in our situation. You can't easily go from object -> id.

@AaronVanGeffen
Copy link
Member

This is pattern that shows up a lot, so it's a neat idea indeed. Agreed the version that passes the ID would be better, for the same reason you've stated.

@ZehMatt
Copy link
Contributor

ZehMatt commented Apr 7, 2024

I would vote for the forEach visitor pattern, we can also return the object id with iterators, just return std::pair instead of the object only, then you can do for(auto&& [id, object] : getLoadedObjects<T>()), there is the downside that when we don't need the id we can't mark it as maybe_unused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants