Author Topic: PCL: What is the meaning of "Class Wide Ownership" in ImageVariant?  (Read 4015 times)

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
The documentation of ImageVariant http://pixinsight.com/developer/pcl/doc/html/classpcl_1_1ImageVariant.html#details states "It is important to know that ownership of transported images is a class-wide property of ImageVariant, not a private property of any particular ImageVariant instance". I have no idea what this is supposed to mean. Methods like SetOwnership() http://pixinsight.com/developer/pcl/doc/html/classpcl_1_1ImageVariant.html#a20fe3012f4672c7da9c01407c8740f19 suggest it is an instance wide property (which also would make more sense).

Juan, I am sure you had something in mind when you wrote this. Only, it does not reveal itself to me....

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Class-wide ownership means that an image is not owned only by a particular instance of ImageVariant, but by all existing instances that transport the same image.

In first place let's clarify the concept of image ownership in ImageVariant. Consider the following code snippets:

Code: [Select]
Image image;
ImageVariant var( &image );
// ImageVariant does not own image

Code: [Select]
ImageVariant var;
var.CreateFloatImage();
// ImageVariant owns a newly created image

In the first case, you have an image and create an ImageVariant to transport it. When the var object gets out of scope, image will continue existing and won't be destroyed.

In the second case, you have an ImageVariant and tell it to create a new image (a 32-bit floating point image in the example). The newly created image will be transported by var and is now owned by ImageVariant.

You can also switch on and off ImageVariant's ownership:

Code: [Select]
Image* image = new Image;
ImageVariant var( image );
var.SetOwnership( true );
// now ImageVariant owns image

(Of course, don't do that for images allocated in the stack as automatic variables, or your module will crash for sure).

Now let's put a few examples to describe class-wide ownership.

Code: [Select]
Console console;
ImageVariant var;
console << bool( var ) << '\n'; // writes 'false' to the console
{
   ImageVariant tmp;
   tmp.CreateFloatImage();
   var = tmp;
}
console << bool( var ) << '\n'; // writes 'true' to the console
console << var.OwnsImage() << '\n'; // also writes 'true'

In this example I'm using "ImageVariant::operator bool() const" (PCL 2.0), which returns true if the ImageVariant transports an image. The tmp object creates a new image, which is owned by default. Then we force var to transport the same image. When tmp gets out of scope the image is not destroyed, since it is still being transported by one or more ImageVariant instances (var in this case). If instead of class-wide ownership we had instance ownership, the image would be destroyed by tmp at the end of the block, and var would be left in an invalid state.

You may argue that this is how implicit data sharing works, so there's nothing really special here. But note that ImageVariant implements an explicit data sharing mechanism, which makes it different from the rest of container classes in PCL. It is important to state clearly that ownership of image data is not a property of any particular object in this case, but of the whole ImageVariant class.

As you know PCL allows you to work transparently with two types of images: local and shared images. Local images allocate their data in the calling module's heap. Shared images live in the PixInsight Core application, and the client-side GenericImage objects are just managed aliases. Image ownership and the associated explicit data sharing mechanism in ImageVariant work equally for local and shared images. For shared images, however, ImageVariant's ownership extends beyond the calling module and includes also all ImageVariant instances in the core application. This is why you can access an image in a View object, and when your View instances are destroyed the corresponding (shared) images are not destroyed.

Hope this clarifies.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline georg.viehoever

  • PTeam Member
  • PixInsight Jedi Master
  • ******
  • Posts: 2132
Juan,

thanks for the explanation. I think that "Class-wide ownership" is a rather unfortunate term for this. Class-wide in my opinion suggests that all instances of the class share ownership (such as static methods or variables are shared by all instances of a class), which is not what you do. Apparently, ownership is only shared by all instances of ImageVariant if they represent the same image.

As I understand it now it is probably better described by stating that ownership of an image is always the same for all ImageVariant instances that represent the same image. If you switch ownership off/on for one ImageVariant instance that represents the image, you change ownership also for all other ImageVariant instances that represent the same image. When you change the ownership by calling imageVariantInstance.SetOwnership(), you really change a property of the image, not of the ImageVariants that represent it.

This is indeed different from the shared ownership concept of -for instance- smart pointers such as boost::shared_ptr. Here shared ownership is a property of a shared_ptr instance. shared_ptr instances that are created as copies of each other indeed share ownership of the object they point to. But it is perfectly possible to create several shared_ptr instances that point to the same object but dont share ownership- which causes rather interesting bugs.

Georg
Georg (6 inch Newton, unmodified Canon EOS40D+80D, unguided EQ5 mount)