]> git.saurik.com Git - wxWidgets.git/blame - src/common/object.cpp
Added #include to get FIONBIO on Solaris 2.6
[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"
bcf1fa6b 25#ifdef USE_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
b2aef89b 34#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
c801d85f
KB
35#include "wx/memory.h"
36#endif
37
b2aef89b 38#if WXDEBUG || USE_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;
bcf1fa6b 56#ifdef USE_SERIAL
f4a8c29f
GL
57 m_serialObj = (wxObject_Serialize *)NULL;
58#endif
c801d85f
KB
59}
60
61wxObject::~wxObject(void)
62{
63 UnRef();
bcf1fa6b 64#ifdef USE_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
77bool wxObject::IsKindOf(wxClassInfo *info)
78{
79 wxClassInfo *thisInfo = GetClassInfo();
80 if (thisInfo)
81 return thisInfo->IsKindOf(info);
82 else
83 return FALSE;
84}
85
b2aef89b 86#if WXDEBUG || USE_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
b2aef89b 96#if WXDEBUG && USE_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
112// Cause problems for VC++ - crashes
113#ifndef _MSC_VER
114void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
115{
116 return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
117}
118
119void wxObject::operator delete[] (void * buf)
120{
121 wxDebugFree(buf, TRUE);
122}
123#endif
124
125#endif
126
127/*
128 * Class info: provides run-time class type information.
129 */
130
c801d85f
KB
131wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
132{
0c32066b
JS
133 m_className = cName;
134 m_baseClassName1 = baseName1;
135 m_baseClassName2 = baseName2;
c801d85f 136
0c32066b
JS
137 m_objectSize = sz;
138 m_objectConstructor = constr;
c801d85f 139
0c32066b
JS
140 m_next = sm_first;
141 sm_first = this;
c801d85f 142
0c32066b
JS
143 m_baseInfo1 = (wxClassInfo *) NULL;
144 m_baseInfo2 = (wxClassInfo *) NULL;
c801d85f
KB
145}
146
c801d85f
KB
147wxObject *wxClassInfo::CreateObject(void)
148{
0c32066b
JS
149 if (m_objectConstructor)
150 return (wxObject *)(*m_objectConstructor)();
c801d85f 151 else
c67daf87 152 return (wxObject *) NULL;
c801d85f
KB
153}
154
155wxClassInfo *wxClassInfo::FindClass(char *c)
156{
0c32066b 157 wxClassInfo *p = sm_first;
c801d85f
KB
158 while (p)
159 {
160 if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
161 return p;
0c32066b 162 p = p->m_next;
c801d85f 163 }
c67daf87 164 return (wxClassInfo *) NULL;
c801d85f
KB
165}
166
167// Climb upwards through inheritance hierarchy.
168// Dual inheritance is catered for.
169bool wxClassInfo::IsKindOf(wxClassInfo *info)
170{
171 if (info == NULL)
172 return FALSE;
173
174 // For some reason, when making/using a DLL, static data has to be included
175 // in both the DLL and the application. This can lead to duplicate
176 // wxClassInfo objects, so we have to test the name instead of the pointers.
0c32066b
JS
177 // PROBABLY NO LONGER TRUE now I've done DLL creation right.
178/*
c801d85f
KB
179#if WXMAKINGDLL
180 if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
181 return TRUE;
182#else
0c32066b 183*/
c801d85f
KB
184 if (this == info)
185 return TRUE;
c801d85f 186
0c32066b
JS
187 if (m_baseInfo1)
188 if (m_baseInfo1->IsKindOf(info))
c801d85f
KB
189 return TRUE;
190
0c32066b
JS
191 if (m_baseInfo2)
192 return m_baseInfo2->IsKindOf(info);
c801d85f
KB
193
194 return FALSE;
195}
196
197// Set pointers to base class(es) to speed up IsKindOf
198void wxClassInfo::InitializeClasses(void)
199{
0c32066b
JS
200 wxClassInfo::sm_classTable = new wxHashTable(wxKEY_STRING);
201
c801d85f 202 // Index all class infos by their class name
0c32066b 203 wxClassInfo *info = sm_first;
c801d85f
KB
204 while (info)
205 {
0c32066b
JS
206 if (info->m_className)
207 sm_classTable->Put(info->m_className, (wxObject *)info);
208 info = info->m_next;
c801d85f
KB
209 }
210
211 // Set base pointers for each wxClassInfo
0c32066b 212 info = sm_first;
c801d85f
KB
213 while (info)
214 {
215 if (info->GetBaseClassName1())
0c32066b 216 info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
c801d85f 217 if (info->GetBaseClassName2())
0c32066b
JS
218 info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
219 info = info->m_next;
c801d85f
KB
220 }
221}
222
0c32066b
JS
223// Clean up hash table
224void wxClassInfo::CleanUpClasses(void)
c801d85f 225{
0c32066b
JS
226 delete wxClassInfo::sm_classTable;
227 wxClassInfo::sm_classTable = NULL;
228}
f4a8c29f 229
0c32066b
JS
230wxObject *wxCreateDynamicObject(const char *name)
231{
232 if (wxClassInfo::sm_classTable)
233 {
234 wxClassInfo *info = (wxClassInfo *)wxClassInfo::sm_classTable->Get(name);
235 if (!info)
236 return (wxObject *)NULL;
237
238 return info->CreateObject();
239 }
240 else
241 {
242 wxClassInfo *info = wxClassInfo::sm_first;
243 while (info)
244 {
245 if (info->m_className && strcmp(info->m_className, name) == 0)
246 return info->CreateObject();
247 info = info->m_next;
248 }
249 return (wxObject*) NULL;
250 }
251 return (wxObject*) NULL;
c801d85f
KB
252}
253
8429bec1 254#ifdef USE_SERIAL
c801d85f 255
7a4b9130
GL
256#include "wx/serbase.h"
257#include "wx/dynlib.h"
258#include "wx/msgdlg.h"
259
1678ad78 260wxObject* wxCreateStoredObject( wxInputStream &stream )
c801d85f 261{
1678ad78
GL
262 wxObjectInputStream obj_s(stream);
263 return obj_s.LoadObject();
c801d85f
KB
264};
265
7a4b9130
GL
266void wxObject::StoreObject( wxObjectOutputStream& stream )
267{
268 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
269 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
1d44aaf8
GL
270
271 if (!lib) {
272 wxMessageBox("Can't load wxSerial dynamic library.", "Alert !");
273 return;
274 }
f4a8c29f
GL
275 if (!m_serialObj) {
276 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
7a4b9130 277
f4a8c29f
GL
278 if (!m_serialObj) {
279 wxString message;
7a4b9130 280
f4a8c29f
GL
281 message.Printf("Can't find the serialization object (%s) for the object %s",
282 WXSTRINGCAST obj_name,
283 WXSTRINGCAST GetClassInfo()->GetClassName());
284 wxMessageBox(message, "Alert !");
285 return;
286 }
287 m_serialObj->SetObject(this);
7a4b9130
GL
288 }
289
f4a8c29f 290 m_serialObj->StoreObject(stream);
7a4b9130
GL
291}
292
293void wxObject::LoadObject( wxObjectInputStream& stream )
294{
295 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
296 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
7a4b9130 297
f4a8c29f
GL
298 if (!m_serialObj) {
299 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
7a4b9130 300
f4a8c29f
GL
301 if (!m_serialObj) {
302 wxString message;
7a4b9130 303
f4a8c29f
GL
304 message.Printf("Can't find the serialization object (%s) for the object %s",
305 WXSTRINGCAST obj_name,
306 WXSTRINGCAST GetClassInfo()->GetClassName());
307 wxMessageBox(message, "Alert !");
308 return;
309 }
310 m_serialObj->SetObject(this);
311 }
6f34921d 312
f4a8c29f 313 m_serialObj->LoadObject(stream);
7a4b9130
GL
314}
315
c801d85f
KB
316#endif
317
318/*
319 * wxObject: cloning of objects
320 */
321
322void wxObject::Ref(const wxObject& clone)
323{
324 // delete reference to old data
325 UnRef();
326 // reference new data
327 if (clone.m_refData) {
328 m_refData = clone.m_refData;
329 ++(m_refData->m_count);
330 }
331}
332
333void wxObject::UnRef(void)
334{
335 if (m_refData) {
336 assert(m_refData->m_count > 0);
337 --(m_refData->m_count);
338 if (m_refData->m_count == 0)
339 delete m_refData;
340 }
c67daf87 341 m_refData = (wxObjectRefData *) NULL;
c801d85f
KB
342}
343
344/*
345 * wxObjectData
346 */
347
348wxObjectRefData::wxObjectRefData(void) : m_count(1)
349{
350}
351
352wxObjectRefData::~wxObjectRefData(void)
353{
354}
355