]> git.saurik.com Git - wxWidgets.git/blame - src/common/object.cpp
speed optimizations: some functions now use wxString::Alloc, wxTextFile::Read
[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
23#include "wx/hash.h"
24
25#include <string.h>
26#include <assert.h>
27
b2aef89b 28#if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
c801d85f
KB
29#include "wx/memory.h"
30#endif
31
b2aef89b 32#if WXDEBUG || USE_DEBUG_CONTEXT
c801d85f
KB
33 // for wxObject::Dump
34 #include <iostream.h>
35#endif
36
37#if !USE_SHARED_LIBRARY
38wxClassInfo wxObject::classwxObject("wxObject", NULL, NULL, sizeof(wxObject), NULL);
39wxClassInfo *wxClassInfo::first = NULL;
40#endif
41
42/*
43 * wxWindows root object.
44 */
45
46wxObject::wxObject(void)
47{
48 m_refData = NULL;
49}
50
51wxObject::~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
63bool wxObject::IsKindOf(wxClassInfo *info)
64{
65 wxClassInfo *thisInfo = GetClassInfo();
66 if (thisInfo)
67 return thisInfo->IsKindOf(info);
68 else
69 return FALSE;
70}
71
b2aef89b 72#if WXDEBUG || USE_DEBUG_CONTEXT
c801d85f
KB
73void 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
b2aef89b 82#if WXDEBUG && USE_MEMORY_TRACING
c801d85f
KB
83
84#ifdef new
85#undef new
86#endif
87
88void * wxObject::operator new (size_t size, char * fileName, int lineNum)
89{
90 return wxDebugAlloc(size, fileName, lineNum, TRUE);
91}
92
93void wxObject::operator delete (void * buf)
94{
95 wxDebugFree(buf);
96}
97
98// Cause problems for VC++ - crashes
99#ifndef _MSC_VER
100void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
101{
102 return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
103}
104
105void 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
119wxClassInfo::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
137wxObject* 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
147wxClassInfo::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
165wxObject *wxClassInfo::CreateObject(void)
166{
167 if (objectConstructor)
168 return (wxObject *)(*objectConstructor)();
169 else
170 return NULL;
171}
172
173wxClassInfo *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.
187bool 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
214void 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
239wxObject *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
253wxObject* 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
271void 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
282void 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
297wxObjectRefData::wxObjectRefData(void) : m_count(1)
298{
299}
300
301wxObjectRefData::~wxObjectRefData(void)
302{
303}
304