]> git.saurik.com Git - wxWidgets.git/blobdiff - interface/wx/object.h
Remove wxDataViewTextRendererAttr by merging it with wxDataViewTextRenderer.
[wxWidgets.git] / interface / wx / object.h
index 6a7ff2de521b72b17c0c674072456b2cd944346a..787e5f7a135c62644a81b8ee9856a0ce2c2205b8 100644 (file)
@@ -1,25 +1,30 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        object.h
 /////////////////////////////////////////////////////////////////////////////
 // Name:        object.h
-// Purpose:     interface of wxObjectRefData
+// Purpose:     interface of wxRefCounter
 // Author:      wxWidgets team
 // RCS-ID:      $Id$
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
 // Author:      wxWidgets team
 // RCS-ID:      $Id$
 // Licence:     wxWindows license
 /////////////////////////////////////////////////////////////////////////////
 
-/**
-    @class wxObjectRefData
+/** @class wxObjectRefData
+
+    This class is just a typedef to wxRefCounter and is used by wxObject.
 
 
-    This class is used to store reference-counted data.
+    Derive classes from this to store your own data in wxObject-derived
+    classes. When retrieving information from a wxObject's reference data,
+    you will need to cast to your own derived class.
 
 
-    Derive classes from this to store your own data. When retrieving information
-    from a wxObject's reference data, you will need to cast to your own derived class.
+    Below is an example illustrating how to store reference counted
+    data in a class derived from wxObject including copy-on-write
+    semantics.
 
 
-    @b Example:
+    @section objectrefdata_example Example
 
     @code
     // include file
 
     @code
     // include file
+    // ------------
 
 
-    class MyCar: public wxObject
+    class MyCar : public wxObject
     {
     public:
         MyCar() { }
     {
     public:
         MyCar() { }
 
 
     // implementation
 
 
     // implementation
+    // --------------
 
 
-    class MyCarRefData: public wxObjectRefData
+    // the reference data class is typically a private class only visible in the
+    // implementation source file of the refcounted class.
+    class MyCarRefData : public wxObjectRefData
     {
     public:
         MyCarRefData()
     {
     public:
         MyCarRefData()
@@ -54,6 +62,9 @@
         MyCarRefData( const MyCarRefData& data )
             : wxObjectRefData()
         {
         MyCarRefData( const MyCarRefData& data )
             : wxObjectRefData()
         {
+            // copy refcounted data; this is usually a time- and memory-consuming operation
+            // and is only done when two (or more) MyCar instances need to unshare a
+            // common instance of MyCarRefData
             m_price = data.m_price;
         }
 
             m_price = data.m_price;
         }
 
             return m_price == data.m_price;
         }
 
             return m_price == data.m_price;
         }
 
+    private:
+        // in real world, reference counting is usually used only when
+        // the wxObjectRefData-derived class holds data very memory-consuming;
+        // in this example the various MyCar instances may share a MyCarRefData
+        // instance which however only takes 4 bytes for this integer!
         int m_price;
     };
 
 
     #define M_CARDATA ((MyCarRefData *)m_refData)
         int m_price;
     };
 
 
     #define M_CARDATA ((MyCarRefData *)m_refData)
-
     IMPLEMENT_DYNAMIC_CLASS(MyCar,wxObject)
 
     MyCar::MyCar( int price )
     {
     IMPLEMENT_DYNAMIC_CLASS(MyCar,wxObject)
 
     MyCar::MyCar( int price )
     {
+        // here we init the MyCar internal data:
         m_refData = new MyCarRefData();
         M_CARDATA->m_price = price;
     }
         m_refData = new MyCarRefData();
         M_CARDATA->m_price = price;
     }
 
     bool MyCar::operator == ( const MyCar& car ) const
     {
 
     bool MyCar::operator == ( const MyCar& car ) const
     {
-        if (m_refData == car.m_refData) return true;
-
-        if (!m_refData || !car.m_refData) return false;
-
+        if (m_refData == car.m_refData)
+            return true;
+        if (!m_refData || !car.m_refData)
+            return false;
+
+        // here we use the MyCarRefData::operator==() function.
+        // Note however that this comparison may be very slow if the
+        // reference data contains a lot of data to be compared.
         return ( *(MyCarRefData*)m_refData == *(MyCarRefData*)car.m_refData );
     }
 
     void MyCar::SetPrice( int price )
     {
         return ( *(MyCarRefData*)m_refData == *(MyCarRefData*)car.m_refData );
     }
 
     void MyCar::SetPrice( int price )
     {
+        // since this function modifies one of the MyCar internal property,
+        // we need to be sure that the other MyCar instances which share the
+        // same MyCarRefData instance are not affected by this call.
+        // I.e. it's very important to call UnShare() in all setters of
+        // refcounted classes!
         UnShare();
 
         M_CARDATA->m_price = price;
         UnShare();
 
         M_CARDATA->m_price = price;
     {
         wxCHECK_MSG( IsOk(), -1, "invalid car" );
 
     {
         wxCHECK_MSG( IsOk(), -1, "invalid car" );
 
-        return (M_CARDATA->m_price);
+        return M_CARDATA->m_price;
     }
     @endcode
 
     }
     @endcode
 
 
     @see wxObject, wxObjectDataPtr<T>, @ref overview_refcount
 */
 
     @see wxObject, wxObjectDataPtr<T>, @ref overview_refcount
 */
-class wxObjectRefData
+typedef wxRefCounter wxObjectRefData;
+
+
+/**
+    @class wxRefCounter
+
+    This class is used to manage reference-counting providing a simple
+    interface and a counter. wxRefCounter can be easily used together
+    with wxObjectDataPtr<T> to ensure that no calls to wxRefCounter::DecRef()
+    are missed - thus avoiding memory leaks.
+
+    wxObjectRefData is a typedef to wxRefCounter and is used as the
+    built-in reference counted storage for wxObject-derived classes.
+
+    @library{wxbase}
+    @category{rtti}
+
+    @see wxObject, wxObjectRefData, wxObjectDataPtr<T>, @ref overview_refcount
+*/
+class wxRefCounter
 {
 protected:
     /**
         Destructor.
 
 {
 protected:
     /**
         Destructor.
 
-        It's declared @c protected so that wxObjectRefData instances
+        It's declared @c protected so that wxRefCounter instances
         will never be destroyed directly but only as result of a DecRef() call.
     */
         will never be destroyed directly but only as result of a DecRef() call.
     */
-    ~wxObjectRefData();
+    virtual ~wxRefCounter();
 
 public:
     /**
         Default constructor. Initialises the internal reference count to 1.
     */
 
 public:
     /**
         Default constructor. Initialises the internal reference count to 1.
     */
-    wxObjectRefData();
+    wxRefCounter();
 
     /**
         Decrements the reference count associated with this shared data and, if
 
     /**
         Decrements the reference count associated with this shared data and, if
-        it reaches zero, destroys this instance of wxObjectRefData releasing its
+        it reaches zero, destroys this instance of wxRefCounter releasing its
         memory.
 
         Please note that after calling this function, the caller should
         memory.
 
         Please note that after calling this function, the caller should
@@ -177,24 +221,33 @@ public:
     wxObject can be used to implement @ref overview_refcount "reference counted"
     objects, such as wxPen, wxBitmap and others
     (see @ref overview_refcount_list "this list").
     wxObject can be used to implement @ref overview_refcount "reference counted"
     objects, such as wxPen, wxBitmap and others
     (see @ref overview_refcount_list "this list").
+    See wxRefCounter and @ref overview_refcount for more info about
+    reference counting.
 
     @library{wxbase}
     @category{rtti}
 
 
     @library{wxbase}
     @category{rtti}
 
-    @see wxClassInfo, @ref overview_debugging, wxObjectRefData
+    @see wxClassInfo, @ref overview_debugging, @ref overview_refcount,
+         wxObjectDataRef, wxObjectDataPtr<T>
 */
 class wxObject
 {
 public:
 
 */
 class wxObject
 {
 public:
 
+    /**
+        Default ctor; initializes to @NULL the internal reference data.
+    */
     wxObject();
 
     /**
         Copy ctor.
     wxObject();
 
     /**
         Copy ctor.
+
+        Sets the internal wxObject::m_refData pointer to point to the same
+        instance of the wxObjectRefData-derived class pointed by @c other and
+        increments the refcount of wxObject::m_refData.
     */
     wxObject(const wxObject& other);
 
     */
     wxObject(const wxObject& other);
 
-
     /**
         Destructor.
 
     /**
         Destructor.
 
@@ -202,25 +255,6 @@ public:
     */
     virtual ~wxObject();
 
     */
     virtual ~wxObject();
 
-    /**
-        A virtual function that may be redefined by derived classes to allow dumping of
-        memory states.
-
-        This function is only defined in debug build and exists only if @c __WXDEBUG__
-        is defined.
-
-        @param stream
-            Stream on which to output dump information.
-
-        @remarks Currently wxWidgets does not define Dump() for derived classes,
-                 but programmers may wish to use it for their own applications.
-                 Be sure to call the Dump member of the class's base class to allow all
-                 information to be dumped.
-                 The implementation of this function in wxObject just writes
-                 the class name of the object.
-    */
-    void Dump(ostream& stream);
-
     /**
         This virtual function is redefined for every class that requires run-time
         type information, when using the ::DECLARE_CLASS macro (or similar).
     /**
         This virtual function is redefined for every class that requires run-time
         type information, when using the ::DECLARE_CLASS macro (or similar).
@@ -298,11 +332,7 @@ public:
     void UnRef();
 
     /**
     void UnRef();
 
     /**
-        Ensure that this object's data is not shared with any other object.
-
-        If we have no data, it is created using CreateRefData() below,
-        if we have shared data, it is copied using CloneRefData(),
-        otherwise nothing is done.
+        This is the same of AllocExclusive() but this method is public.
     */
     void UnShare();
 
     */
     void UnShare();
 
@@ -323,13 +353,55 @@ public:
     void* operator new(size_t size, const wxString& filename = NULL, int lineNum = 0);
 
 protected:
     void* operator new(size_t size, const wxString& filename = NULL, int lineNum = 0);
 
 protected:
+    /**
+        Ensure that this object's data is not shared with any other object.
+
+        If we have no data, it is created using CreateRefData();
+        if we have shared data (i.e. data with a reference count greater than 1),
+        it is copied using CloneRefData(); otherwise nothing is done (the data
+        is already present and is not shared by other object instances).
+
+        If you use this function you should make sure that you override the
+        CreateRefData() and CloneRefData() functions in your class otherwise
+        an assertion will fail at runtime.
+    */
+    void AllocExclusive();
+
+    /**
+        Creates a new instance of the wxObjectRefData-derived class specific to
+        this object and returns it.
+
+        This is usually implemented as a one-line call:
+        @code
+        wxObjectRefData *MyObject::CreateRefData() const
+        {
+            return new MyObjectRefData;
+        }
+        @endcode
+    */
+    virtual wxObjectRefData *CreateRefData() const;
+
+    /**
+        Creates a new instance of the wxObjectRefData-derived class specific to
+        this object and initializes it copying @a data.
+
+        This is usually implemented as a one-line call:
+        @code
+        wxObjectRefData *MyObject::CloneRefData(const wxObjectRefData *data) const
+        {
+            // rely on the MyObjectRefData copy ctor:
+            return new MyObjectRefData(*(MyObjectRefData *)data);
+        }
+        @endcode
+    */
+    virtual wxObjectRefData *CloneRefData(const wxObjectRefData *data) const;
 
     /**
         Pointer to an object which is the object's reference-counted data.
 
         @see Ref(), UnRef(), SetRefData(), GetRefData(), wxObjectRefData
     */
 
     /**
         Pointer to an object which is the object's reference-counted data.
 
         @see Ref(), UnRef(), SetRefData(), GetRefData(), wxObjectRefData
     */
-    wxObjectRefData*  m_refData;
+    wxObjectRefData* m_refData;
 };
 
 
 };
 
 
@@ -373,34 +445,28 @@ public:
     /**
         Finds the wxClassInfo object for a class with the given @a name.
     */
     /**
         Finds the wxClassInfo object for a class with the given @a name.
     */
-    static wxClassInfo* FindClass(wxChar* name);
+    static wxClassInfo* FindClass(const wxString& className);
 
     /**
         Returns the name of the first base class (@NULL if none).
     */
 
     /**
         Returns the name of the first base class (@NULL if none).
     */
-    wxChar* GetBaseClassName1() const;
+    const wxChar* GetBaseClassName1() const;
 
     /**
         Returns the name of the second base class (@NULL if none).
     */
 
     /**
         Returns the name of the second base class (@NULL if none).
     */
-    wxChar* GetBaseClassName2() const;
+    const wxChar* GetBaseClassName2() const;
 
     /**
         Returns the string form of the class name.
     */
 
     /**
         Returns the string form of the class name.
     */
-    wxChar* GetClassName() const;
+    const wxChar* GetClassName() const;
 
     /**
         Returns the size of the class.
     */
     int GetSize() const;
 
 
     /**
         Returns the size of the class.
     */
     int GetSize() const;
 
-    /**
-        Initializes pointers in the wxClassInfo objects for fast execution of IsKindOf().
-        Called in base wxWidgets library initialization.
-    */
-    static void InitializeClasses();
-
     /**
         Returns @true if this class info can create objects of the associated class.
     */
     /**
         Returns @true if this class info can create objects of the associated class.
     */
@@ -409,41 +475,39 @@ public:
     /**
         Returns @true if this class is a kind of (inherits from) the given class.
     */
     /**
         Returns @true if this class is a kind of (inherits from) the given class.
     */
-    bool IsKindOf(wxClassInfo* info);
+    bool IsKindOf(const wxClassInfo* info) const;
 };
 
 
 
 /**
 
 };
 
 
 
 /**
 
-    This is helper template class primarily written to avoid memory leaks because of
-    missing calls to wxObjectRefData::DecRef().
+    This is an helper template class primarily written to avoid memory leaks because
+    of missing calls to wxRefCounter::DecRef() and wxObjectRefData::DecRef().
 
     Despite the name this template can actually be used as a smart pointer for any
     class implementing the reference counting interface which only consists of the two
     methods @b T::IncRef() and @b T::DecRef().
 
     The difference to wxSharedPtr<T> is that wxObjectDataPtr<T> relies on the reference
 
     Despite the name this template can actually be used as a smart pointer for any
     class implementing the reference counting interface which only consists of the two
     methods @b T::IncRef() and @b T::DecRef().
 
     The difference to wxSharedPtr<T> is that wxObjectDataPtr<T> relies on the reference
-    counting to be in the class pointed to where instead wxSharedPtr<T> implements the
+    counting to be in the class pointed to, where instead wxSharedPtr<T> implements the
     reference counting itself.
 
     reference counting itself.
 
+    Below is an example illustrating how to implement reference counted
+    data using wxRefCounter and wxObjectDataPtr<T> with copy-on-write
+    semantics.
 
 
-    @b Example:
+    @section objectdataptr_example Example
 
     @code
 
     @code
-    class MyCarRefData: public wxObjectRefData
+    class MyCarRefData: public wxRefCounter
     {
     public:
     {
     public:
-        MyCarRefData()  { m_price = 0; }
-
-        MyCarRefData( const MyCarRefData& data )
-            : wxObjectRefData()
-        {
-            m_price = data.m_price;
-        }
+        MyCarRefData( int price = 0 ) : m_price(price) { }
+        MyCarRefData( const MyCarRefData& data ) : m_price(data.m_price) { }
 
         void SetPrice( int price )  { m_price = price; }
 
         void SetPrice( int price )  { m_price = price; }
-        int GetPrice()              { return m_price; }
+        int GetPrice() const        { return m_price; }
 
     protected:
         int m_price;
 
     protected:
         int m_price;
@@ -452,27 +516,37 @@ public:
     class MyCar
     {
     public:
     class MyCar
     {
     public:
-        MyCar( int price ) : m_data( new MyCarRefData )
+        // initializes this MyCar assigning to the
+        // internal data pointer a new instance of MyCarRefData
+        MyCar( int price = 0 ) : m_data( new MyCarRefData(price) )
         {
         {
-            m_data->SetPrice( price );
         }
 
         MyCar& operator =( const MyCar& tocopy )
         {
         }
 
         MyCar& operator =( const MyCar& tocopy )
         {
+            // shallow copy: this is just a fast copy of pointers; the real
+            // memory-consuming data which typically is stored inside
+            // MyCarRefData is not copied here!
             m_data = tocopy.m_data;
             return *this;
         }
 
         bool operator == ( const MyCar& other ) const
         {
             m_data = tocopy.m_data;
             return *this;
         }
 
         bool operator == ( const MyCar& other ) const
         {
-            if (m_data.get() == other.m_data.get()) return true;
-            return (m_data->GetPrice() == other.m_data->GetPrice());
+            if (m_data.get() == other.m_data.get())
+                return true; // this instance and the 'other' one share the
+                             // same MyCarRefData data...
+
+            return (m_data.GetPrice() == other.m_data.GetPrice());
         }
 
         void SetPrice( int price )
         {
         }
 
         void SetPrice( int price )
         {
-           UnShare();
-           m_data->SetPrice( price );
+            // make sure changes to this class do not affect other instances
+            // currently sharing our same refcounted data:
+            UnShare();
+
+            m_data->SetPrice( price );
         }
 
         int GetPrice() const
         }
 
         int GetPrice() const
@@ -500,6 +574,7 @@ public:
     @see wxObject, wxObjectRefData, @ref overview_refcount, wxSharedPtr<T>,
          wxScopedPtr<T>, wxWeakRef<T>
 */
     @see wxObject, wxObjectRefData, @ref overview_refcount, wxSharedPtr<T>,
          wxScopedPtr<T>, wxWeakRef<T>
 */
+template <class T>
 class wxObjectDataPtr<T>
 {
 public:
 class wxObjectDataPtr<T>
 {
 public:
@@ -572,7 +647,7 @@ public:
 // Global functions/macros
 // ============================================================================
 
 // Global functions/macros
 // ============================================================================
 
-/** @ingroup group_funcmacro_rtti */
+/** @addtogroup group_funcmacro_rtti */
 //@{
 
 /**
 //@{
 
 /**
@@ -828,7 +903,7 @@ wxObject *wxCreateDynamicObject(const wxString& className);
 
 //@}
 
 
 //@}
 
-/** @ingroup group_funcmacro_debug */
+/** @addtogroup group_funcmacro_debug */
 //@{
 
 /**
 //@{
 
 /**