~ubuntu-branches/ubuntu/oneiric/nux/oneiric

« back to all changes in this revision

Viewing changes to NuxCore/Object.h

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-11-18 19:17:32 UTC
  • Revision ID: james.westby@ubuntu.com-20101118191732-rn35790vekj6o4my
Tags: upstream-0.9.4
ImportĀ upstreamĀ versionĀ 0.9.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2010 Inalogic Inc.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU Lesser General Public License version 3, as
 
6
 * published by the  Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
 
12
 * License for more details.
 
13
 *
 
14
 * You should have received a copy of both the GNU Lesser General Public
 
15
 * License version 3 along with this program.  If not, see
 
16
 * <http://www.gnu.org/licenses/>
 
17
 *
 
18
 * Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
 
19
 *
 
20
 */
 
21
 
 
22
 
 
23
#ifndef NUXOBJECT_H
 
24
#define NUXOBJECT_H
 
25
 
 
26
namespace nux
 
27
{
 
28
 
 
29
  template <typename T>
 
30
  class IntrusiveSP;
 
31
 
 
32
  template <typename T>
 
33
  class IntrusiveWeakSP;
 
34
 
 
35
// #if defined(NUX_DEBUG)
 
36
#define NUX_FILE_LINE_PROTO     const char* __Nux_FileName__=__FILE__, int __Nux_LineNumber__ = __LINE__
 
37
#define NUX_FILE_LINE_DECL      const char* __Nux_FileName__, int __Nux_LineNumber__
 
38
#define NUX_FILE_LINE_PARAM     __Nux_FileName__, __Nux_LineNumber__
 
39
#define NUX_TRACKER_LOCATION    __FILE__, __LINE__
 
40
// #else
 
41
//     #define NUX_FILE_LINE_PROTO     int __Nux_Dummy__ = 0xD0DECADE
 
42
//     #define NUX_FILE_LINE_DECL      int __Nux_Dummy__
 
43
//     #define NUX_FILE_LINE_PARAM     __Nux_Dummy__
 
44
//     #define NUX_TRACKER_LOCATION    0xD0DECADE
 
45
// #endif
 
46
 
 
47
  class ObjectStats
 
48
  {
 
49
    NUX_DECLARE_GLOBAL_OBJECT (ObjectStats, GlobalSingletonInitializer);
 
50
  public:
 
51
    class AllocationList : public std::list<void *>
 
52
    {
 
53
    public:
 
54
      AllocationList();
 
55
      ~AllocationList();
 
56
    };
 
57
 
 
58
    AllocationList _allocation_list;
 
59
    int _total_allocated_size;  //! Total allocated memory size in bytes.
 
60
    int _number_of_objects;     //! Number of allocated objects;
 
61
  };
 
62
#define GObjectStats NUX_GLOBAL_OBJECT_INSTANCE(nux::ObjectStats)
 
63
 
 
64
//! Base class of heap allocated objects.
 
65
  /*!
 
66
      Trackable does not implement reference counting. It only defines the API. It is up
 
67
      to the class that inherit from Trackable to implement the reference counting.
 
68
  */
 
69
  class Trackable
 
70
  {
 
71
  public:
 
72
    NUX_DECLARE_ROOT_OBJECT_TYPE (Trackable);
 
73
    //! Test if object reference is owned.
 
74
    /*
 
75
        @return True if the object reference is owned.
 
76
    */
 
77
    bool OwnsTheReference();
 
78
 
 
79
    //! Test if object was allocated dynamically.
 
80
    /*
 
81
        @return True if the object was allocated dynamically.
 
82
    */
 
83
    bool IsHeapAllocated() const;
 
84
 
 
85
    //! Test if object was allocated dynamically.
 
86
    /*
 
87
        @return True if the object was allocated dynamically.
 
88
    */
 
89
    bool IsDynamic() const;
 
90
 
 
91
    //! Increase the reference count.
 
92
    /*
 
93
        Widget are typically created and added to containers. It is decided that when widgets are created, they should have a floating reference
 
94
        and their reference count is set to 1.
 
95
        {
 
96
            Button* button = new Button();  // button ref_cout = 1, floating = true;
 
97
            container->AddButton(button);   // button has a floating reference; when container call button->ref() the ref count
 
98
                                            // of button remains at 1 but the floating reference is set to false. From now on,
 
99
                                            // calling button->ref will always increase the ref count (since button no longer has a floating reference).
 
100
        }
 
101
 
 
102
        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
 
103
        floating reference, then call Dispose(). Dispose does some sanity check; it verifies that:
 
104
             ref_count == 1
 
105
             floating == true
 
106
        If these conditions are verified, dispose will cause the object to be destroyed.
 
107
        Calling unref() on an object that has a floating reference will trigger a warning/error in order to invite the
 
108
        developer. The developer can either ref the object first before calling unref or simply not create the widget since it
 
109
        does not appear to have been used.
 
110
 
 
111
        During development it often happen that one forget to dispose an object with a floating reference.
 
112
        Assuming that all functions that receive a reference counted object properly call ref on the object and that the compiler
 
113
        can detect unused variables, then the developer should have a way to detect reference counted objects that are not owned.
 
114
        It is up to the developer to properly handle these objects.
 
115
    */
 
116
    virtual void Reference();
 
117
 
 
118
    //! Decrease the reference count.
 
119
    /*!
 
120
        @return True if the object has been destroyed
 
121
    */
 
122
    virtual bool UnReference();
 
123
 
 
124
    //! Mark the object as owned.
 
125
    /*!
 
126
        @return True if the object was not owned previously
 
127
    */
 
128
    virtual bool SinkReference();
 
129
 
 
130
    //! Destroy and object that has a floating reference.
 
131
    /*!
 
132
        If this object is not owned, calling SinkReference() as the same effect as calling Reference().
 
133
        @return True if the object has been destroyed
 
134
    */
 
135
    virtual bool Dispose();
 
136
 
 
137
    static std::new_handler set_new_handler (std::new_handler handler);
 
138
    static void *operator new (size_t size);
 
139
 
 
140
#if (__GNUC__ < 4 && __GNUC_MINOR__ < 4)
 
141
    static void *operator new (size_t size, void *ptr);
 
142
#endif
 
143
 
 
144
    static void operator delete (void *ptr);
 
145
 
 
146
  protected:
 
147
    Trackable();
 
148
    virtual ~Trackable() = 0;
 
149
    void SetOwnedReference (bool b);
 
150
 
 
151
  private:
 
152
    Trackable (const Trackable &);
 
153
    Trackable &operator= (const Trackable &);
 
154
 
 
155
//     class AllocationList : public std::list<void *>
 
156
//     {
 
157
//     public:
 
158
//       AllocationList();
 
159
//       ~AllocationList();
 
160
//     };
 
161
 
 
162
    //static AllocationList m_allocation_list;
 
163
    static std::new_handler m_new_current_handler;
 
164
//     static int m_total_allocated_size;  //! Total allocated memory size in bytes.
 
165
//     static int m_number_of_objects;     //! Number of allocated objects;
 
166
 
 
167
    bool m_owns_the_reference;
 
168
    int m_size_of_this_object;
 
169
 
 
170
    //template<typename T> friend class Pointer;
 
171
  };
 
172
 
 
173
//! The base class of Nux objects.
 
174
  class Object: public Trackable
 
175
  {
 
176
  public:
 
177
    NUX_DECLARE_OBJECT_TYPE (BaseObject, Trackable);
 
178
 
 
179
    //! Constructor
 
180
    Object (bool OwnTheReference = true, NUX_FILE_LINE_PROTO);
 
181
    //! Increase reference count.
 
182
    void Reference();
 
183
    //! Decrease reference count.
 
184
    /*!
 
185
        @return True if the object reference count has reached 0 and the object has been destroyed.
 
186
    */
 
187
    bool UnReference();
 
188
 
 
189
    //! Mark the object as owned.
 
190
    /*!
 
191
        @return True if the object was not owned previously
 
192
    */
 
193
    virtual bool SinkReference();
 
194
 
 
195
    //! Destroy and object that has a floating reference.
 
196
    /*!
 
197
        If this object is not owned, calling SinkReference() as the same effect as calling Reference().
 
198
        @return True is the object has been destroyed
 
199
    */
 
200
    virtual bool Dispose();
 
201
 
 
202
    //! Returns true if the object was allocated on the heap.
 
203
    /*!
 
204
        @return True if the object was allocated on the heap.
 
205
    */
 
206
    bool IsHeapAllocated();
 
207
 
 
208
    //! Get the reference count of this object.
 
209
    /*!
 
210
        @return The reference count of this object.
 
211
    */
 
212
    int GetReferenceCount () const;
 
213
 
 
214
    //! Get the weak reference count of this object.
 
215
    /*!
 
216
        @return The weak reference count of this object.
 
217
    */
 
218
    int GetWeakReferenceCount () const;
 
219
 
 
220
    NThreadSafeCounter *m_reference_count; //!< Reference count.
 
221
    NThreadSafeCounter *m_weak_reference_count; //!< Weak reference count.
 
222
 
 
223
  protected:
 
224
    //! Private destructor.
 
225
    /*
 
226
        Private destructor. Ensure that Object cannot be created on the stack (only on the heap), but objects that inherits
 
227
        from Object can stil be created on the stack or on the heap.
 
228
        (MEC++ item27)
 
229
    */
 
230
    virtual ~Object();
 
231
 
 
232
    void IncrementWeakCounter();
 
233
    void DecrementWeakCounter();
 
234
 
 
235
  private:
 
236
    //! Destroy the object.
 
237
    void Destroy();
 
238
 
 
239
    Object (const Object &);
 
240
    Object &operator = (const Object &);
 
241
 
 
242
 
 
243
//#if defined(NUX_DEBUG)
 
244
    NString m_allocation_file_name;
 
245
    int     m_allocation_line_number;
 
246
//#endif
 
247
 
 
248
    template <typename T>
 
249
    friend class IntrusiveSP;
 
250
 
 
251
    template <typename T>
 
252
    friend class IntrusiveWeakSP;
 
253
    friend class ObjectStats;
 
254
  };
 
255
 
 
256
}
 
257
 
 
258
#endif // NUXOBJECT_H
 
259