Skip to main content
gamedev.net
🔒 Locked

Numeric IDs VS Pointers

Started by Darkor 11 replies 800+ views
Original Post
Darkor
Darkor
I have an entity system that works like this. Data that is shared are kept in the prototype classes, so all Goblins have the same max health and this is stored here in the Prototype class. Runtime entity objects store data that is different like current health. The thing is that the entity objects frequently have to check back with the prototype classes. And the current design is by using an ID to refer to it. This is unwieldly because at runtime, many checks have to be made to get the correct prototype. It would then be more efficient to use pointers of course, but there is the downside of bad pointers and stuff like that. The question then is what would be the best system to work this out.
Promit
Promit
You might want to look into class factories, that will probably help quite a bit.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
sark
sark
The pointer will only go "bad" if you make it "bad". Just have your Goblin class constructor take a pointer/reference to the GoblinInformation (or whatever) object and leave it at that.
RonHiler
RonHiler
quote:

The pointer will only go "bad" if you make it "bad".


Not necessarily true. I'm running into the exact same sort of situations. I have "items" (things players can pick up) which have both a generic and specific index, and I'm finding I often have to "look up" a generic index from an ID value in the specific item list, which requires a linear search through the generic item list. I'm thinking about sorting the generic item list so I can do a better search, like a binary or something.

Anyway, I can't use pointers, because my item lists are dynamic sized, and are constantly changing in both content and number of entries. Therefore I used vectors, and as we all know, vectors entries can and do move around in memory as the list grows/shrinks, totally wrecking any pointers you may have into particular entries. However, vectors are what I intend to keep using (there are just too many advantanges to vectors that outweigh the loss of pointer functionality).

But I also would be pretty interested in other options, as long as I get to keep my vectors

[edited by - RonHiler on December 27, 2003 5:53:26 PM]
Creation is an act of sheer will
guywithknife
guywithknife
I dunno, I''ve always kept a vector of pointers.
Rather than storing the actual items in the vector, I merely store a pointer to the item. This way I have a pointer from which I can free items but if I need to store the pointer elsewhere, I can without the risk of the vector changing where it should point to.

Its always worked fine, unless I misunderstood whats been said.
sark
sark
quote:
Original post by RonHiler
I''m running into the exact same sort of situations. I have "items" (things players can pick up) which have both a generic and specific index, and I''m finding I often have to "look up" a generic index from an ID value in the specific item list, which requires a linear search through the generic item list. I''m thinking about sorting the generic item list so I can do a better search, like a binary or something.



Use a hash table then, or store by vector index. Tis an O(1) to look stuff up both of those ways.

quote:

Anyway, I can''t use pointers, because my item lists are dynamic sized, and are constantly changing in both content and number of entries. Therefore I used vectors, and as we all know, vectors entries can and do move around in memory as the list grows/shrinks, totally wrecking any pointers you may have into particular entries. However, vectors are what I intend to keep using (there are just too many advantanges to vectors that outweigh the loss of pointer functionality).



Well in that case don''t let std::vector allocate the memory for you. What I would suggest is you allocate each generic object once, and store reference-counted smart pointers to them in a vector. Then each specific object can receive the smart pointer to it''s associated generic object on creation. These specific objects can then be popped into a list of items owned by the player or whatever. I can illustrate with some code if you like.
Polymorphic OOP
Polymorphic OOP
quote:
Original post by RonHiler
Therefore I used vectors, and as we all know, vectors entries can and do move around in memory as the list grows/shrinks, totally wrecking any pointers you may have into particular entries. However, vectors are what I intend to keep using (there are just too many advantanges to vectors that outweigh the loss of pointer functionality).


If you need to preserve your iterators after deletion of other elements in the middle of the container, then just use std::list instead of std::vector.
Darkor
Darkor
Hey back to the main topic? =p So I take it that using pointers are best? I''ve just applied the changes to the codes and so far there''s been no problems.

Also I was thinking of how to protect these pointers. So that client programmers cannot delete it. I thought of using const to fix that, but it didn''t work.

Anyway I store pointers in vectors/lists.
sark
sark
quote:
Original post by Darkor
Also I was thinking of how to protect these pointers. So that client programmers cannot delete it.


Your client programmers should know not to delete things they didn''t new themselves in the first place. Anyway, you could use smart pointers, as suggested in my above post, or say "dont delete these pointers" in your documentation.
RonHiler
RonHiler
quote:
Original post by Darkor
Hey back to the main topic? =p So I take it that using pointers are best? I've just applied the changes to the codes and so far there's been no problems.


If your Generic items (what you are calling the prototype) is a static number of objects (or if they don't change much) and you can use the regular old new/delete commands to allocate them, then you can store pointers to them however you like. Once you new them, they aren't going anywhere in memory until they are deleted. Store your pointers in vectors or lists or whatever. That's exactly what I would do if my generic items list was pretty static.

What you *can't* do is store a pointer *to* a vector element, because vector elements move in memory. In my case, my generic (prototype) list is just as dynamic as my specific (entity) list. Therefore I've stuck both lists in vectors, and I can't use a pointer in either direction.

As for protecting it, if you client programmers are deleting things they didn't new, they're not particularly good programmers. You could always stick a comment at the pointer declaration saying "leave this alone!!!"

quote:
Original post by sark
Well in that case don't let std::vector allocate the memory for you. What I would suggest is you allocate each generic object once...

Can't My generic item lists are dynamic for a reason. This is a multiplayer game, and all item data (both specific and generic) lives on a server database. It would be an extrodinarily major waste of bandwidth to transmit the *entire* generic list to every client when typically each client is only using a fraction of the list at any given time (not to mention a potential cheat opening). All the clients only get generic item data elements upon request. Also if the specific item reference count drops to 0 and stays there for more than 5 minutes, the generic item data is erased. Thus, my client item generic lists are quite dynamic, they can grow and shrink nearly as much as the specific item lists, and therefore I have them in vectors.

Poly, I'll play around with the list container as an alternative to vector, thanks for the suggestion. I was under the impression that all the container type elements move around, though. Are you sure that's safe? Or did I misunderstand what you said?

[edited by - RonHiler on December 28, 2003 4:21:47 PM]
Creation is an act of sheer will
Ilici
Ilici
Use Indexes if you''re using STL vectors. I had lots of problems with pointers because the vector kept deallocating and allocating again the data in it and the pointers changed.
Bad Monkey
Bad Monkey
Just out of curiousity... why don''t you just define these shared attributes statically for the class? No need for every object to store a pointer to sme other shared object at all as far as I can see...
Darkor
Darkor
BadMonkey: Someone gave that suggestion once and the thing is that it''s not as flexible as the other approach, since you can create two instances of the prototype with minimal changes. In a statically-shared class, you have to create a new class.

Anyway, my project also follows the practice of deleting what you create. I didn''t know that STL vectors shift their memory around, but I use lists anyway, so it''s quite a bit of luck I didn''t use vectors.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.