1
\$\begingroup\$

I am attempting to create a fast & robust object management system that allows adding, removing and retrieving objects from a "scene". I am trying to wrap my head around the best way to do this regarding ownership and object lifecycle. Code:

main.cpp:

int main()
{
 r3d::scene main_scene;
 game_object& obj = main_scene.create_object("obj", glm::vec3(0, 0, 0), glm::vec3(-90, 0, -90), glm::vec3(1, 1, 1));
 main_scene.remove_object("obj");
 return 0;
}

scene.hpp:

namespace r3d
{
 class scene
 {
 public:
 scene::scene() { }
 game_object& create_object(std::string name,
 glm::vec3 position = glm::vec3(0, 0, 0),
 glm::vec3 euler_angles = glm::vec3(0, 0, 0),
 glm::vec3 scale = glm::vec3(1, 1, 1));
 void remove_object(std::string);
 game_object& get_object(std::string);
 private:
 std::map<std::string, r3d::game_object> game_objects;
 };
}

scene.cpp:

game_object& scene::create_object(std::string name, glm::vec3 position, glm::vec3 euler_angles, glm::vec3 scale)
{
 game_objects.emplace(name, game_object { name, position, euler_angles, scale });
 return game_objects[name];
}
void scene::remove_object(std::string name)
{
 game_objects.erase(name);
}
game_object& scene::get_object(std::string name)
{
 return game_objects[name];
}

game_object.hpp

namespace r3d
{
 class game_object
 {
 public:
 std::string name;
 game_object() {}
 // constructor
 game_object(std::string name, glm::vec3 position, glm::vec3 euler_angles, glm::vec3 scale) 
 : name(name), 
 position(position), 
 euler_angles(euler_angles), 
 scale(scale) 
 {
 printf("New game_object: %s [address: %p]\n", name.c_str(), this);
 }
 // destructor
 ~game_object()
 {
 printf("Delete game_object: %s [address: %p]\n", name.c_str(), this);
 }
 // copy constructor
 game_object(const game_object& source)
 : name { source.name },
 position { source.position },
 euler_angles { source.euler_angles },
 scale { source.scale }
 {
 printf("Copy game_object: %s [from: %p to: %p]\n", source.name.c_str(), &source, this);
 }
 // move constructor
 game_object(game_object&& source)
 : name { source.name },
 position { source.position },
 euler_angles { source.euler_angles },
 scale { source.scale }
 {
 printf("Move game_object: %s [from: %p to: %p]\n", source.name.c_str(), &source, this);
 }
 protected:
 glm::vec3 position;
 glm::vec3 euler_angles;
 glm::vec3 scale;
 };
}
asked Dec 4, 2018 at 14:08
\$\endgroup\$
7
  • 3
    \$\begingroup\$ Do you really want to use pointers here (even smart)? can't you deal with inplace object and references? Also, did you tried std::map or std::unordered_map (with name as a key) instead of a std::set? Can't you emplace the game_object ? \$\endgroup\$ Commented Dec 4, 2018 at 15:46
  • 1
    \$\begingroup\$ Responding to those questions might help people to provide good reviews. \$\endgroup\$ Commented Dec 8, 2018 at 14:37
  • \$\begingroup\$ Thanks for pointing (xD) me in the right direction, was under the assumption that it’s good practice to use pointers to all objects in cpp. After doing some more research I have improved my solution (edited above). \$\endgroup\$ Commented Dec 21, 2018 at 16:31
  • \$\begingroup\$ Please add the relevant #includes to the code listings and make sure your code compiles and runs correctly. I'd be surprised if this compiles, since std::map operator[] requires a default constructor and game_object doesn't have one. \$\endgroup\$ Commented Dec 21, 2018 at 17:07
  • 1
    \$\begingroup\$ Your code is essentially a wrapper around a dictionary. What is your use-case for string lookup of the objects? If it's configuration-file-based, then fine. But if there are no exterior files expected to refer to objects, and this is intended for static code only, then I don't understand how this approach benefits you. \$\endgroup\$ Commented Dec 21, 2018 at 17:15

1 Answer 1

1
\$\begingroup\$

the idea being that any other class can access a game_object by name if given a reference to main_scene, even if it doesn't hold a reference to the actual object

You've stated that one of your primary goals is speed. Based on your description above, you can still achieve object lookup and avoid the performance hit of a string dictionary.

One of the easiest ways to do this is to add a header file to the application that defines an enum of numeric, sequential object IDs. This will allow for much faster lookup, and depending on how you define and load your data, you wouldn't even need a map - simply a fixed array.

answered Dec 21, 2018 at 17:52
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.