Eliminated some warnings under Windows; wxGetHomeDir problem in wxFile;
[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 #ifndef WX_PRECOMP
24 #include "wx/hash.h"
25 #ifdef USE_SERIAL
26 #include "wx/objstrm.h"
27 #include "wx/serbase.h"
28 #endif
29 #endif
30
31 #include <string.h>
32 #include <assert.h>
33
34 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
35 #include "wx/memory.h"
36 #endif
37
38 #if WXDEBUG || USE_DEBUG_CONTEXT
39 // for wxObject::Dump
40 #include <iostream.h>
41 #endif
42
43 #if !USE_SHARED_LIBRARY
44 wxClassInfo wxObject::sm_classwxObject((char *) "wxObject", (char *) NULL, (char *) NULL, (int ) sizeof(wxObject), (wxObjectConstructorFn) NULL);
45 wxClassInfo* wxClassInfo::sm_first = (wxClassInfo *) NULL;
46 wxHashTable* wxClassInfo::sm_classTable = (wxHashTable*) NULL;
47 #endif
48
49 /*
50 * wxWindows root object.
51 */
52
53 wxObject::wxObject(void)
54 {
55 m_refData = (wxObjectRefData *) NULL;
56 #ifdef USE_SERIAL
57 m_serialObj = (wxObject_Serialize *)NULL;
58 #endif
59 }
60
61 wxObject::~wxObject(void)
62 {
63 UnRef();
64 #ifdef USE_SERIAL
65 if (m_serialObj)
66 delete m_serialObj;
67 #endif
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
77 bool wxObject::IsKindOf(wxClassInfo *info)
78 {
79 wxClassInfo *thisInfo = GetClassInfo();
80 if (thisInfo)
81 return thisInfo->IsKindOf(info);
82 else
83 return FALSE;
84 }
85
86 #if WXDEBUG || USE_DEBUG_CONTEXT
87 void 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
96 #if WXDEBUG && USE_MEMORY_TRACING
97
98 #ifdef new
99 #undef new
100 #endif
101
102 void * wxObject::operator new (size_t size, char * fileName, int lineNum)
103 {
104 return wxDebugAlloc(size, fileName, lineNum, TRUE);
105 }
106
107 void wxObject::operator delete (void * buf)
108 {
109 wxDebugFree(buf);
110 }
111
112 // Cause problems for VC++ - crashes
113 #ifndef _MSC_VER
114 void * wxObject::operator new[] (size_t size, char * fileName, int lineNum)
115 {
116 return wxDebugAlloc(size, fileName, lineNum, TRUE, TRUE);
117 }
118
119 void 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
131 wxClassInfo::wxClassInfo(char *cName, char *baseName1, char *baseName2, int sz, wxObjectConstructorFn constr)
132 {
133 m_className = cName;
134 m_baseClassName1 = baseName1;
135 m_baseClassName2 = baseName2;
136
137 m_objectSize = sz;
138 m_objectConstructor = constr;
139
140 m_next = sm_first;
141 sm_first = this;
142
143 m_baseInfo1 = (wxClassInfo *) NULL;
144 m_baseInfo2 = (wxClassInfo *) NULL;
145 }
146
147 wxObject *wxClassInfo::CreateObject(void)
148 {
149 if (m_objectConstructor)
150 return (wxObject *)(*m_objectConstructor)();
151 else
152 return (wxObject *) NULL;
153 }
154
155 wxClassInfo *wxClassInfo::FindClass(char *c)
156 {
157 wxClassInfo *p = sm_first;
158 while (p)
159 {
160 if (p && p->GetClassName() && strcmp(p->GetClassName(), c) == 0)
161 return p;
162 p = p->m_next;
163 }
164 return (wxClassInfo *) NULL;
165 }
166
167 // Climb upwards through inheritance hierarchy.
168 // Dual inheritance is catered for.
169 bool 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.
177 // PROBABLY NO LONGER TRUE now I've done DLL creation right.
178 /*
179 #if WXMAKINGDLL
180 if (GetClassName() && info->GetClassName() && (strcmp(GetClassName(), info->GetClassName()) == 0))
181 return TRUE;
182 #else
183 */
184 if (this == info)
185 return TRUE;
186
187 if (m_baseInfo1)
188 if (m_baseInfo1->IsKindOf(info))
189 return TRUE;
190
191 if (m_baseInfo2)
192 return m_baseInfo2->IsKindOf(info);
193
194 return FALSE;
195 }
196
197 // Set pointers to base class(es) to speed up IsKindOf
198 void wxClassInfo::InitializeClasses(void)
199 {
200 wxClassInfo::sm_classTable = new wxHashTable(wxKEY_STRING);
201
202 // Index all class infos by their class name
203 wxClassInfo *info = sm_first;
204 while (info)
205 {
206 if (info->m_className)
207 sm_classTable->Put(info->m_className, (wxObject *)info);
208 info = info->m_next;
209 }
210
211 // Set base pointers for each wxClassInfo
212 info = sm_first;
213 while (info)
214 {
215 if (info->GetBaseClassName1())
216 info->m_baseInfo1 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName1());
217 if (info->GetBaseClassName2())
218 info->m_baseInfo2 = (wxClassInfo *)sm_classTable->Get(info->GetBaseClassName2());
219 info = info->m_next;
220 }
221 }
222
223 // Clean up hash table
224 void wxClassInfo::CleanUpClasses(void)
225 {
226 delete wxClassInfo::sm_classTable;
227 wxClassInfo::sm_classTable = NULL;
228 }
229
230 wxObject *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;
252 }
253
254 #ifdef USE_SERIAL
255
256 #include "wx/serbase.h"
257 #include "wx/dynlib.h"
258 #include "wx/msgdlg.h"
259
260 wxObject* wxCreateStoredObject( wxInputStream &stream )
261 {
262 wxObjectInputStream obj_s(stream);
263 return obj_s.LoadObject();
264 };
265
266 void wxObject::StoreObject( wxObjectOutputStream& stream )
267 {
268 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
269 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
270
271 if (!lib) {
272 wxMessageBox("Can't load wxSerial dynamic library.", "Alert !");
273 return;
274 }
275 if (!m_serialObj) {
276 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
277
278 if (!m_serialObj) {
279 wxString message;
280
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);
288 }
289
290 m_serialObj->StoreObject(stream);
291 }
292
293 void wxObject::LoadObject( wxObjectInputStream& stream )
294 {
295 wxString obj_name = wxString(GetClassInfo()->GetClassName()) + "_Serialize";
296 wxLibrary *lib = wxTheLibraries.LoadLibrary("wxserial");
297
298 if (!m_serialObj) {
299 m_serialObj = (WXSERIAL(wxObject) *)lib->CreateObject( obj_name );
300
301 if (!m_serialObj) {
302 wxString message;
303
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 }
312
313 m_serialObj->LoadObject(stream);
314 }
315
316 #endif
317
318 /*
319 * wxObject: cloning of objects
320 */
321
322 void 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
333 void 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 }
341 m_refData = (wxObjectRefData *) NULL;
342 }
343
344 /*
345 * wxObjectData
346 */
347
348 wxObjectRefData::wxObjectRefData(void) : m_count(1)
349 {
350 }
351
352 wxObjectRefData::~wxObjectRefData(void)
353 {
354 }
355