Cleared up DEBUG define mess, defines are now called __WXDEBUG__ and WXDEBUG.
[wxWidgets.git] / src / common / object.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: object.cpp
3 // Purpose: wxObject implementation
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "object.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #include "wx/hash.h"
24
25 #include <string.h>
26 #include <assert.h>
27
28 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
29 #include "wx/memory.h"
30 #endif
31
32 #if WXDEBUG || USE_DEBUG_CONTEXT
33 // for wxObject::Dump
34 #include <iostream.h>
35 #endif
36
37 #if !USE_SHARED_LIBRARY
38 wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
39 wxClassInfo *wxClassInfo::first = NULL;
40 #endif
41
42 /*
43 * wxWindows root object.
44 */
45
46 wxObject::wxObject(void)
47 {
48 m_refData = NULL;
49 }
50
51 wxObject::~wxObject(void)
52 {
53 UnRef();
54 }
55
56 /*
57 * Is this object a kind of (a subclass of) 'info'?
58 * E.g. is wxWindow a kind of wxObject?
59 * Go from this class to superclass, taking into account
60 * two possible base classes.
61 */
62
63 bool wxObject::IsKindOf(wxClassInfo *info)
64 {
65 wxClassInfo *thisInfo = GetClassInfo();
66 if (thisInfo)
67 return thisInfo->IsKindOf(info);
68 else
69 return FALSE;
70 }
71
72 #if WXDEBUG || USE_DEBUG_CONTEXT
73 void wxObject::Dump(ostream& str)
74 {
75 if (GetClassInfo() && GetClassInfo()->GetClassName())
76 str << GetClassInfo()->GetClassName();
77 else
78 str << "unknown object class";
79 }
80 #endif
81
82 #if WXDEBUG && USE_MEMORY_TRACING
83
84 #ifdef new
85 #undef new
86 #endif
87
88 void * wxObject::operator new (size_t size, char * fileName, int lineNum)
89 {
90 return wxDebugAlloc(size, fileName, lineNum, TRUE);
91 }
92
93 void wxObject::operator delete (void * buf)
94 {
95 wxDebugFree(buf);
96 }
97
98 // Cause problems for VC++ - crashes
99 #ifndef _MSC_VER
100 void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
101 {
102 return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
103 }
104
105 void wxObject::operator delete[] (void * buf)
106 {
107 wxDebugFree(buf, TRUE);
108 }
109 #endif
110
111 #endif
112
113 /*
114 * Class info: provides run-time class type information.
115 */
116
117 #ifdef USE_STORABLE_CLASSES
118
119 wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn fn,
120 wxStorableConstructorFn stoFn )
121 {
122 className = cName;
123 baseClassName1 = baseName1;
124 baseClassName2 = baseName2;
125
126 objectSize = sz;
127 objectConstructor = fn;
128 storableConstructor = stoFn;
129
130 next = first;
131 first = this;
132
133 baseInfo1 = NULL;
134 baseInfo2 = NULL;
135 }
136
137 wxObject* wxClassInfo::CreateObject( istream &stream, char *data )
138 {
139 if (storableConstructor)
140 return (wxObject *)(*storableConstructor)( stream, data );
141 else
142 return NULL;
143 }
144
145 #else
146
147 wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
148 {
149 className = cName;
150 baseClassName1 = baseName1;
151 baseClassName2 = baseName2;
152
153 objectSize = sz;
154 objectConstructor = constr;
155
156 next = first;
157 first = this;
158
159 baseInfo1 = NULL;
160 baseInfo2 = NULL;
161 }
162
163 #endif
164
165 wxObject *wxClassInfo::CreateObject(void)
166 {
167 if (objectConstructor)
168 return (wxObject *)(*objectConstructor)();
169 else
170 return NULL;
171 }
172
173 wxClassInfo *wxClassInfo::FindClass(char *c)
174 {
175 wxClassInfo *p = first;
176 while (p)
177 {
178 if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
179 return p;
180 p = p->next;
181 }
182 return NULL;
183 }
184
185 // Climb upwards through inheritance hierarchy.
186 // Dual inheritance is catered for.
187 bool wxClassInfo::IsKindOf(wxClassInfo *info)
188 {
189 if (info == NULL)
190 return FALSE;
191
192 // For some reason, when making/using a DLL, static data has to be included
193 // in both the DLL and the application. This can lead to duplicate
194 // wxClassInfo objects, so we have to test the name instead of the pointers.
195 #if WXMAKINGDLL
196 if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
197 return TRUE;
198 #else
199 if (this == info)
200 return TRUE;
201 #endif
202
203 if (baseInfo1)
204 if (baseInfo1->IsKindOf(info))
205 return TRUE;
206
207 if (baseInfo2)
208 return baseInfo2->IsKindOf(info);
209
210 return FALSE;
211 }
212
213 // Set pointers to base class(es) to speed up IsKindOf
214 void wxClassInfo::InitializeClasses(void)
215 {
216 wxHashTable table(wxKEY_STRING);
217
218 // Index all class infos by their class name
219 wxClassInfo *info = first;
220 while (info)
221 {
222 if (info->className)
223 table.Put(info->className, (wxObject *)info);
224 info = info->next;
225 }
226
227 // Set base pointers for each wxClassInfo
228 info = first;
229 while (info)
230 {
231 if (info->GetBaseClassName1())
232 info->baseInfo1 = (wxClassInfo *)table.Get(info->GetBaseClassName1());
233 if (info->GetBaseClassName2())
234 info->baseInfo2 = (wxClassInfo *)table.Get(info->GetBaseClassName2());
235 info = info->next;
236 }
237 }
238
239 wxObject *wxCreateDynamicObject(char *name)
240 {
241 wxClassInfo *info = wxClassInfo::first;
242 while (info)
243 {
244 if (info->className && strcmp(info->className, name) == 0)
245 return info->CreateObject();
246 info = info->next;
247 }
248 return NULL;
249 }
250
251 #ifdef USE_STORABLE_CLASSES
252
253 wxObject* wxCreateStoredObject( char *name, istream &stream, char *data )
254 {
255 wxClassInfo *info = wxClassInfo::first;
256 while (info)
257 {
258 if (info->className && strcmp(info->className, name) == 0)
259 return info->CreateObject( stream, data );
260 info = info->next;
261 }
262 return NULL;
263 };
264
265 #endif
266
267 /*
268 * wxObject: cloning of objects
269 */
270
271 void wxObject::Ref(const wxObject& clone)
272 {
273 // delete reference to old data
274 UnRef();
275 // reference new data
276 if (clone.m_refData) {
277 m_refData = clone.m_refData;
278 ++(m_refData->m_count);
279 }
280 }
281
282 void wxObject::UnRef(void)
283 {
284 if (m_refData) {
285 assert(m_refData->m_count > 0);
286 --(m_refData->m_count);
287 if (m_refData->m_count == 0)
288 delete m_refData;
289 }
290 m_refData = NULL;
291 }
292
293 /*
294 * wxObjectData
295 */
296
297 wxObjectRefData::wxObjectRefData(void) : m_count(1)
298 {
299 }
300
301 wxObjectRefData::~wxObjectRefData(void)
302 {
303 }
304