]> git.saurik.com Git - wxWidgets.git/blame - src/common/object.cpp
Dialog unit mods; wxProp tidying
[wxWidgets.git] / src / common / object.cpp
CommitLineData
c801d85f
KB
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
1678ad78 23#ifndef WX_PRECOMP
c801d85f 24#include "wx/hash.h"
47d67540 25#ifdef wxUSE_SERIAL
1678ad78 26#include "wx/objstrm.h"
f4a8c29f
GL
27#include "wx/serbase.h"
28#endif
1678ad78 29#endif
c801d85f
KB
30
31#include <string.h>
32#include <assert.h>
33
47d67540 34#if (WXDEBUG && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
c801d85f
KB
35#include "wx/memory.h"
36#endif
37
47d67540 38#if WXDEBUG || wxUSE_DEBUG_CONTEXT
c801d85f
KB
39 // for wxObject::Dump
40 #include <iostream.h>
41#endif
42
43#if !USE_SHARED_LIBRARY
0c32066b
JS
44wxClassInfo wxObject::sm_classwxObject((char *) "wxObject", (char *) NULL, (char *) NULL, (int ) sizeof(wxObject), (wxObjectConstructorFn) NULL);
45wxClassInfo* wxClassInfo::sm_first = (wxClassInfo *) NULL;
46wxHashTable* wxClassInfo::sm_classTable = (wxHashTable*) NULL;
c801d85f
KB
47#endif
48
49/*
50 * wxWindows root object.
51 */
52
53wxObject::wxObject(void)
54{
c67daf87 55 m_refData = (wxObjectRefData *) NULL;
47d67540 56#ifdef wxUSE_SERIAL
f4a8c29f
GL
57 m_serialObj = (wxObject_Serialize *)NULL;
58#endif
c801d85f
KB
59}
60
61wxObject::~wxObject(void)
62{
63 UnRef();
47d67540 64#ifdef wxUSE_SERIAL
f4a8c29f
GL
65 if (m_serialObj)
66 delete m_serialObj;
67#endif
c801d85f
KB
68}
69
70/*
71 * Is this object a kind of (a subclass of) 'info'?
72 * E.g. is wxWindow a kind of wxObject?
73 * Go from this class to superclass, taking into account
74 * two possible base classes.
75 */
76
341287bf 77bool wxObject::IsKindOf(wxClassInfo *info) const
c801d85f
KB
78{
79 wxClassInfo *thisInfo = GetClassInfo();
80 if (thisInfo)
81 return thisInfo->IsKindOf(info);
82 else
83 return FALSE;
84}
85
47d67540 86#if WXDEBUG || wxUSE_DEBUG_CONTEXT
c801d85f
KB
87void wxObject::Dump(ostream& str)
88{
89 if (GetClassInfo() && GetClassInfo()->GetClassName())
90 str << GetClassInfo()->GetClassName();
91 else
92 str << "unknown object class";
93}
94#endif
95
47d67540 96#if WXDEBUG && wxUSE_MEMORY_TRACING
c801d85f
KB
97
98#ifdef new
99#undef new
100#endif
101
102void * wxObject::operator new (size_t size, char * fileName, int lineNum)
103{
104 return wxDebugAlloc(size, fileName, lineNum, TRUE);
105}
106
107void wxObject::operator delete (void * buf)
108{
109 wxDebugFree(buf);
110}
111
76626af2
JS
112// VC++ 6.0
113#if _MSC_VER >= 1200
f97c9854 114void operator wxObject::delete(void* pData, char* /* fileName */, int /* lineNum */)
76626af2
JS
115{
116 ::operator delete(pData);
117}
118#endif
119
c801d85f
KB
120// Cause problems for VC++ - crashes
121#ifndef _MSC_VER
122void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
123{
124 return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
125}
126
127void wxObject::operator delete[] (void * buf)
128{
129 wxDebugFree(buf, TRUE);
130}
131#endif
132
133#endif
134
135/*
136 * Class info: provides run-time class type information.
137 */
138
c801d85f
KB
139wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
140{
0c32066b
JS
141 m_className = cName;
142 m_baseClassName1 = baseName1;
143 m_baseClassName2 = baseName2;
c801d85f 144
0c32066b
JS
145 m_objectSize = sz;
146 m_objectConstructor = constr;
c801d85f 147
0c32066b
JS
148 m_next = sm_first;
149 sm_first = this;
c801d85f 150
0c32066b
JS
151 m_baseInfo1 = (wxClassInfo *) NULL;
152 m_baseInfo2 = (wxClassInfo *) NULL;
c801d85f
KB
153}
154
c801d85f
KB
155wxObject *wxClassInfo::CreateObject(void)
156{
0c32066b
JS
157 if (m_objectConstructor)
158 return (wxObject *)(*m_objectConstructor)();
c801d85f 159 else
c67daf87 160 return (wxObject *) NULL;
c801d85f
KB
161}
162
163wxClassInfo *wxClassInfo::FindClass(char *c)
164{
0c32066b 165 wxClassInfo *p = sm_first;
c801d85f
KB
166 while (p)
167 {
168 if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
169 return p;
0c32066b 170 p = p->m_next;
c801d85f 171 }
c67daf87 172 return (wxClassInfo *) NULL;
c801d85f
KB
173}
174
175// Climb upwards through inheritance hierarchy.
176// Dual inheritance is catered for.
341287bf 177bool wxClassInfo::IsKindOf(wxClassInfo *info) const
c801d85f
KB
178{
179 if (info == NULL)
180 return FALSE;
181
182 // For some reason, when making/using a DLL, static data has to be included
183 // in both the DLL and the application. This can lead to duplicate
184 // wxClassInfo objects, so we have to test the name instead of the pointers.
0c32066b
JS
185 // PROBABLY NO LONGER TRUE now I've done DLL creation right.
186/*
c801d85f
KB
187#if WXMAKINGDLL
188 if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
189 return TRUE;
190#else
0c32066b 191*/
c801d85f
KB
192 if (this == info)
193 return TRUE;
c801d85f 194
0c32066b
JS
195 if (m_baseInfo1)
196 if (m_baseInfo1->IsKindOf(info))
c801d85f
KB
197 return TRUE;
198
0c32066b
JS
199 if (m_baseInfo2)
200 return m_baseInfo2->IsKindOf(info);
c801d85f
KB
201
202 return FALSE;
203}
204
205// Set pointers to base class(es) to speed up IsKindOf
206void wxClassInfo::InitializeClasses(void)
207{
0c32066b
JS
208 wxClassInfo::sm_classTable = new wxHashTable(wxKEY_STRING);
209
c801d85f 210 // Index all class infos by their class name
0c32066b 211 wxClassInfo *info = sm_first;
c801d85f
KB
212 while (info)
213 {
0c32066b
JS
214 if (info->m_className)
215 sm_classTable->Put(info->m_className, (wxObject *)info);
216 info = info->m_next;
c801d85f
KB
217 }
218
219 // Set base pointers for each wxClassInfo
0c32066b 220 info = sm_first;
c801d85f
KB
221 while (info)
222 {
223 if (info->GetBaseClassName1())
0c32066b 224 info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
c801d85f 225 if (info->GetBaseClassName2())
0c32066b
JS
226 info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
227 info = info->m_next;
c801d85f
KB
228 }
229}
230
0c32066b 231void wxClassInfo::CleanUpClasses(void)
c801d85f 232{
0c32066b
JS
233 delete wxClassInfo::sm_classTable;
234 wxClassInfo::sm_classTable = NULL;
235}
f4a8c29f 236
0c32066b
JS
237wxObject *wxCreateDynamicObject(const char *name)
238{
239 if (wxClassInfo::sm_classTable)
240 {
241 wxClassInfo *info = (wxClassInfo *)wxClassInfo::sm_classTable->Get(name);
242 if (!info)
243 return (wxObject *)NULL;
244
245 return info->CreateObject();
246 }
247 else
248 {
249 wxClassInfo *info = wxClassInfo::sm_first;
250 while (info)
251 {
252 if (info->m_className && strcmp(info->m_className, name) == 0)
253 return info->CreateObject();
254 info = info->m_next;
255 }
256 return (wxObject*) NULL;
257 }
258 return (wxObject*) NULL;
c801d85f
KB
259}
260
47d67540 261#ifdef wxUSE_SERIAL
c801d85f 262
7a4b9130
GL
263#include "wx/serbase.h"
264#include "wx/dynlib.h"
265#include "wx/msgdlg.h"
266
1678ad78 267wxObject* wxCreateStoredObject( wxInputStream &stream )
c801d85f 268{
1678ad78
GL
269 wxObjectInputStream obj_s(stream);
270 return obj_s.LoadObject();
c801d85f
KB
271};
272
7a4b9130
GL
273void wxObject::StoreObject( wxObjectOutputStream& stream )
274{
275 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
276 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
1d44aaf8
GL
277
278 if (!lib) {
279 wxMessageBox("Can't load wxSerial dynamic library.", "Alert !");
280 return;
281 }
f4a8c29f
GL
282 if (!m_serialObj) {
283 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
7a4b9130 284
f4a8c29f
GL
285 if (!m_serialObj) {
286 wxString message;
7a4b9130 287
f4a8c29f
GL
288 message.Printf("Can't find the serialization object (%s) for the object %s",
289 WXSTRINGCAST obj_name,
290 WXSTRINGCAST GetClassInfo()->GetClassName());
291 wxMessageBox(message, "Alert !");
292 return;
293 }
294 m_serialObj->SetObject(this);
7a4b9130
GL
295 }
296
f4a8c29f 297 m_serialObj->StoreObject(stream);
7a4b9130
GL
298}
299
300void wxObject::LoadObject( wxObjectInputStream& stream )
301{
302 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
303 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
7a4b9130 304
f4a8c29f
GL
305 if (!m_serialObj) {
306 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
7a4b9130 307
f4a8c29f
GL
308 if (!m_serialObj) {
309 wxString message;
7a4b9130 310
f4a8c29f
GL
311 message.Printf("Can't find the serialization object (%s) for the object %s",
312 WXSTRINGCAST obj_name,
313 WXSTRINGCAST GetClassInfo()->GetClassName());
314 wxMessageBox(message, "Alert !");
315 return;
316 }
317 m_serialObj->SetObject(this);
318 }
6f34921d 319
f4a8c29f 320 m_serialObj->LoadObject(stream);
7a4b9130
GL
321}
322
c801d85f
KB
323#endif
324
325/*
326 * wxObject: cloning of objects
327 */
328
329void wxObject::Ref(const wxObject& clone)
330{
331 // delete reference to old data
332 UnRef();
333 // reference new data
334 if (clone.m_refData) {
335 m_refData = clone.m_refData;
336 ++(m_refData->m_count);
337 }
338}
339
340void wxObject::UnRef(void)
341{
342 if (m_refData) {
343 assert(m_refData->m_count > 0);
344 --(m_refData->m_count);
345 if (m_refData->m_count == 0)
346 delete m_refData;
347 }
c67daf87 348 m_refData = (wxObjectRefData *) NULL;
c801d85f
KB
349}
350
351/*
352 * wxObjectData
353 */
354
355wxObjectRefData::wxObjectRefData(void) : m_count(1)
356{
357}
358
359wxObjectRefData::~wxObjectRefData(void)
360{
361}
362
341287bf
JS
363// These are here so we can avoid 'always true/false' warnings
364// by referring to these instead of TRUE/FALSE
365const bool wxTrue = TRUE;
366const bool wxFalse = FALSE;