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