1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xtistrm.cpp
3 // Purpose: streaming runtime metadata information
4 // Author: Stefan Csomor
8 // Copyright: (c) 2003 Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 #include "wx/xtistrm.h"
22 #include "wx/object.h"
32 #include "wx/tokenzr.h"
33 #include "wx/txtstrm.h"
34 #include "codereadercallback.h"
36 #if !wxUSE_EXTENDED_RTTI
37 #error This sample requires XTI (eXtended RTTI) enabled
40 // ----------------------------------------------------------------------------
41 // wxObjectCodeReaderCallback - depersisting to code
42 // ----------------------------------------------------------------------------
44 struct wxObjectCodeReaderCallback::wxObjectCodeReaderCallbackInternal
47 map
<int,wstring
> m_objectNames
;
49 map
<int,string
> m_objectNames
;
52 void SetObjectName(int objectID
, const wxString
&name
)
54 if ( m_objectNames
.find(objectID
) != m_objectNames
.end() )
56 wxLogError( _("Passing a already registered object to SetObjectName") );
59 m_objectNames
[objectID
] = (const wxChar
*)name
;
62 wxString
GetObjectName( int objectID
)
64 if ( objectID
== wxNullObjectID
)
67 if ( m_objectNames
.find(objectID
) == m_objectNames
.end() )
69 wxLogError( _("Passing an unkown object to GetObject") );
72 return wxString( m_objectNames
[objectID
].c_str() );
76 wxObjectCodeReaderCallback::wxObjectCodeReaderCallback(wxString
& headerincludes
, wxString
&source
)
77 : m_headerincludes(headerincludes
),m_source(source
)
79 m_data
= new wxObjectCodeReaderCallbackInternal
;
82 wxObjectCodeReaderCallback::~wxObjectCodeReaderCallback()
87 void wxObjectCodeReaderCallback::AllocateObject(int objectID
, wxClassInfo
*classInfo
,
88 wxStringToAnyHashMap
&WXUNUSED(metadata
))
90 if ( classInfo
->GetIncludeName() != wxEmptyString
)
92 // add corresponding header if not already included
94 include
.Printf(wxT("#include \"%s\"\n"),classInfo
->GetIncludeName());
95 if ( m_headerincludes
.Find(include
) == wxNOT_FOUND
)
96 m_headerincludes
+= include
;
99 wxString objectName
= wxString::Format( wxT("LocalObject_%d"), objectID
);
100 m_source
+= ( wxString::Format( wxT("\t%s *%s = new %s;\n"),
101 classInfo
->GetClassName(),
103 classInfo
->GetClassName()) );
104 m_data
->SetObjectName( objectID
, objectName
);
107 void wxObjectCodeReaderCallback::DestroyObject(int objectID
, wxClassInfo
*WXUNUSED(classInfo
))
109 m_source
+= ( wxString::Format( wxT("\tdelete %s;\n"),
110 m_data
->GetObjectName( objectID
).c_str() ) );
113 class WXDLLIMPEXP_BASE wxObjectConstructorWriter
: public wxObjectWriterFunctor
116 wxObjectConstructorWriter(const wxClassTypeInfo
* cti
,
117 wxObjectCodeReaderCallback
* writer
) :
118 m_cti(cti
),m_writer(writer
)
121 virtual void operator()(const wxObject
*vobj
)
123 const wxClassInfo
* ci
= m_cti
->GetClassInfo();
125 for ( int i
= 0; i
< ci
->GetCreateParamCount(); ++i
)
127 wxString name
= ci
->GetCreateParamName(i
);
128 const wxPropertyInfo
* prop
= ci
->FindPropertyInfo(name
);
130 m_constructor
+= ", ";
132 prop
->GetAccessor()->GetProperty(vobj
, value
);
133 m_constructor
+= m_writer
->ValueAsCode(value
);
137 const wxString
& GetConstructorString() const { return m_constructor
;}
139 const wxClassTypeInfo
* m_cti
;
140 wxObjectCodeReaderCallback
* m_writer
;
141 wxString m_constructor
;
144 wxString
wxObjectCodeReaderCallback::ValueAsCode( const wxAny
¶m
)
148 const wxTypeInfo
* type
= param
.GetTypeInfo();
149 if ( type
->GetKind() == wxT_CUSTOM
)
151 const wxCustomTypeInfo
* cti
= wx_dynamic_cast(const wxCustomTypeInfo
*, type
);
154 value
.Printf( wxT("%s(%s)"), cti
->GetTypeName().c_str(),
155 wxAnyGetAsString(param
).c_str() );
159 wxLogError ( _("Internal error, illegal wxCustomTypeInfo") );
162 else if ( type
->GetKind() == wxT_STRING
)
164 value
.Printf( wxT("\"%s\""), wxAnyGetAsString(param
).c_str() );
166 else if ( type
->GetKind() == wxT_OBJECT
)
168 const wxClassTypeInfo
* ctype
= wx_dynamic_cast(const wxClassTypeInfo
*,type
);
169 const wxClassInfo
* ci
= ctype
->GetClassInfo();
170 if( ci
->NeedsDirectConstruction())
172 wxObjectConstructorWriter
cw(ctype
,this);
174 ci
->CallOnAny(param
,&cw
);
176 value
.Printf( wxT("%s(%s)"), ctype
->GetClassInfo()->GetClassName(),
177 cw
.GetConstructorString() );
182 value
.Printf( wxT("%s"), wxAnyGetAsString(param
).c_str() );
188 void wxObjectCodeReaderCallback::CreateObject(int objectID
,
189 const wxClassInfo
*WXUNUSED(classInfo
),
193 const wxClassInfo
**WXUNUSED(objectClassInfos
),
194 wxStringToAnyHashMap
&WXUNUSED(metadata
)
198 m_source
+= ( wxString::Format( wxT("\t%s->Create("),
199 m_data
->GetObjectName(objectID
).c_str() ) );
200 for (i
= 0; i
< paramCount
; i
++)
202 if ( objectIDValues
[i
] != wxInvalidObjectID
)
205 wxString::Format( wxT("%s"),
206 m_data
->GetObjectName( objectIDValues
[i
] ).c_str() );
212 wxString::Format( wxT("%s"), ValueAsCode(params
[i
]).c_str() ) );
214 if (i
< paramCount
- 1)
215 m_source
+= ( wxT(", "));
217 m_source
+= ( wxT(");\n") );
220 void wxObjectCodeReaderCallback::ConstructObject(int objectID
,
221 const wxClassInfo
*classInfo
,
225 const wxClassInfo
**WXUNUSED(objectClassInfos
),
226 wxStringToAnyHashMap
&WXUNUSED(metadata
)
229 wxString objectName
= wxString::Format( wxT("LocalObject_%d"), objectID
);
230 m_source
+= ( wxString::Format( wxT("\t%s *%s = new %s("),
231 classInfo
->GetClassName(),
233 classInfo
->GetClassName()) );
234 m_data
->SetObjectName( objectID
, objectName
);
237 for (i
= 0; i
< paramCount
; i
++)
239 if ( objectIDValues
[i
] != wxInvalidObjectID
)
240 m_source
+= ( wxString::Format( wxT("%s"),
241 m_data
->GetObjectName( objectIDValues
[i
] ).c_str() ) );
245 wxString::Format( wxT("%s"), ValueAsCode(params
[i
]).c_str() ) );
247 if (i
< paramCount
- 1)
248 m_source
+= ( wxT(", ") );
250 m_source
+= ( wxT(");\n") );
253 void wxObjectCodeReaderCallback::SetProperty(int objectID
,
254 const wxClassInfo
*WXUNUSED(classInfo
),
255 const wxPropertyInfo
* propertyInfo
,
258 m_source
+= ( wxString::Format( wxT("\t%s->%s(%s);\n"),
259 m_data
->GetObjectName(objectID
).c_str(),
260 propertyInfo
->GetAccessor()->GetSetterName().c_str(),
261 ValueAsCode(value
).c_str()) );
264 void wxObjectCodeReaderCallback::SetPropertyAsObject(int objectID
,
265 const wxClassInfo
*WXUNUSED(classInfo
),
266 const wxPropertyInfo
* propertyInfo
,
269 if ( propertyInfo
->GetTypeInfo()->GetKind() == wxT_OBJECT
)
270 m_source
+= ( wxString::Format( wxT("\t%s->%s(*%s);\n"),
271 m_data
->GetObjectName(objectID
).c_str(),
272 propertyInfo
->GetAccessor()->GetSetterName().c_str(),
273 m_data
->GetObjectName( valueObjectId
).c_str() ) );
275 m_source
+= ( wxString::Format( wxT("\t%s->%s(%s);\n"),
276 m_data
->GetObjectName(objectID
).c_str(),
277 propertyInfo
->GetAccessor()->GetSetterName().c_str(),
278 m_data
->GetObjectName( valueObjectId
).c_str() ) );
281 void wxObjectCodeReaderCallback::AddToPropertyCollection( int objectID
,
282 const wxClassInfo
*WXUNUSED(classInfo
),
283 const wxPropertyInfo
* propertyInfo
,
286 m_source
+= ( wxString::Format( wxT("\t%s->%s(%s);\n"),
287 m_data
->GetObjectName(objectID
).c_str(),
288 propertyInfo
->GetAccessor()->GetAdderName().c_str(),
289 ValueAsCode(value
).c_str()) );
292 // sets the corresponding property (value is an object)
293 void wxObjectCodeReaderCallback::
294 AddToPropertyCollectionAsObject(int WXUNUSED(objectID
),
295 const wxClassInfo
*WXUNUSED(classInfo
),
296 const wxPropertyInfo
* WXUNUSED(propertyInfo
),
297 int WXUNUSED(valueObjectId
))
302 void wxObjectCodeReaderCallback::SetConnect(int eventSourceObjectID
,
303 const wxClassInfo
*WXUNUSED(eventSourceClassInfo
),
304 const wxPropertyInfo
*delegateInfo
,
305 const wxClassInfo
*eventSinkClassInfo
,
306 const wxHandlerInfo
* handlerInfo
,
307 int eventSinkObjectID
)
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
)
316 int eventType
= delegateTypeInfo
->GetEventType();
317 wxString handlerName
= handlerInfo
->GetName();
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() );
326 m_source
+= ( code
);
330 wxLogError(_("delegate has no type info"));