codereadercallback.cpp 11 KB

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