nux-0.9.46

NuxCore/Object.h

Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #ifndef NUXOBJECT_H
00024 #define NUXOBJECT_H
00025 
00026 #include <sigc++/trackable.h>
00027 #include <sigc++/signal.h>
00028 
00029 namespace nux
00030 {
00031 
00032   template <typename T>
00033   class ObjectPtr;
00034 
00035   template <typename T>
00036   class ObjectWeakPtr;
00037 
00038 // #if defined(NUX_DEBUG)
00039 #define NUX_FILE_LINE_PROTO     const char* __Nux_FileName__=__FILE__, int __Nux_LineNumber__ = __LINE__
00040 #define NUX_FILE_LINE_DECL      const char* __Nux_FileName__, int __Nux_LineNumber__
00041 #define NUX_FILE_LINE_PARAM     __Nux_FileName__, __Nux_LineNumber__
00042 #define NUX_TRACKER_LOCATION    __FILE__, __LINE__
00043 // #else
00044 //     #define NUX_FILE_LINE_PROTO     int __Nux_Dummy__ = 0xD0DECADE
00045 //     #define NUX_FILE_LINE_DECL      int __Nux_Dummy__
00046 //     #define NUX_FILE_LINE_PARAM     __Nux_Dummy__
00047 //     #define NUX_TRACKER_LOCATION    0xD0DECADE
00048 // #endif
00049 
00050   class ObjectStats
00051   {
00052     NUX_DECLARE_GLOBAL_OBJECT (ObjectStats, GlobalSingletonInitializer);
00053   public:
00054     class AllocationList : public std::list<void *>
00055     {
00056     public:
00057       AllocationList();
00058       ~AllocationList();
00059     };
00060 
00061     AllocationList _allocation_list;
00062     int _total_allocated_size;  
00063     int _number_of_objects;     
00064   };
00065 #define GObjectStats NUX_GLOBAL_OBJECT_INSTANCE(nux::ObjectStats)
00066 
00068 
00072   class Trackable : public sigc::trackable
00073   {
00074   public:
00075     NUX_DECLARE_ROOT_OBJECT_TYPE (Trackable);
00077     /*
00078         @return True if the object reference is owned.
00079     */
00080     bool OwnsTheReference();
00081 
00083     /*
00084         @return True if the object was allocated dynamically.
00085     */
00086     bool IsHeapAllocated();
00087 
00089     /*
00090         @return True if the object was allocated dynamically.
00091     */
00092     bool IsDynamic() const;
00093 
00094 
00096     /*
00097         Widget are typically created and added to containers. It is decided that when widgets are created, they should have a floating reference
00098         and their reference count is set to 1.
00099         {
00100             Button* button = new Button();  // button ref_cout = 1, floating = true;
00101             container->AddButton(button);   // button has a floating reference; when container call button->ref() the ref count
00102                                             // of button remains at 1 but the floating reference is set to false. From now on,
00103                                             // calling button->ref will always increase the ref count (since button no longer has a floating reference).
00104         }
00105 
00106         It is best to pair calls to ref() with unref() when it comes to widgets. So if a widget was not added to a container and so it still has a
00107         floating reference, then call Dispose(). Dispose does some sanity check; it verifies that:
00108              ref_count == 1
00109              floating == true
00110         If these conditions are verified, dispose will cause the object to be destroyed.
00111         Calling unref() on an object that has a floating reference will trigger a warning/error in order to invite the
00112         developer. The developer can either ref the object first before calling unref or simply not create the widget since it
00113         does not appear to have been used.
00114 
00115         During development it often happen that one forget to dispose an object with a floating reference.
00116         Assuming that all functions that receive a reference counted object properly call ref on the object and that the compiler
00117         can detect unused variables, then the developer should have a way to detect reference counted objects that are not owned.
00118         It is up to the developer to properly handle these objects.
00119 
00120         @return True if the object has been referenced.
00121     */
00122     virtual bool Reference();
00123 
00125 
00128     virtual bool UnReference();
00129 
00131 
00134     virtual bool SinkReference();
00135 
00137 
00141     virtual bool Dispose();
00142 
00144 
00147     virtual int GetObjectSize ();
00148 
00149     static std::new_handler set_new_handler (std::new_handler handler);
00150     static void *operator new (size_t size);
00151 
00152 #if (__GNUC__ < 4 && __GNUC_MINOR__ < 4)
00153     static void *operator new (size_t size, void *ptr);
00154 #endif
00155 
00156     static void operator delete (void *ptr);
00157 
00158   protected:
00159     Trackable();
00160     virtual ~Trackable() = 0;
00161     void SetOwnedReference (bool b);
00162     int _heap_allocated;
00163 
00164   private:
00165     Trackable (const Trackable &);
00166     Trackable &operator= (const Trackable &);
00167 
00168 //     class AllocationList : public std::list<void *>
00169 //     {
00170 //     public:
00171 //       AllocationList();
00172 //       ~AllocationList();
00173 //     };
00174 
00175     //static AllocationList m_allocation_list;
00176     static std::new_handler _new_current_handler;
00177 //     static int m_total_allocated_size;  //! Total allocated memory size in bytes.
00178 //     static int m_number_of_objects;     //! Number of allocated objects;
00179 
00180     bool _owns_the_reference;
00181     int _size_of_this_object;
00182 
00183     //template<typename T> friend class Pointer;
00184   };
00185 
00187   class Object: public Trackable
00188   {
00189   public:
00190     NUX_DECLARE_OBJECT_TYPE (BaseObject, Trackable);
00191 
00193     Object (bool OwnTheReference = true, NUX_FILE_LINE_PROTO);
00195 
00198     bool Reference();
00199 
00201 
00204     bool UnReference();
00205 
00207 
00210     virtual bool SinkReference();
00211 
00213 
00217     virtual bool Dispose();
00218 
00220 
00223     int GetReferenceCount () const;
00224 
00226 
00229     int GetWeakReferenceCount () const;
00230 
00232     sigc::signal <void, Object *> OnDestroyed;
00233 
00234   protected:
00235     NThreadSafeCounter *_reference_count; 
00236     NThreadSafeCounter *_weak_reference_count; 
00237     NThreadSafeCounter *_objectptr_count; 
00238 
00247     bool *_destroyed;
00248 
00250     /*
00251         Private destructor. Ensure that Object cannot be created on the stack (only on the heap), but objects that inherits
00252         from Object can stil be created on the stack or on the heap.
00253         (MEC++ item27)
00254     */
00255     virtual ~Object();
00256 
00257     void IncrementWeakCounter();
00258     void DecrementWeakCounter();
00259 
00260   private:
00262     void Destroy();
00263 
00264     Object (const Object &);
00265     Object &operator = (const Object &);
00266 
00267 
00268 //#if defined(NUX_DEBUG)
00269     NString _allocation_file_name;
00270     int     _allocation_line_number;
00271 //#endif
00272 
00273     template <typename T>
00274     friend class ObjectPtr;
00275 
00276     template <typename T>
00277     friend class ObjectWeakPtr;
00278     friend class ObjectStats;
00279   };
00280 
00281 }
00282 
00283 #endif // NUXOBJECT_H
00284