nux-1.16.0
|
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- 00002 /* 00003 * Copyright 2010-2011 Inalogic® Inc. 00004 * 00005 * This program is free software: you can redistribute it and/or modify it 00006 * under the terms of the GNU Lesser General Public License, as 00007 * published by the Free Software Foundation; either version 2.1 or 3.0 00008 * of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, but 00011 * WITHOUT ANY WARRANTY; without even the implied warranties of 00012 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00013 * PURPOSE. See the applicable version of the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of both the GNU Lesser General Public 00017 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00018 * 00019 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00020 * 00021 */ 00022 00023 00024 #ifndef NUXCORE_OBJECT_H 00025 #define NUXCORE_OBJECT_H 00026 00027 #include <sigc++/trackable.h> 00028 #include <sigc++/signal.h> 00029 #include "ObjectType.h" 00030 #include "Property.h" 00031 #include "PropertyTraits.h" 00032 00033 #define NUX_FILE_LINE_PROTO const char* __Nux_FileName__=__FILE__, int __Nux_LineNumber__ = __LINE__ 00034 #define NUX_FILE_LINE_DECL const char* __Nux_FileName__, int __Nux_LineNumber__ 00035 #define NUX_FILE_LINE_PARAM __Nux_FileName__, __Nux_LineNumber__ 00036 #define NUX_TRACKER_LOCATION __FILE__, __LINE__ 00037 00038 #define OnDestroyed object_destroyed 00039 00040 00041 namespace nux 00042 { 00043 template <typename T> 00044 class ObjectPtr; 00045 00046 template <typename T> 00047 class ObjectWeakPtr; 00048 00049 class ObjectStats 00050 { 00051 NUX_DECLARE_GLOBAL_OBJECT (ObjectStats, GlobalSingletonInitializer); 00052 public: 00053 typedef std::list<void*> AllocationList; 00054 AllocationList _allocation_list; 00055 int _total_allocated_size; 00056 int _number_of_objects; 00057 }; 00058 00059 #define GObjectStats NUX_GLOBAL_OBJECT_INSTANCE(nux::ObjectStats) 00060 00062 00066 class Trackable: public nux::Introspectable, public sigc::trackable 00067 { 00068 public: 00069 NUX_DECLARE_ROOT_OBJECT_TYPE (Trackable); 00071 /* 00072 @return True if the object reference is owned. 00073 */ 00074 bool OwnsTheReference(); 00075 00077 /* 00078 @return True if the object was allocated dynamically. 00079 */ 00080 bool IsHeapAllocated(); 00081 00083 /* 00084 @return True if the object was allocated dynamically. 00085 */ 00086 bool IsDynamic() const; 00087 00088 00090 /* 00091 Widget are typically created and added to containers. It is decided that when widgets are created, they should have a floating reference 00092 and their reference count is set to 1. 00093 { 00094 Button* button = new Button(); // button ref_cout = 1, floating = true; 00095 container->AddButton(button); // button has a floating reference; when container call button->ref() the ref count 00096 // of button remains at 1 but the floating reference is set to false. From now on, 00097 // calling button->ref will always increase the ref count (since button no longer has a floating reference). 00098 } 00099 00100 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 00101 floating reference, then call Dispose(). Dispose does some sanity check; it verifies that: 00102 ref_count == 1 00103 floating == true 00104 If these conditions are verified, dispose will cause the object to be destroyed. 00105 Calling unref() on an object that has a floating reference will trigger a warning/error in order to invite the 00106 developer. The developer can either ref the object first before calling unref or simply not create the widget since it 00107 does not appear to have been used. 00108 00109 During development it often happen that one forget to dispose an object with a floating reference. 00110 Assuming that all functions that receive a reference counted object properly call ref on the object and that the compiler 00111 can detect unused variables, then the developer should have a way to detect reference counted objects that are not owned. 00112 It is up to the developer to properly handle these objects. 00113 00114 @return True if the object has been referenced. 00115 */ 00116 virtual bool Reference(); 00117 00119 00122 virtual bool UnReference(); 00123 00125 00131 virtual bool SinkReference(); 00132 00134 00137 virtual bool Dispose(); 00138 00140 00143 virtual int GetObjectSize (); 00144 00145 static std::new_handler set_new_handler (std::new_handler handler); 00146 static void *operator new (size_t size); 00147 00148 #if (__GNUC__ < 4 && __GNUC_MINOR__ < 4) 00149 static void *operator new (size_t size, void *ptr); 00150 #endif 00151 00152 static void operator delete (void *ptr); 00153 00154 protected: 00155 Trackable(); 00156 virtual ~Trackable() = 0; 00157 void SetOwnedReference (bool b); 00158 int _heap_allocated; 00159 00160 private: 00161 // Trackable objects are not copyable. 00162 Trackable (const Trackable &); 00163 Trackable &operator= (const Trackable &); 00164 00165 static std::new_handler _new_current_handler; 00166 00167 bool _owns_the_reference; 00168 int _size_of_this_object; 00169 }; 00170 00172 class Object: public Trackable 00173 { 00174 public: 00175 NUX_DECLARE_OBJECT_TYPE (BaseObject, Trackable); 00176 00178 Object (bool OwnTheReference = true, NUX_FILE_LINE_PROTO); 00180 00183 bool Reference(); 00184 00186 00190 bool UnReference(); 00191 00193 00199 virtual bool SinkReference(); 00200 00202 00205 virtual bool Dispose(); 00206 00208 00211 int GetReferenceCount () const; 00212 00214 sigc::signal <void, Object *> object_destroyed; 00215 00216 std::string GetAllocationLoation() const; 00217 00218 protected: 00220 /* 00221 Private destructor. Ensure that Object cannot be created on the stack 00222 (only on the heap), but objects that inherits from Object can stil be 00223 created on the stack or on the heap. (MEC++ item27) 00224 */ 00225 virtual ~Object(); 00226 00227 private: 00229 void Destroy(); 00230 00231 Object (const Object &); 00232 Object &operator = (const Object &); 00233 00234 const char* allocation_file_name_; 00235 int allocation_line_number_; 00236 00237 NThreadSafeCounter* reference_count_; 00239 NThreadSafeCounter* objectptr_count_; 00240 00241 template <typename T> 00242 friend class ObjectPtr; 00243 00244 template <typename T> 00245 friend class ObjectWeakPtr; 00246 friend class ObjectStats; 00247 }; 00248 00249 } 00250 00251 #endif // NUXOBJECT_H 00252