Page 1 of 1

COffscreenContext help?

Posted: Wed Jul 17, 2019 2:59 pm
by howardantares
I am updating our software to the latest VST2 SDK and VSTGUI, and have a question on how to use the newer SharedPointer that is returned from COffscreenContext::create(). The docs told me this:

COffscreenContext::create returns a SharedPointer<COffscreenContext> now, not a naked pointer.

But I don't know what I am supposed to do with a SharedPointer, as opposed to simply storing the COffscreenContext* that was returned previously. What do I declare as my class member, and how do I use it later? Do I just declare my member as SharedPointer<COffscreenContext> instead of COffscreenContext*? And if I need to pass it around to existing functions that expect a COffscreen*, how do I do that?

And how do I dispose of it? Previously, I called forget() on the pointer and then set it to NULL, so that I could test its existence later, to be sure I didn't use it or dispose of it again.

I don't see any explanations about this in the SharedPointer documentation or header file. I am getting crashes when trying to store and use the raw pointer, so I assume this is the problem.

Re: COffscreenContext help?

Posted: Thu Jul 18, 2019 1:26 pm
by pongasoft
I am not an expert, but what I have done in my code is to pass the raw pointer around and store the shared pointer.

Example (from Jamba https://github.com/pongasoft/jamba/blob ... View.h#L89)

Code: Select all

// with these types
using BitmapPtr = CBitmap *;
using BitmapSPtr = SharedPointer<CBitmap>;

// From header
// getter/setter
  BitmapPtr getImage() const { return fImage; }
  void setImage(BitmapPtr iImage) { fImage = iImage; }

// member
  BitmapSPtr fImage{nullptr};
  
// usage
  if(fImage)
  {
    int frameIndex;
    CCoord frameHeight = fImage->getHeight() / getFrames();
    if(getFrames() == 4)
    {
      frameIndex = on ? 2 : 0;
      if(fPressed)
        frameIndex++;
    }
    else
    {
      frameIndex = on ? 1 : 0;
    }

    fImage->draw(iContext, getViewSize(), CPoint{0, frameIndex * frameHeight});
  }

In VSTGUI, the raw pointer (CBitmap *) actually already contains the reference count and SharedPointer<CBitmap> is only a wrapper that increments/decrements it automatically and you use it like a normal pointer. I am not sure why VSTGUI reinvented the wheel since C++ (since C++11) already offer the concepts of shared and unique pointers...

So in your case, since the method you call returns a SharedPointer you should just store a SharedPointer and use it like you would a regular pointer but DO NOT call forget or remember or whatever pointer lifecycle management method on it since that is what SharedPointer is doing.

The only advantage I see for SharedPointer vs std::shared is that because the class itself (in this example CBitmap) contains the reference counter, you can pass the raw pointer around since the reference counter will obviously be passed around with the instance. And then if you assign it to a SharedPointer, then it will get incremented (and obviously decremented when it gets out of scope), which is exactly what happens in the setter in the example above (receiving a CBitmap * and assigning it to a SharedPointer<CBitmap>). That would be impossible to do with std::shared.

Yan

Yan

Re: COffscreenContext help?

Posted: Thu Jul 18, 2019 8:32 pm
by howardantares
Thanks, that's what I was kind of hoping!

Re: COffscreenContext help?

Posted: Thu Aug 01, 2019 7:35 pm
by Arne Scheffler
The SharedPointer is like the std::shared_ptr. A way to control the live-cycle of the embedded object. At the time the first parts of VSTGUI were written there was no std::shared_ptr one could use. So the reference count was embedded into the base class. So with this change, you now store the SharedPointer<COffscreenContext> instead of COffscreenContext* and you never call forget or remember on it. If you want to get rid of it, just set the SharedPointer to nullptr and the object will automatically be destroyed if the reference count drops to zero.