/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

// Author: Andrei.Gheata@cern.ch  29/05/2013
// Following proposal by Markus Frank

#ifndef ROOT_TGeoExtension
#define ROOT_TGeoExtension

#include "TObject.h"

class TGeoExtension : public TObject {
protected:
   TGeoExtension() : TObject() {}
   ~TGeoExtension() override {}

public:
   // Method called whenever requiring a pointer to the extension
   // Equivalent to new()
   virtual TGeoExtension *Grab() = 0;
   // Method called always when the pointer to the extension is not needed
   // Equivalent to delete()
   virtual void Release() const = 0;

   ClassDefOverride(TGeoExtension, 1) // User extension for volumes and nodes
};

class TGeoRCExtension : public TGeoExtension {
protected:
   ~TGeoRCExtension() override { delete fUserObject; }

public:
   TGeoRCExtension() : TGeoExtension(), fRC(0), fUserObject(nullptr) { fRC++; }
   TGeoRCExtension(TObject *obj) : TGeoExtension(), fRC(0), fUserObject(obj) { fRC++; }

   TGeoExtension *Grab() override
   {
      fRC++;
      return this;
   }
   void Release() const override;

   void SetUserObject(TObject *obj) { fUserObject = obj; }
   TObject *GetUserObject() const { return fUserObject; }

private:
   // Copy constructor and assignment not allowed
   TGeoRCExtension(const TGeoRCExtension &) = delete;
   TGeoRCExtension &operator=(const TGeoRCExtension &) = delete;
   mutable Int_t fRC{0};          // Reference counter
   TObject *fUserObject{nullptr}; // Attached user object

   ClassDefOverride(TGeoRCExtension, 1) // Reference counted extension for volumes and nodes
};

#endif
