c++boostcompiler-errorsmulti-indexboost-multi-index

compiler errors when trying to use modify function in boost multiindex when looping over a specific iterator?


I have made a boost multiindex of my GameObject, and I am trying to loop through and call non const functions on it. And I cannot for the life of me to get boost to stop giving long nasty compiler errors, like saying there is no matching function call and so forth.

Inside of game.hpp, I have this code to declare what my multiindex container looks like:

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/random_access_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/mem_fun.hpp>

#include "game_object.hpp"

struct ByPosition {};
struct ByName {};

namespace bmi = boost::multi_index;
typedef boost::multi_index_container<
    GameObject,
    bmi::indexed_by<
        bmi::random_access<
            bmi::tag<ByPosition>
        >,
        bmi::ordered_non_unique<
            bmi::tag<ByName>,
            bmi::const_mem_fun<GameObject, const std::string&, &GameObject::name>
        >
    >
> GameObjectCollection;

class Game
{
     //... various other code

private:
     GameObjectCollection gameObjects_;

}

then inside game_object.hpp:

#pragma once

#include <string>

#include "drawable.hpp"

class GameObject : public Drawable
{
public:
    virtual ~GameObject() = default;

    virtual void processEvent(const SDL_Event& event) {}
    virtual void update(const float deltaTime) {}

    const std::string& name() const { return name_; }
    void setName(const std::string& name) { name_ = name; }

private:
    std::string name_;
};

then inside game.cpp, where the compiler errors are triggered:

void Game::processEvent(const SDL_Event& event)
{
    auto& index = gameObjects_.get<ByPosition>();

    for (auto it : index)
        index.modify(it, [&event](GameObject& object) {
                object.processEvent(event);
        });
}

void Game::update()
{
    auto& index = gameObjects_.get<ByPosition>();

    for (const auto& it : index)
        index.modify(it, [&](GameObject& object) {
                object.update(deltaTime_);
        });
}

And with that boost is giving me these long compiler errors:

game.cpp: In member function ‘void Game::processEvent(const SDL_Event&)’:
game.cpp:68:21: error: no matching function for call to ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::modify(GameObject&, Game::processEvent(const SDL_Event&)::<lambda(GameObject&)>)’
   68 |         index.modify(it, [&event](GameObject& object) {
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   69 |                 object.processEvent(event);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   70 |         });
      |         ~~           
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note: candidate: ‘template<class Modifier> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier) [with Modifier = Modifier; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  472 |   bool modify(iterator position,Modifier mod)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note:   template argument deduction/substitution failed:
game.cpp:68:22: note:   cannot convert ‘it’ (type ‘GameObject’) to type ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::iterator’ {aka ‘boost::multi_index::detail::rnd_node_iterator<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::null_augment_policy, boost::multi_index::detail::index_node_base<GameObject, std::allocator<GameObject> > > > >’}
   68 |         index.modify(it, [&event](GameObject& object) {
      |                      ^~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note: candidate: ‘template<class Modifier, class Rollback> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier, Rollback) [with Modifier = Modifier; Rollback = Rollback; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  493 |   bool modify(iterator position,Modifier mod,Rollback back_)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note:   template argument deduction/substitution failed:
game.cpp:68:21: note:   candidate expects 3 arguments, 2 provided
   68 |         index.modify(it, [&event](GameObject& object) {
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   69 |                 object.processEvent(event);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
   70 |         });
      |         ~~           
game.cpp: In member function ‘void Game::update()’:
game.cpp:78:21: error: no matching function for call to ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::modify(const GameObject&, Game::update()::<lambda(GameObject&)>)’
   78 |         index.modify(it, [&](GameObject& object) {
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   79 |                 object.update(deltaTime_);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   80 |         });
      |         ~~           
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note: candidate: ‘template<class Modifier> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier) [with Modifier = Modifier; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  472 |   bool modify(iterator position,Modifier mod)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note:   template argument deduction/substitution failed:
game.cpp:78:22: note:   cannot convert ‘it’ (type ‘const GameObject’) to type ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::iterator’ {aka ‘boost::multi_index::detail::rnd_node_iterator<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::null_augment_policy, boost::multi_index::detail::index_node_base<GameObject, std::allocator<GameObject> > > > >’}
   78 |         index.modify(it, [&](GameObject& object) {
      |                      ^~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note: candidate: ‘template<class Modifier, class Rollback> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier, Rollback) [with Modifier = Modifier; Rollback = Rollback; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  493 |   bool modify(iterator position,Modifier mod,Rollback back_)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note:   template argument deduction/substitution failed:
game.cpp:78:21: note:   candidate expects 3 arguments, 2 provided
   78 |         index.modify(it, [&](GameObject& object) {
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   79 |                 object.update(deltaTime_);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   80 |         });
      |         ~~           

To fix it I tried for example:

Noticing that it said that 3 arguments were expected instead of 2, so I checked and apparently you might need a rollback function, eventhough some other documentation seems to suggest that is optional, but I tried it anyway, I didn't have anything to do for a rollback so I tried adding empty lambdas, like this, on update for example:

void Game::update()
{
    auto& index = gameObjects_.get<ByPosition>();

    for (const auto& it : index)
        index.modify(it, [&](GameObject& object) {
                object.update(deltaTime_);
        }, [](GameObject& obj){});
}

but then it still gives me that same complaint in the compiler error messages, where I see this:

/usr/include/boost/multi_index/random_access_index.hpp:472:8: note:   template argument deduction/substitution failed:
game.cpp:78:21: note:   candidate expects 2 arguments, 3 provided
   78 |         index.modify(it, [&](GameObject& object) {
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   79 |                 object.update(deltaTime_);
      |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~
   80 |         }, [](GameObject& object) {});
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I also tried to fix it all by using functors instead of lambdas, so in my game.hpp, I added:

class ProcessEvent {
public:
    ProcessEvent(const SDL_Event& event) : event_(event) {}
    void operator()(GameObject& gameObject) { gameObject.processEvent(event_); }
private:
    const SDL_Event& event_;
};

class Update {
public:
    Update(const float delta) : delta_(delta) {}
    void operator()(GameObject& gameObject) { gameObject.update(delta_); }
private:
    const float& delta_;
};

and changed the code in game.cpp to:

void Game::processEvent(const SDL_Event& event)
{
    auto& index = gameObjects_.get<ByPosition>();

    for (auto it : index)
        index.modify(it, ProcessEvent(event));
}

void Game::update()
{
    auto& index = gameObjects_.get<ByPosition>();

    for (const auto& it : index)
        index.modify(it, Update(deltaTime_));
}

but that just gives me these compiler error messages:

game.cpp: In member function ‘void Game::processEvent(const SDL_Event&)’:
game.cpp:68:21: error: no matching function for call to ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::modify(GameObject&, ProcessEvent)’
   68 |         index.modify(it, ProcessEvent(event));
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note: candidate: ‘template<class Modifier> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier) [with Modifier = Modifier; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  472 |   bool modify(iterator position,Modifier mod)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note:   template argument deduction/substitution failed:
game.cpp:68:22: note:   cannot convert ‘it’ (type ‘GameObject’) to type ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::iterator’ {aka ‘boost::multi_index::detail::rnd_node_iterator<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::null_augment_policy, boost::multi_index::detail::index_node_base<GameObject, std::allocator<GameObject> > > > >’}
   68 |         index.modify(it, ProcessEvent(event));
      |                      ^~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note: candidate: ‘template<class Modifier, class Rollback> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier, Rollback) [with Modifier = Modifier; Rollback = Rollback; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  493 |   bool modify(iterator position,Modifier mod,Rollback back_)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note:   template argument deduction/substitution failed:
game.cpp:68:21: note:   candidate expects 3 arguments, 2 provided
   68 |         index.modify(it, ProcessEvent(event));
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
game.cpp: In member function ‘void Game::update()’:
game.cpp:76:21: error: no matching function for call to ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::modify(const GameObject&, Update)’
   76 |         index.modify(it, Update(deltaTime_));
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note: candidate: ‘template<class Modifier> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier) [with Modifier = Modifier; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  472 |   bool modify(iterator position,Modifier mod)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:472:8: note:   template argument deduction/substitution failed:
game.cpp:76:22: note:   cannot convert ‘it’ (type ‘const GameObject’) to type ‘boost::multi_index::detail::random_access_index<boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >, boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0> >::iterator’ {aka ‘boost::multi_index::detail::rnd_node_iterator<boost::multi_index::detail::random_access_index_node<boost::multi_index::detail::ordered_index_node<boost::multi_index::detail::null_augment_policy, boost::multi_index::detail::index_node_base<GameObject, std::allocator<GameObject> > > > >’}
   76 |         index.modify(it, Update(deltaTime_));
      |                      ^~
In file included from game.hpp:6,
                 from game.cpp:3:
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note: candidate: ‘template<class Modifier, class Rollback> bool boost::multi_index::detail::random_access_index<SuperMeta, TagList>::modify(boost::multi_index::detail::random_access_index<SuperMeta, TagList>::iterator, Modifier, Rollback) [with Modifier = Modifier; Rollback = Rollback; SuperMeta = boost::multi_index::detail::nth_layer<1, GameObject, boost::multi_index::indexed_by<boost::multi_index::random_access<boost::multi_index::tag<ByPosition> >, boost::multi_index::ordered_non_unique<boost::multi_index::tag<ByName>, boost::multi_index::const_mem_fun<GameObject, const std::__cxx11::basic_string<char>&, &GameObject::name> > >, std::allocator<GameObject> >; TagList = boost::mpl::v_item<ByPosition, boost::mpl::vector0<mpl_::na>, 0>]’
  493 |   bool modify(iterator position,Modifier mod,Rollback back_)
      |        ^~~~~~
/usr/include/boost/multi_index/random_access_index.hpp:493:8: note:   template argument deduction/substitution failed:
game.cpp:76:21: note:   candidate expects 3 arguments, 2 provided
   76 |         index.modify(it, Update(deltaTime_));
      |         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~

I have been struggling trying to figure this all out for hours now.

Hopefully someone here can help me out with this.

Thank you.


Solution

  • You need to pass an iterator. it is now a copy of the element. Instead, use e.g.:

        for (auto it = index.begin(); it != index.end(); ++it)
            index.modify(it, [&event](GameObject& object) { object.processEvent(event); });
    

    See it Live On Coliru

    #include <boost/multi_index/mem_fun.hpp>
    #include <boost/multi_index/ordered_index.hpp>
    #include <boost/multi_index/random_access_index.hpp>
    #include <boost/multi_index_container.hpp>
    #include <string>
    
    //#include "drawable.hpp"
    #include <SDL2/SDL.h>
    class Drawable {
      public:
        virtual ~Drawable() = default;
        virtual void update(float const deltaTime) = 0;
    };
    // end stub
    
    class GameObject : public Drawable {
      public:
        virtual ~GameObject() = default;
    
        virtual void processEvent(SDL_Event const& /*event*/) {}
        virtual void update(float const /*deltaTime*/) {}
    
        std::string const& name() const { return name_; }
        void               setName(std::string const& name) { name_ = name; }
    
      private:
        std::string name_;
    };
    
    namespace bmi = boost::multi_index;
    typedef boost::multi_index_container<
        GameObject,
        bmi::indexed_by<
            bmi::random_access<bmi::tag<struct ByPosition>>,
            bmi::ordered_non_unique<bmi::tag<struct ByName>,
                                    bmi::const_mem_fun<GameObject, std::string const&, &GameObject::name>>>>
        GameObjectCollection;
    
    class Game {
        //... various other code
      public:
        void processEvent(SDL_Event const& event) {
            auto& index = gameObjects_.get<ByPosition>();
    
            for (auto it = index.begin(); it != index.end(); ++it)
                index.modify(it, [&event](GameObject& object) { object.processEvent(event); });
        }
    
        void update() {
            auto& index = gameObjects_.get<ByPosition>();
    
            for (auto it = index.begin(); it != index.end(); ++it)
                index.modify(it, [&](GameObject& object) { object.update(deltaTime_); });
        }
    
      private:
        static constexpr float deltaTime_ = 0.1f;
        GameObjectCollection   gameObjects_;
    };
    
    int main() {
        Game game;
    
        // Example usage
        SDL_Event event;
        // Initialize SDL and create an event loop here...
    
        while (true) {
            // Poll events and call game.processEvent(event);
            game.processEvent(event);
    
            // Update game state
            game.update();
    
            // Render the game...
        }
    }