]> git.saurik.com Git - wxWidgets.git/blame - samples/xti/codereadercallback.cpp
Compilation fix to propgrid sample after r74628.
[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
e1d3601a
PC
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>
29using 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
43struct 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
1bf29304
SC
75wxObjectCodeReaderCallback::wxObjectCodeReaderCallback(wxString& headerincludes, wxString &source)
76: m_headerincludes(headerincludes),m_source(source)
e1d3601a
PC
77{
78 m_data = new wxObjectCodeReaderCallbackInternal;
79}
80
81wxObjectCodeReaderCallback::~wxObjectCodeReaderCallback()
82{
83 delete m_data;
84}
85
86void wxObjectCodeReaderCallback::AllocateObject(int objectID, wxClassInfo *classInfo,
1bf29304 87 wxStringToAnyHashMap &WXUNUSED(metadata))
e1d3601a 88{
1bf29304
SC
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
e1d3601a 98 wxString objectName = wxString::Format( wxT("LocalObject_%d"), objectID );
1bf29304 99 m_source += ( wxString::Format( wxT("\t%s *%s = new %s;\n"),
e1d3601a
PC
100 classInfo->GetClassName(),
101 objectName.c_str(),
102 classInfo->GetClassName()) );
103 m_data->SetObjectName( objectID, objectName );
104}
105
106void wxObjectCodeReaderCallback::DestroyObject(int objectID, wxClassInfo *WXUNUSED(classInfo))
107{
1bf29304 108 m_source += ( wxString::Format( wxT("\tdelete %s;\n"),
e1d3601a
PC
109 m_data->GetObjectName( objectID).c_str() ) );
110}
111
1bf29304
SC
112class WXDLLIMPEXP_BASE wxObjectConstructorWriter: public wxObjectWriterFunctor
113{
114public:
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;}
137private:
138 const wxClassTypeInfo* m_cti;
139 wxObjectCodeReaderCallback* m_writer;
140 wxString m_constructor;
141};
142
143wxString wxObjectCodeReaderCallback::ValueAsCode( const wxAny &param )
e1d3601a
PC
144{
145 wxString value;
1bf29304 146
e1d3601a
PC
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(),
1bf29304 154 wxAnyGetAsString(param).c_str() );
e1d3601a
PC
155 }
156 else
157 {
158 wxLogError ( _("Internal error, illegal wxCustomTypeInfo") );
159 }
160 }
161 else if ( type->GetKind() == wxT_STRING )
162 {
1bf29304
SC
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 }
e1d3601a
PC
178 }
179 else
180 {
1bf29304 181 value.Printf( wxT("%s"), wxAnyGetAsString(param).c_str() );
e1d3601a 182 }
1bf29304 183
e1d3601a
PC
184 return value;
185}
186
187void wxObjectCodeReaderCallback::CreateObject(int objectID,
188 const wxClassInfo *WXUNUSED(classInfo),
189 int paramCount,
1bf29304 190 wxAny *params,
e1d3601a
PC
191 int *objectIDValues,
192 const wxClassInfo **WXUNUSED(objectClassInfos),
1bf29304 193 wxStringToAnyHashMap &WXUNUSED(metadata)
e1d3601a
PC
194 )
195{
196 int i;
1bf29304 197 m_source += ( wxString::Format( wxT("\t%s->Create("),
e1d3601a
PC
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() );
1bf29304 206 m_source += ( str );
e1d3601a
PC
207 }
208 else
209 {
1bf29304 210 m_source += (
e1d3601a
PC
211 wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
212 }
213 if (i < paramCount - 1)
1bf29304 214 m_source += ( wxT(", "));
e1d3601a 215 }
1bf29304 216 m_source += ( wxT(");\n") );
e1d3601a
PC
217}
218
219void wxObjectCodeReaderCallback::ConstructObject(int objectID,
220 const wxClassInfo *classInfo,
221 int paramCount,
1bf29304 222 wxAny *params,
e1d3601a
PC
223 int *objectIDValues,
224 const wxClassInfo **WXUNUSED(objectClassInfos),
1bf29304 225 wxStringToAnyHashMap &WXUNUSED(metadata)
e1d3601a
PC
226 )
227{
228 wxString objectName = wxString::Format( wxT("LocalObject_%d"), objectID );
1bf29304 229 m_source += ( wxString::Format( wxT("\t%s *%s = new %s("),
e1d3601a
PC
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 )
1bf29304 239 m_source += ( wxString::Format( wxT("%s"),
e1d3601a
PC
240 m_data->GetObjectName( objectIDValues[i] ).c_str() ) );
241 else
242 {
1bf29304 243 m_source += (
e1d3601a
PC
244 wxString::Format( wxT("%s"), ValueAsCode(params[i]).c_str() ) );
245 }
246 if (i < paramCount - 1)
1bf29304 247 m_source += ( wxT(", ") );
e1d3601a 248 }
1bf29304 249 m_source += ( wxT(");\n") );
e1d3601a
PC
250}
251
252void wxObjectCodeReaderCallback::SetProperty(int objectID,
253 const wxClassInfo *WXUNUSED(classInfo),
254 const wxPropertyInfo* propertyInfo,
1bf29304 255 const wxAny &value)
e1d3601a 256{
1bf29304 257 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
258 m_data->GetObjectName(objectID).c_str(),
259 propertyInfo->GetAccessor()->GetSetterName().c_str(),
260 ValueAsCode(value).c_str()) );
261}
262
263void wxObjectCodeReaderCallback::SetPropertyAsObject(int objectID,
264 const wxClassInfo *WXUNUSED(classInfo),
265 const wxPropertyInfo* propertyInfo,
266 int valueObjectId)
267{
268 if ( propertyInfo->GetTypeInfo()->GetKind() == wxT_OBJECT )
1bf29304 269 m_source += ( wxString::Format( wxT("\t%s->%s(*%s);\n"),
e1d3601a
PC
270 m_data->GetObjectName(objectID).c_str(),
271 propertyInfo->GetAccessor()->GetSetterName().c_str(),
272 m_data->GetObjectName( valueObjectId).c_str() ) );
273 else
1bf29304 274 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
275 m_data->GetObjectName(objectID).c_str(),
276 propertyInfo->GetAccessor()->GetSetterName().c_str(),
277 m_data->GetObjectName( valueObjectId).c_str() ) );
278}
279
280void wxObjectCodeReaderCallback::AddToPropertyCollection( int objectID,
281 const wxClassInfo *WXUNUSED(classInfo),
282 const wxPropertyInfo* propertyInfo,
1bf29304 283 const wxAny &value)
e1d3601a 284{
1bf29304 285 m_source += ( wxString::Format( wxT("\t%s->%s(%s);\n"),
e1d3601a
PC
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)
292void 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
301void 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
1bf29304 325 m_source += ( code );
e1d3601a
PC
326 }
327 else
328 {
329 wxLogError(_("delegate has no type info"));
330 }
331}