]>
Commit | Line | Data |
---|---|---|
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> | |
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 | ||
1bf29304 SC |
75 | wxObjectCodeReaderCallback::wxObjectCodeReaderCallback(wxString& headerincludes, wxString &source) |
76 | : m_headerincludes(headerincludes),m_source(source) | |
e1d3601a PC |
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, | |
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 | ||
106 | void 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 |
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 ¶m ) | |
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 | ||
187 | void 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 | ||
219 | void 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 | ||
252 | void 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 | ||
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 ) | |
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 | ||
280 | void 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) | |
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 | ||
1bf29304 | 325 | m_source += ( code ); |
e1d3601a PC |
326 | } |
327 | else | |
328 | { | |
329 | wxLogError(_("delegate has no type info")); | |
330 | } | |
331 | } |