Skip to main content
GameDev.net gamedev.net
🔒 Locked

std vectors and data sharing. or something.

Started by Specchum Mar 13, 2007 at 6:22 AM 6 replies 1.2k views
Original Post
Specchum
Specchum
Right. So i have this class for animation that has a vector of keyframes in it. Each skinned mesh has it's own animation instance. Now, I was wondering, given 2 skinned meshes that have the same hierarchy (and perhaps vertices) I should be able to use the same animation data for both meshes. Basically this means I should be able to load 2 meshes, and reuse the same animation data for both. Yes? Ok, so my problem is this then. The animation data (ie keyframes) is stored in the vector within the animation class. If I clone the animation class, I want some properties to be copied (easy enough) and the keyframe data in the vector to be shared for both the meshes. How do I do this? I suppose some code will clear up what I'm trying to do:

class animation
{
assorted data etc...
std::vector<keyframes> kfList;

//the clone function
animation* Clone()
{
  animation* anim = new animation(); 

  //the below is what I want to achieve but not sure how to do it for a vector
  anim->kfList = this->kfList; //share the kf data though thru reference
  return anim;
}
};

Other consideration aside (like ownership issues etc), is there some way to do this or should I just go back and use an array for kf to pull it off?
"There is no dark side of the moon." - Pink Floyd
Evil Steve
Evil Steve
You should store a pointer to the vector, or better - a smart pointer. std::vector will reallocate (duplicate) the memory if you just assign it like you're doing. To share that memory, you'll need to keep a pointer to the vector, and then worry about the ownership (Which a smart pointer should fix).
Zahlman
Zahlman
As a side note, whenever you are implementing the virtual clone idiom, you normally are in a situation where the rule of 3 applies (i.e. you need a copy constructor, assignment operator and destructor). Therefore, since the clone() is supposed to make a copy of the current object, the normal way is to reuse the code of the copy constructor.

typedef boost::shared_ptr<std::vector<keyframe> > kf_buffer;class animation {  kf_buffer keyframes;  // Although, because of the shared_ptr, you suddenly *don't* need the  // Rule of Three any more - i.e. the default versions will be fine - unless  // some other member of the class requires it.  // The copy constructor - invoked implicitly from here :) - will just call the  // copy constructors of the other members, including the shared_ptr's cctor -  // which will cause the clone to refer to the same buffer, and increment the  // reference count.  animation* clone() { return new animation(*this); }  // Actually, you might need to use enable_shared_from_this for that to work...  // I don't really know the details of that part :s};
Specchum
Specchum
Evile Steve > Pointer to the vector. Well I did try that before I posted but must have done something wrong 'cos it didn't look like it was sharing the data. I say "look like" 'cos I was using the task manager to watch the memory allocation. :D Now that I know it will work, I'll just go about doing it right.

ToohrVyk> The flyweight pattern is indeed what I actually need. I'll probably switch to that when I get some parts of the system up and running.

Zahlman> The boost shared_ptr does look like the magic wand I was looking for. :) Unfortunately, I'm not using boost since erm... I just can't get my head around some of the stuff and am wary of using it in an improper fashion. Perhaps in due course, with perserverance, I will get around to using it. :)

Thanks all for your inputs. Much appreciated! Cheers!
"There is no dark side of the moon." - Pink Floyd
Zahlman
Zahlman
Quote:
Original post by Specchum
Zahlman> The boost shared_ptr does look like the magic wand I was looking for. :) Unfortunately, I'm not using boost since erm... I just can't get my head around some of the stuff and am wary of using it in an improper fashion. Perhaps in due course, with perserverance, I will get around to using it. :)


Relax... Boost is (a) pretty fully documented, and (b) not all-or-nothing, not at all... you should be able to grab just the shared_ptr stuff fairly easily. As for "using it improperly", what exactly do you worry might go wrong? :) (Also, this stuff normally has full source code available, so you can at minimum see how they do things and learn from it.)
Specchum
Specchum
Quote:
Original post by Zahlman
As for "using it improperly", what exactly do you worry might go wrong?


Well many moons ago when I was writing a 2d tile engine using SDL, I used boosts shared_ptr implementation almost exclusively. Everything worked well enough but unfortunately it appears that the app didn't quit properly because of a leaked resource with SDL (probably a SDL_Surface reference). I never did figure out what the problem was partly because I wasn't sure I'd understood shared_ptr too well and partly because despite extensive debugging I couldn't pin down the problem to a specific module.

In hindsight, I should have understood the pros and cons of shared_ptr better and probably checked out other ptr alternatives in boost before deciding that shared_ptr would suffice for all my needs.

Anyhow, I'm reading up on shared_ptrs again now and if I can plug it in my project without reworking too much of the code, I will do so. Cheers!
"There is no dark side of the moon." - Pink Floyd
Zakwayda
Zakwayda
Quote:
Original post by Specchum
Well many moons ago when I was writing a 2d tile engine using SDL, I used boosts shared_ptr implementation almost exclusively. Everything worked well enough but unfortunately it appears that the app didn't quit properly because of a leaked resource with SDL (probably a SDL_Surface reference). I never did figure out what the problem was partly because I wasn't sure I'd understood shared_ptr too well and partly because despite extensive debugging I couldn't pin down the problem to a specific module.
Naive usage of shared_ptr to store pointers to SDL resources will most likely lead to trouble. If this is what you were doing, the errors were probably to be expected.

In normal usage, shared_ptr stores a pointer to an object created via new. When the last shared_ptr referencing the object is destroyed, the object itself is destroyed via delete.

Most (perhaps all) SDL resources are allocated via malloc() or a variant thereof. For each resource type there is a corresponding 'free' function that calls free() (or a variant) on the pointer, and in some cases performs additional cleanup as well. Invoking delete on such a pointer is not correct, and was likely the cause of the problems you encountered.

If you do wish to use shared_ptr to store SDL resources, you can use the 'custom deleter' feature to tie deletion of the resource to the appropriate SDL function (I haven't tried this myself, but I can't think why it wouldn't work). A quick Google search turns up this thread, which appears to include an example of how to do this.

Topic Locked

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

Sign in to reply to this topic.