A Question about Handles
a guest Jun 25th, 2019 147 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
- Hi Casey!
- In an effort to make my game state serializable, I replaced pointers to entites with handles. I hoped to avoid pointer fix-ups and heard from Jon and some others, that handles for game objects are the goto solution. In my case, a handle holds an array index, and an integer for the generation (to catch use-after-free bugs). Each entity gets it's own pool allocator, you can get a pointer from a handle by looking into that pool. So far so good.
- Except: I use basic inheritance for my entites and other things. For example: I have 3 kinds of physics bodies, circle-, rectangle- and polygon-bodies. When entities just wanted to refer to "some physics objects" they could hold a pointer to their common base-class: Physics_Body. Replacing these pointers with handles is tricky:
- If I have a handle to a Physics_Body, I can't directly resolve it, because there is no Physics_Body-pool. There are only pools for Circle-, Rectangle- and Polygon-Bodies. My solution was to introduce a generic handle, that carries the actual type of object. On lookup, I can switch on that and find the right pool.
- But what if you want to get a handle from pointer? In case of a Physics_Body pointer, you don't know in which pool the entity resides, because there might be a Circle/Rectangle/Polygon-Body behind this pointer. So I ended up adding the actual type not only to the handle, but to all the entites. And while I'm at that, I might aswell just put the handle itsself into the entity to save some additional computation. The alternative would be to always pass around handles only and lookup the pointer every time, or to have a struct that holds both the handle and the looked-up pointer when working on it? Both seem slow/messy.
- I then realized, that I couldn't stop there: Some things I want to serialize are far from game objects, just data-containers with unknown size at compile time like a polygon. Refering to these with handles feels overkill and also would mean I'd have to add type and handle to these data structures aswell. And having 1 pool for every data type in my game seems kinda overkill too.
- I feel like I have gone too far down the rabbit hole. Maybe I should just use a general-purpose-allocator that can iterate over it's data for serialization? Maybe I should completly eliminate inheritance/struct-inclusion in my game objects in favor of a component system so there are no Generic/Polymorphic handles? Or create a base class, that holds the actual type and handle and derive every serializable data structure from that? Since I endorse Data oriented design, I try to avoid features like virtual functions, but at that point, it feels like I would just reeimplement them.
- I feel like I have a fundamental oversight here and hope that you can shed some light into how these problems are usually overcome in games.
- Thanks for reading!
RAW Paste Data