nux-0.9.46
|
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