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