1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/xtistrm.cpp
3 // Purpose: streaming runtime metadata information
4 // Author: Stefan Csomor
7 // Copyright: (c) 2003 Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
18 #include "wx/xtistrm.h"
21 #include "wx/object.h"
31 #include "wx/tokenzr.h"
32 #include "wx/txtstrm.h"
33 #include "codereadercallback.h"
35 #if !wxUSE_EXTENDED_RTTI
36 #error This sample requires XTI (eXtended RTTI) enabled
39 // ----------------------------------------------------------------------------
40 // wxObjectCodeReaderCallback - depersisting to code
41 // ----------------------------------------------------------------------------
43 struct wxObjectCodeReaderCallback::wxObjectCodeReaderCallbackInternal
46 map
<int,wstring
> m_objectNames
;
48 map
<int,string
> m_objectNames
;
51 void SetObjectName(int objectID
, const wxString
&name
)
53 if ( m_objectNames
.find(objectID
) != m_objectNames
.end() )
55 wxLogError( _("Passing a already registered object to SetObjectName") );
58 m_objectNames
[objectID
] = (const wxChar
*)name
;
61 wxString
GetObjectName( int objectID
)
63 if ( objectID
== wxNullObjectID
)
66 if ( m_objectNames
.find(objectID
) == m_objectNames
.end() )
68 wxLogError( _("Passing an unkown object to GetObject") );
71 return wxString( m_objectNames
[objectID
].c_str() );
75 wxObjectCodeReaderCallback::wxObjectCodeReaderCallback(wxString
& headerincludes
, wxString
&source
)
76 : m_headerincludes(headerincludes
),m_source(source
)
78 m_data
= new wxObjectCodeReaderCallbackInternal
;
81 wxObjectCodeReaderCallback::~wxObjectCodeReaderCallback()
86 void wxObjectCodeReaderCallback::AllocateObject(int objectID
, wxClassInfo
*classInfo
,
87 wxStringToAnyHashMap
&WXUNUSED(metadata
))
89 if ( classInfo
->GetIncludeName() != wxEmptyString
)
91 // add corresponding header if not already included
93 include
.Printf(wxT("#include \"%s\"\n"),classInfo
->GetIncludeName());
94 if ( m_headerincludes
.Find(include
) == wxNOT_FOUND
)
95 m_headerincludes
+= include
;
98 wxString objectName
= wxString::Format( wxT("LocalObject_%d"), objectID
);
99 m_source
+= ( wxString::Format( wxT("\t%s *%s = new %s;\n"),
100 classInfo
->GetClassName(),
102 classInfo
->GetClassName()) );
103 m_data
->SetObjectName( objectID
, objectName
);
106 void wxObjectCodeReaderCallback::DestroyObject(int objectID
, wxClassInfo
*WXUNUSED(classInfo
))
108 m_source
+= ( wxString::Format( wxT("\tdelete %s;\n"),
109 m_data
->GetObjectName( objectID
).c_str() ) );
112 class WXDLLIMPEXP_BASE wxObjectConstructorWriter
: public wxObjectWriterFunctor
115 wxObjectConstructorWriter(const wxClassTypeInfo
* cti
,
116 wxObjectCodeReaderCallback
* writer
) :
117 m_cti(cti
),m_writer(writer
)
120 virtual void operator()(const wxObject
*vobj
)
122 const wxClassInfo
* ci
= m_cti
->GetClassInfo();
124 for ( int i
= 0; i
< ci
->GetCreateParamCount(); ++i
)
126 wxString name
= ci
->GetCreateParamName(i
);
127 const wxPropertyInfo
* prop
= ci
->FindPropertyInfo(name
);
129 m_constructor
+= ", ";
131 prop
->GetAccessor()->GetProperty(vobj
, value
);
132 m_constructor
+= m_writer
->ValueAsCode(value
);
136 const wxString
& GetConstructorString() const { return m_constructor
;}
138 const wxClassTypeInfo
* m_cti
;
139 wxObjectCodeReaderCallback
* m_writer
;
140 wxString m_constructor
;
143 wxString
wxObjectCodeReaderCallback::ValueAsCode( const wxAny
¶m
)
147 const wxTypeInfo
* type
= param
.GetTypeInfo();
148 if ( type
->GetKind() == wxT_CUSTOM
)
150 const wxCustomTypeInfo
* cti
= wx_dynamic_cast(const wxCustomTypeInfo
*, type
);
153 value
.Printf( wxT("%s(%s)"), cti
->GetTypeName().c_str(),
154 wxAnyGetAsString(param
).c_str() );
158 wxLogError ( _("Internal error, illegal wxCustomTypeInfo") );
161 else if ( type
->GetKind() == wxT_STRING
)
163 value
.Printf( wxT("\"%s\""), wxAnyGetAsString(param
).c_str() );
165 else if ( type
->GetKind() == wxT_OBJECT
)
167 const wxClassTypeInfo
* ctype
= wx_dynamic_cast(const wxClassTypeInfo
*,type
);
168 const wxClassInfo
* ci
= ctype
->GetClassInfo();
169 if( ci
->NeedsDirectConstruction())
171 wxObjectConstructorWriter
cw(ctype
,this);
173 ci
->CallOnAny(param
,&cw
);
175 value
.Printf( wxT("%s(%s)"), ctype
->GetClassInfo()->GetClassName(),
176 cw
.GetConstructorString() );
181 value
.Printf( wxT("%s"), wxAnyGetAsString(param
).c_str() );
187 void wxObjectCodeReaderCallback::CreateObject(int objectID
,
188 const wxClassInfo
*WXUNUSED(classInfo
),
192 const wxClassInfo
**WXUNUSED(objectClassInfos
),
193 wxStringToAnyHashMap
&WXUNUSED(metadata
)
197 m_source
+= ( wxString::Format( wxT("\t%s->Create("),
198 m_data
->GetObjectName(objectID
).c_str() ) );
199 for (i
= 0; i
< paramCount
; i
++)
201 if ( objectIDValues
[i
] != wxInvalidObjectID
)
204 wxString::Format( wxT("%s"),
205 m_data
->GetObjectName( objectIDValues
[i
] ).c_str() );
211 wxString::Format( wxT("%s"), ValueAsCode(params
[i
]).c_str() ) );
213 if (i
< paramCount
- 1)
214 m_source
+= ( wxT(", "));
216 m_source
+= ( wxT(");\n") );
219 void wxObjectCodeReaderCallback::ConstructObject(int objectID
,
220 const wxClassInfo
*classInfo
,
224 const wxClassInfo
**WXUNUSED(objectClassInfos
),
225 wxStringToAnyHashMap
&WXUNUSED(metadata
)
228 wxString objectName
= wxString::Format( wxT("LocalObject_%d"), objectID
);
229 m_source
+= ( wxString::Format( wxT("\t%s *%s = new %s("),
230 classInfo
->GetClassName(),
232 classInfo
->GetClassName()) );
233 m_data
->SetObjectName( objectID
, objectName
);
236 for (i
= 0; i
< paramCount
; i
++)
238 if ( objectIDValues
[i
] != wxInvalidObjectID
)
239 m_source
+= ( wxString::Format( wxT("%s"),
240 m_data
->GetObjectName( objectIDValues
[i
] ).c_str() ) );
244 wxString::Format( wxT("%s"), ValueAsCode(params
[i
]).c_str() ) );
246 if (i
< paramCount
- 1)
247 m_source
+= ( wxT(", ") );
249 m_source
+= ( wxT(");\n") );
252 void wxObjectCodeReaderCallback::SetProperty(int objectID
,
253 const wxClassInfo
*WXUNUSED(classInfo
),
254 const wxPropertyInfo
* propertyInfo
,
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()) );
263 void wxObjectCodeReaderCallback::SetPropertyAsObject(int objectID
,
264 const wxClassInfo
*WXUNUSED(classInfo
),
265 const wxPropertyInfo
* propertyInfo
,
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() ) );
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() ) );
280 void wxObjectCodeReaderCallback::AddToPropertyCollection( int objectID
,
281 const wxClassInfo
*WXUNUSED(classInfo
),
282 const wxPropertyInfo
* propertyInfo
,
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()) );
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
))
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
)
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
)
315 int eventType
= delegateTypeInfo
->GetEventType();
316 wxString handlerName
= handlerInfo
->GetName();
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() );
325 m_source
+= ( code
);
329 wxLogError(_("delegate has no type info"));