]> git.saurik.com Git - wxWidgets.git/blame - samples/xti/codereadercallback.cpp
Fix a crash in wxExecute() in wxMSW too.
[wxWidgets.git] / samples / xti / codereadercallback.cpp
CommitLineData
e1d3601a
PC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/xtistrm.cpp
3// Purpose: streaming runtime metadata information
4// Author: Stefan Csomor
5// Modified by:
6// Created: 27/07/03
7// RCS-ID: $Id$
8// Copyright: (c) 2003 Stefan Csomor
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// For compilers that support precompilation, includes "wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#include "wx/xtistrm.h"
20
21#ifndef WX_PRECOMP
22 #include "wx/object.h"
23 #include "wx/hash.h"
24 #include "wx/event.h"
25#endif
26
27#include <map>
28#include <vector>
29#include <string>
30using namespace std;
31
32#include "wx/tokenzr.h"
33#include "wx/txtstrm.h"
34#include "codereadercallback.h"
35
36#if !wxUSE_EXTENDED_RTTI
37 #error This sample requires XTI (eXtended RTTI) enabled
38#endif
39
40// ----------------------------------------------------------------------------
41// wxObjectCodeReaderCallback - depersisting to code
42// ----------------------------------------------------------------------------
43
44struct wxObjectCodeReaderCallback::wxObjectCodeReaderCallbackInternal
45{
46#if wxUSE_UNICODE
47 map<int,wstring> m_objectNames;
48#else
49 map<int,string> m_objectNames;
50#endif
51
52 void SetObjectName(int objectID, const wxString &name )
53 {
54 if ( m_objectNames.find(objectID) != m_objectNames.end() )
55 {
56 wxLogError( _("Passing a already registered object to SetObjectName") );
57 return ;
58 }
59 m_objectNames[objectID] = (const wxChar *)name;
60 }
61
62 wxString GetObjectName( int objectID )
63 {
64 if ( objectID == wxNullObjectID )
65 return wxT("NULL");
66
67 if ( m_objectNames.find(objectID) == m_objectNames.end() )
68 {
69 wxLogError( _("Passing an unkown object to GetObject") );
70 return wxEmptyString;
71 }
72 return wxString( m_objectNames[objectID].c_str() );
73 }
74};
75
1bf29304
SC
76wxObjectCodeReaderCallback::wxObjectCodeReaderCallback(wxString& headerincludes, wxString &source)
77: m_headerincludes(headerincludes),m_source(source)
e1d3601a
PC
78{
79 m_data = new wxObjectCodeReaderCallbackInternal;
80}
81
82wxObjectCodeReaderCallback::~wxObjectCodeReaderCallback()
83{
84 delete m_data;
85}
86
87void wxObjectCodeReaderCallback::AllocateObject(int objectID, wxClassInfo *classInfo,
1bf29304 88 wxStringToAnyHashMap &WXUNUSED(metadata))
e1d3601a 89{
1bf29304
SC
90 if ( classInfo->GetIncludeName() != wxEmptyString)
91 {
92 // add corresponding header if not already included
93 wxString include;
94 include.Printf(wxT("#include \"%s\"\n"),classInfo->GetIncludeName());
95 if ( m_headerincludes.Find(include) == wxNOT_FOUND)
96 m_headerincludes += include;
97 }
98
e1d3601a 99 wxString objectName = wxString::Format( wxT("LocalObject_%d"), objectID );
1bf29304 100 m_source += ( wxString::Format( wxT("\t%s *%s = new %s;\n"),
e1d3601a
PC
101 classInfo->GetClassName(),
102 objectName.c_str(),
103 classInfo->GetClassName()) );
104 m_data->SetObjectName( objectID, objectName );
105}
106
107void wxObjectCodeReaderCallback::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
108{
1bf29304 109 m_source += ( wxString::Format( wxT("\tdelete %s;\n"),
e1d3601a
PC
110 m_data->GetObjectName( objectID).c_str() ) );
111}
112
1bf29304
SC
113class WXDLLIMPEXP_BASE wxObjectConstructorWriter: public wxObjectWriterFunctor
114{
115public:
116 wxObjectConstructorWriter(const wxClassTypeInfo* cti,
117 wxObjectCodeReaderCallback* writer) :
118 m_cti(cti),m_writer(writer)
119 {}
120
121 virtual void operator()(const wxObject *vobj)
122 {
123 const wxClassInfo* ci = m_cti->GetClassInfo();
124
125 for ( int i = 0; i < ci->GetCreateParamCount(); ++i )
126 {
127 wxString name = ci->GetCreateParamName(i);
128 const wxPropertyInfo* prop = ci->FindPropertyInfo(name);
129 if ( i > 0 )
130 m_constructor += ", ";
131 wxAny value;
132 prop->GetAccessor()->GetProperty(vobj, value);
133 m_constructor+= m_writer->ValueAsCode(value);
134 }
135 }
136
137 const wxString& GetConstructorString() const { return m_constructor;}
138private:
139 const wxClassTypeInfo* m_cti;
140 wxObjectCodeReaderCallback* m_writer;
141 wxString m_constructor;
142};
143
144wxString wxObjectCodeReaderCallback::ValueAsCode( const wxAny &param )
e1d3601a
PC
145{
146 wxString value;
1bf29304 147
e1d3601a
PC
148 const wxTypeInfo* type = param.GetTypeInfo();
149 if ( type->GetKind() == wxT_CUSTOM )
150 {
151 const wxCustomTypeInfo* cti = wx_dynamic_cast(const wxCustomTypeInfo*, type);
152 if ( cti )
153 {
154 value.Printf( wxT("%s(%s)"), cti->GetTypeName().c_str(),
1bf29304 155 wxAnyGetAsString(param).c_str() );
e1d3601a
PC
156 }
157 else
158 {
159 wxLogError ( _("Internal error, illegal wxCustomTypeInfo") );
160 }
161 }
162 else if ( type->GetKind() == wxT_STRING )
163 {
1bf29304
SC
164 value.Printf( wxT("\"%s\""), wxAnyGetAsString(param).c_str() );
165 }
166 else if ( type->GetKind() == wxT_OBJECT )
167 {
168 const wxClassTypeInfo* ctype = wx_dynamic_cast(const wxClassTypeInfo*,type);
169 const wxClassInfo* ci = ctype->GetClassInfo();
170 if( ci->NeedsDirectConstruction())
171 {
172 wxObjectConstructorWriter cw(ctype,this);
173
174 ci->CallOnAny(param,&cw);
175
176 value.Printf( wxT("%s(%s)"), ctype->GetClassInfo()->GetClassName(),
177 cw.GetConstructorString() );
178 }
e1d3601a
PC
179 }
180 else
181 {
1bf29304 182 value.Printf( wxT("%s"), wxAnyGetAsString(param).c_str() );
e1d3601a 183 }
1bf29304 184
e1d3601a
PC
185 return value;
186}
187
188void wxObjectCodeReaderCallback::CreateObject(int objectID,
189 const wxClassInfo *WXUNUSED(classInfo),
190 int paramCount,
1bf29304 191 wxAny *params,
e1d3601a
PC
192 int *objectIDValues,
193 const wxClassInfo **WXUNUSED(objectClassInfos),
1bf29304 194 wxStringToAnyHashMap &WXUNUSED(metadata)
e1d3601a
PC
195 )
196{
197 int i;
1bf29304 198 m_source += ( wxString::Format( wxT("\t%s->Create("),
e1d3601a
PC
199 m_data->GetObjectName(objectID).c_str() ) );
200 for (i = 0; i < paramCount; i++)
201 {
202 if ( objectIDValues[i] != wxInvalidObjectID )
203 {
204 wxString str =
205 wxString::Format( wxT("%s"),
206 m_data->GetObjectName( objectIDValues[i] ).c_str() );
1bf29304 207 m_source += ( str );
e1d3601a
PC
208 }
209 else
210 {
1bf29304 211 m_source += (
e1d3601a
PC
212 wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
213 }
214 if (i < paramCount - 1)
1bf29304 215 m_source += ( wxT(", "));
e1d3601a 216 }
1bf29304 217 m_source += ( wxT(");\n") );
e1d3601a
PC
218}
219
220void wxObjectCodeReaderCallback::ConstructObject(int objectID,
221 const wxClassInfo *classInfo,
222 int paramCount,
1bf29304 223 wxAny *params,
e1d3601a
PC
224 int *objectIDValues,
225 const wxClassInfo **WXUNUSED(objectClassInfos),
1bf29304 226 wxStringToAnyHashMap &WXUNUSED(metadata)
e1d3601a
PC
227 )
228{
229 wxString objectName = wxString::Format( wxT("LocalObject_%d"), objectID );
1bf29304 230 m_source += ( wxString::Format( wxT("\t%s *%s = new %s("),
e1d3601a
PC
231 classInfo->GetClassName(),
232 objectName.c_str(),
233 classInfo->GetClassName()) );
234 m_data->SetObjectName( objectID, objectName );
235
236 int i;
237 for (i = 0; i < paramCount; i++)
238 {
239 if ( objectIDValues[i] != wxInvalidObjectID )
1bf29304 240 m_source += ( wxString::Format( wxT("%s"),
e1d3601a
PC
241 m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
242 else
243 {
1bf29304 244 m_source += (
e1d3601a
PC
245 wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
246 }
247 if (i < paramCount - 1)
1bf29304 248 m_source += ( wxT(", ") );
e1d3601a 249 }
1bf29304 250 m_source += ( wxT(");\n") );
e1d3601a
PC
251}
252
253void wxObjectCodeReaderCallback::SetProperty(int objectID,
254 const wxClassInfo *WXUNUSED(classInfo),
255 const wxPropertyInfo* propertyInfo,
1bf29304 256 const wxAny &value)
e1d3601a 257{
1bf29304 258 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
259 m_data->GetObjectName(objectID).c_str(),
260 propertyInfo->GetAccessor()->GetSetterName().c_str(),
261 ValueAsCode(value).c_str()) );
262}
263
264void wxObjectCodeReaderCallback::SetPropertyAsObject(int objectID,
265 const wxClassInfo *WXUNUSED(classInfo),
266 const wxPropertyInfo* propertyInfo,
267 int valueObjectId)
268{
269 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
1bf29304 270 m_source += ( wxString::Format( wxT("\t%s->%s(*%s);\n"),
e1d3601a
PC
271 m_data->GetObjectName(objectID).c_str(),
272 propertyInfo->GetAccessor()->GetSetterName().c_str(),
273 m_data->GetObjectName( valueObjectId).c_str() ) );
274 else
1bf29304 275 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
276 m_data->GetObjectName(objectID).c_str(),
277 propertyInfo->GetAccessor()->GetSetterName().c_str(),
278 m_data->GetObjectName( valueObjectId).c_str() ) );
279}
280
281void wxObjectCodeReaderCallback::AddToPropertyCollection( int objectID,
282 const wxClassInfo *WXUNUSED(classInfo),
283 const wxPropertyInfo* propertyInfo,
1bf29304 284 const wxAny &value)
e1d3601a 285{
1bf29304 286 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
287 m_data->GetObjectName(objectID).c_str(),
288 propertyInfo->GetAccessor()->GetAdderName().c_str(),
289 ValueAsCode(value).c_str()) );
290}
291
292// sets the corresponding property (value is an object)
293void wxObjectCodeReaderCallback::
294 AddToPropertyCollectionAsObject(int WXUNUSED(objectID),
295 const wxClassInfo *WXUNUSED(classInfo),
296 const wxPropertyInfo* WXUNUSED(propertyInfo),
297 int WXUNUSED(valueObjectId))
298{
299 // TODO
300}
301
302void wxObjectCodeReaderCallback::SetConnect(int eventSourceObjectID,
303 const wxClassInfo *WXUNUSED(eventSourceClassInfo),
304 const wxPropertyInfo *delegateInfo,
305 const wxClassInfo *eventSinkClassInfo,
306 const wxHandlerInfo* handlerInfo,
307 int eventSinkObjectID )
308{
309 wxString ehsource = m_data->GetObjectName( eventSourceObjectID );
310 wxString ehsink = m_data->GetObjectName(eventSinkObjectID);
311 wxString ehsinkClass = eventSinkClassInfo->GetClassName();
312 const wxEventSourceTypeInfo *delegateTypeInfo =
313 wx_dynamic_cast(const wxEventSourceTypeInfo*, delegateInfo->GetTypeInfo());
314 if ( delegateTypeInfo )
315 {
316 int eventType = delegateTypeInfo->GetEventType();
317 wxString handlerName = handlerInfo->GetName();
318
319 wxString code =
320 wxString::Format(
321 wxT("\t%s->Connect( %s->GetId(), %d, ")
322 wxT("(wxObjectEventFunction)(wxEventFunction) & %s::%s, NULL, %s );"),
323 ehsource.c_str(), ehsource.c_str(), eventType, ehsinkClass.c_str(),
324 handlerName.c_str(), ehsink.c_str() );
325
1bf29304 326 m_source += ( code );
e1d3601a
PC
327 }
328 else
329 {
330 wxLogError(_("delegate has no type info"));
331 }
332}