mummy
1.0.2
|
00001 //---------------------------------------------------------------------------- 00002 // 00003 // $Id: MummyCsharpShadowLayerGenerator.cxx 442 2009-04-03 19:47:41Z david.cole $ 00004 // 00005 // $Author: david.cole $ 00006 // $Date: 2009-04-03 15:47:41 -0400 (Fri, 03 Apr 2009) $ 00007 // $Revision: 442 $ 00008 // 00009 // Copyright (C) 2006-2007 Kitware, Inc. 00010 // 00011 //---------------------------------------------------------------------------- 00012 00013 #include "MummyCsharpShadowLayerGenerator.h" 00014 #include "MummyCsharpGenerator.h" 00015 #include "MummyLog.h" 00016 #include "MummySettings.h" 00017 00018 #include "cableClass.h" 00019 #include "cableClassType.h" 00020 #include "cableFundamentalType.h" 00021 #include "cableFunctionType.h" 00022 #include "cableMethod.h" 00023 #include "cablePointerType.h" 00024 #include "cableType.h" 00025 00026 #include "gxsys/ios/sstream" 00027 00028 00029 //---------------------------------------------------------------------------- 00030 MummyCsharpShadowLayerGenerator::MummyCsharpShadowLayerGenerator() 00031 { 00032 this->CsharpGenerator = 0; 00033 } 00034 00035 00036 //---------------------------------------------------------------------------- 00037 MummyCsharpShadowLayerGenerator::~MummyCsharpShadowLayerGenerator() 00038 { 00039 } 00040 00041 00042 //---------------------------------------------------------------------------- 00043 bool MummyCsharpShadowLayerGenerator::GenerateWrappers() 00044 { 00045 this->EmitClassForShadowLayer(*GetStream(), GetTargetClass()); 00046 return false; 00047 } 00048 00049 00050 //---------------------------------------------------------------------------- 00051 MummyCsharpGenerator* MummyCsharpShadowLayerGenerator::GetCsharpGenerator() 00052 { 00053 return this->CsharpGenerator; 00054 } 00055 00056 00057 //---------------------------------------------------------------------------- 00058 void MummyCsharpShadowLayerGenerator::SetCsharpGenerator(MummyCsharpGenerator* generator) 00059 { 00060 this->CsharpGenerator = generator; 00061 } 00062 00063 00064 //---------------------------------------------------------------------------- 00065 const char *MummyCsharpShadowLayerGenerator::GetArgName(cable::FunctionType *ftype, unsigned int i) 00066 { 00067 return this->GetCsharpGenerator()->GetArgName(ftype, i); 00068 } 00069 00070 00071 //---------------------------------------------------------------------------- 00072 gxsys_stl::string GetShadowClassName(const cable::Class *c) 00073 { 00074 gxsys_stl::string s(c->GetName()); 00075 s += "Shadow"; 00076 return s; 00077 } 00078 00079 00080 //---------------------------------------------------------------------------- 00081 gxsys_stl::string GetPrimaryDelegateCxxType(const cable::Class *c) 00082 { 00083 return GetShadowClassName(c) + "_PrimaryType"; 00084 } 00085 00086 00087 //---------------------------------------------------------------------------- 00088 gxsys_stl::string GetSecondaryDelegateCxxType(const cable::Class *c) 00089 { 00090 return gxsys_stl::string(c->GetName()) + "*"; 00091 } 00092 00093 00094 //---------------------------------------------------------------------------- 00095 void MummyCsharpShadowLayerGenerator::EmitClassMethodDeclarationForShadowLayer(gxsys_ios::ostream &os, const cable::Class *, const cable::Method *m, const unsigned int, int indent, const char *implClassName) 00096 { 00097 cable::FunctionType *ft = m->GetFunctionType(); 00098 unsigned int cArgs = ft->GetNumberOfArguments(); 00099 unsigned int i = 0; 00100 cable::Type *argType = 0; 00101 cable::Type *retType = ft->GetReturns(); 00102 00103 EmitIndent(os, indent); 00104 00105 // Context: 00106 // Emit(os, "/* "); 00107 // Emit(os, m->GetContext()->GetName()); 00108 // Emit(os, " */ "); 00109 00110 // Abstract? 00111 // if (m->GetPureVirtual()) 00112 // { 00113 // Emit(os, "/* pure virtual */ "); 00114 // } 00115 00116 // Definitely virtual: 00117 if (m->GetVirtual() && !implClassName) 00118 { 00119 Emit(os, "virtual "); 00120 } 00121 00122 // Return type: 00123 Emit(os, retType->GetCxxType().GetName().c_str()); 00124 Emit(os, " "); 00125 00126 // Class name colon colon: 00127 if (implClassName) 00128 { 00129 Emit(os, implClassName); 00130 Emit(os, "::"); 00131 } 00132 00133 // Method name: 00134 Emit(os, m->GetName()); 00135 00136 // Open args: 00137 Emit(os, "("); 00138 00139 // The real args: 00140 for (i= 0; i<cArgs; ++i) 00141 { 00142 argType = ft->GetArgument(i); 00143 00144 // arg "i": 00145 Emit(os, argType->GetCxxType().GetName().c_str()); 00146 Emit(os, " "); 00147 Emit(os, GetArgName(ft, i)); 00148 00149 if (i<cArgs-1) 00150 { 00151 Emit(os, ", "); 00152 } 00153 } 00154 00155 // Close args: 00156 Emit(os, ")"); 00157 } 00158 00159 00160 //---------------------------------------------------------------------------- 00161 void MummyCsharpShadowLayerGenerator::EmitClassDeclarationForShadowLayer(gxsys_ios::ostream &os, const cable::Class *c, const gxsys_stl::vector<cable::Method*>& wrapped_methods, cable::Method*, cable::Method*, cable::Method*, cable::Method*) 00162 { 00163 unsigned int i = 0; 00164 gxsys_stl::string s(GetShadowClassName(c)); 00165 00166 if (ClassIsA(c, "vtkObject")) 00167 { 00168 Emit(os, "\n"); 00169 Emit(os, "\n"); 00170 Emit(os, "//----------------------------------------------------------------------------\n"); 00171 Emit(os, "#include \"vtkDebugLeaks.h\"\n"); 00172 } 00173 00174 Emit(os, "\n"); 00175 Emit(os, "\n"); 00176 Emit(os, "//----------------------------------------------------------------------------\n"); 00177 00178 Emit(os, "#undef "); 00179 Emit(os, s.c_str()); 00180 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00181 Emit(os, "\n"); 00182 Emit(os, "#ifdef _MSC_VER\n"); 00183 Emit(os, "#define "); 00184 Emit(os, s.c_str()); 00185 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00186 Emit(os, "#endif\n"); 00187 Emit(os, "\n"); 00188 Emit(os, "#ifdef "); 00189 Emit(os, s.c_str()); 00190 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00191 Emit(os, "#include \"windows.h\" // HRESULT, FAILED, E_UNEXPECTED\n"); 00192 Emit(os, "#define "); 00193 Emit(os, s.c_str()); 00194 Emit(os, "_PrimaryType IDispatch*\n"); 00195 Emit(os, "#else\n"); 00196 Emit(os, "#define "); 00197 Emit(os, s.c_str()); 00198 Emit(os, "_PrimaryType void*\n"); 00199 Emit(os, "#define HRESULT long\n"); 00200 Emit(os, "#define FAILED(hr) ((HRESULT)(hr) < 0)\n"); 00201 Emit(os, "#define E_UNEXPECTED ((HRESULT)0x8000FFFFL)\n"); 00202 Emit(os, "#endif\n"); 00203 00204 00205 Emit(os, "\n"); 00206 Emit(os, "\n"); 00207 Emit(os, "//----------------------------------------------------------------------------\n"); 00208 00209 Emit(os, "class "); 00210 Emit(os, s.c_str()); 00211 Emit(os, " : public "); 00212 Emit(os, c->GetQualifiedName().c_str()); 00213 00214 // Abstract? 00215 //if (c->GetAbstract()) 00216 // { 00217 // Emit(os, " /* abstract */"); 00218 // } 00219 00220 Emit(os, "\n"); 00221 00222 Emit(os, "{\n"); 00223 Emit(os, "public:\n"); 00224 00225 // Shadow class always has factory method and DisconnectShadowDelegates: 00226 // 00227 // The factory method is "create-and-connect" so that it can be made in 00228 // one "over-the-boundary" call from the wrapped layer: 00229 // 00230 EmitIndent(os); 00231 Emit(os, "static "); 00232 Emit(os, s.c_str()); 00233 Emit(os, "* CreateShadow("); 00234 Emit(os, GetPrimaryDelegateCxxType(c).c_str()); 00235 Emit(os, " primary);"); 00236 Emit(os, "\n"); 00237 00238 EmitIndent(os); 00239 Emit(os, "void DisconnectShadowDelegates();"); 00240 Emit(os, "\n"); 00241 00242 Emit(os, "\n"); 00243 00244 // And overrides of all the virtual wrapped methods (including the Register 00245 // and UnRegister methods, if any...) 00246 // 00247 i = 0; 00248 for (gxsys_stl::vector<cable::Method*>::const_iterator mit = wrapped_methods.begin(); 00249 mit != wrapped_methods.end(); ++mit) 00250 { 00251 if ((*mit)->GetVirtual()) 00252 { 00253 EmitClassMethodDeclarationForShadowLayer(os, c, *mit, i+1, 1, false); 00254 Emit(os, ";\n"); 00255 } 00256 ++i; 00257 } 00258 00259 00260 Emit(os, "\n"); 00261 Emit(os, "protected:\n"); 00262 EmitIndent(os); 00263 Emit(os, s.c_str()); 00264 Emit(os, "();\n"); 00265 EmitIndent(os); 00266 Emit(os, "virtual ~"); 00267 Emit(os, s.c_str()); 00268 Emit(os, "();\n"); 00269 00270 00271 Emit(os, "\n"); 00272 Emit(os, "private:\n"); 00273 EmitIndent(os); 00274 Emit(os, GetPrimaryDelegateCxxType(c).c_str()); 00275 Emit(os, " PrimaryDelegate;"); 00276 Emit(os, "\n"); 00277 EmitIndent(os); 00278 Emit(os, GetSecondaryDelegateCxxType(c).c_str()); 00279 Emit(os, " SecondaryDelegate;"); 00280 Emit(os, "\n"); 00281 00282 // A bool flag for each virtual override indicating whether the shadow 00283 // class is currently calling that method on the primary delegate or not: 00284 // 00285 i = 0; 00286 for (gxsys_stl::vector<cable::Method*>::const_iterator mit = wrapped_methods.begin(); 00287 mit != wrapped_methods.end(); ++mit) 00288 { 00289 if ((*mit)->GetVirtual()) 00290 { 00291 EmitIndent(os); 00292 Emit(os, "bool CallingPrimary_"); 00293 Emit(os, (*mit)->GetName()); 00294 Emit(os, "_"); 00295 EmitUint(os, i+1); 00296 Emit(os, ";\n"); 00297 } 00298 00299 ++i; 00300 } 00301 00302 Emit(os, "};\n"); 00303 } 00304 00305 00306 //---------------------------------------------------------------------------- 00307 // The string returned from these Variant functions should be a valid V_ and 00308 // VT_ suffix for use with initializing/accessing a VARIANT variable of the 00309 // given type... 00310 // 00311 // For example, in the use case: 00312 // VariantInit(&vargs[0]); 00313 // V_VT(&vargs[0]) = VT_I4; 00314 // V_I4(&vargs[0]) = (long) callData; 00315 // This function will receive a cable type representing the C++ type "long" 00316 // and return "I4"... 00317 // 00318 gxsys_stl::string /* MummyCsharpShadowLayerGenerator:: */ GetVariantFundamentalTypeString(const cable::Type *t) 00319 { 00320 gxsys_stl::string s; 00321 00322 if (cable::Type::FundamentalTypeId == t->GetTypeId()) 00323 { 00324 s = cable::FundamentalType::SafeDownCast(t)->GetTypeName(); 00325 00326 switch (cxx::FundamentalType::SafeDownCast(t->GetCxxType().GetType())->GetId()) 00327 { 00328 case cxx::FundamentalType::UnsignedChar: 00329 s = "UI1"; 00330 break; 00331 00332 case cxx::FundamentalType::UnsignedShortInt: 00333 s = "UI2"; 00334 break; 00335 00336 case cxx::FundamentalType::UnsignedInt: 00337 case cxx::FundamentalType::UnsignedLongInt: 00338 s = "UI4"; 00339 break; 00340 00341 case cxx::FundamentalType::UnsignedLongLongInt: 00342 s = "UI8"; 00343 break; 00344 00345 case cxx::FundamentalType::SignedChar: 00346 case cxx::FundamentalType::Char: 00347 s = "I1"; 00348 break; 00349 00350 case cxx::FundamentalType::ShortInt: 00351 s = "I2"; 00352 break; 00353 00354 case cxx::FundamentalType::Int: 00355 case cxx::FundamentalType::LongInt: 00356 s = "I4"; 00357 break; 00358 00359 case cxx::FundamentalType::LongLongInt: 00360 s = "I8"; 00361 break; 00362 00363 case cxx::FundamentalType::Bool: 00364 s = "BOOL"; 00365 break; 00366 00367 case cxx::FundamentalType::Float: 00368 s = "R4"; 00369 break; 00370 00371 case cxx::FundamentalType::Double: 00372 s = "R8"; 00373 break; 00374 00375 //case cxx::FundamentalType::Void: 00376 //case cxx::FundamentalType::WChar_t: 00377 //case cxx::FundamentalType::LongDouble: 00378 //case cxx::FundamentalType::ComplexFloat: 00379 //case cxx::FundamentalType::ComplexDouble: 00380 //case cxx::FundamentalType::ComplexLongDouble: 00381 //case cxx::FundamentalType::NumberOfTypes: 00382 default: 00383 break; 00384 } 00385 } 00386 00387 if (s == "") 00388 { 00389 LogError(me_InternalError, 00390 << "Unhandled variable type. GetVariantFundamentalTypeString returning the empty string..."); 00391 } 00392 00393 return s; 00394 } 00395 00396 00397 //---------------------------------------------------------------------------- 00398 gxsys_stl::string /* MummyCsharpShadowLayerGenerator:: */ GetVariantTypeString(const cable::Type *t) 00399 { 00400 gxsys_stl::string s; 00401 cable::Type *nested_type = 0; 00402 00403 switch (t->GetTypeId()) 00404 { 00405 case cable::Type::EnumerationTypeId: 00406 s = "UI4"; 00407 break; 00408 00409 case cable::Type::FundamentalTypeId: 00410 s = GetVariantFundamentalTypeString(t); 00411 break; 00412 00413 case cable::Type::ArrayTypeId: 00414 s = "ERROR_ArrayTypeId_not_yet_implemented"; 00415 LogError(me_InternalError, << s.c_str()); 00416 break; 00417 00418 case cable::Type::ClassTypeId: 00419 s = "ERROR_passing_class__"; 00420 s += cable::ClassType::SafeDownCast(t)->GetClass()->GetName(); 00421 s += "__by_value_not_allowed"; 00422 LogError(me_InternalError, << s.c_str()); 00423 break; 00424 00425 case cable::Type::PointerTypeId: 00426 nested_type = cable::PointerType::SafeDownCast(t)->GetTarget(); 00427 00428 // IntPtr maps to I4 on 32-bit windows and I8 on 64-bit windows... 00429 // 00430 if (IsObject(nested_type)) 00431 { 00432 s = "I4"; 00433 } 00434 else if (IsChar(nested_type)) 00435 { 00436 s = "I4"; 00437 } 00438 else if (IsVoid(nested_type)) 00439 { 00440 s = "I4"; 00441 } 00442 else if (cable::Type::FundamentalTypeId == nested_type->GetTypeId()) 00443 { 00444 s = "I4"; 00445 } 00446 else if (cable::Type::PointerTypeId == nested_type->GetTypeId()) 00447 { 00448 s = "I4 /* pointer */"; 00449 } 00450 else 00451 { 00452 s = "ERROR_PointerTypeId_not_yet_implemented_for_nested_type"; 00453 LogError(me_InternalError, << s.c_str()); 00454 } 00455 break; 00456 00457 case cable::Type::ReferenceTypeId: 00458 s = "ERROR_ReferenceTypeId_not_yet_implemented"; 00459 LogError(me_InternalError, << s.c_str()); 00460 break; 00461 00462 case cable::Type::OffsetTypeId: 00463 case cable::Type::MethodTypeId: 00464 case cable::Type::FunctionTypeId: 00465 default: 00466 s = "ERROR_No_Variant_type_for_cable_Type_TypeId"; 00467 LogError(me_InternalError, << s.c_str()); 00468 break; 00469 } 00470 00471 if (s == "") 00472 { 00473 LogError(me_InternalError, 00474 << "Unhandled variable type. GetVariantTypeString returning the empty string..."); 00475 } 00476 00477 return s; 00478 } 00479 00480 00481 //---------------------------------------------------------------------------- 00482 gxsys_stl::string /* MummyCsharpShadowLayerGenerator:: */ GetVariantTypeCastingString(const cable::Type *t) 00483 { 00484 gxsys_stl::string s; 00485 cable::Type *nested_type = 0; 00486 00487 switch (t->GetTypeId()) 00488 { 00489 case cable::Type::EnumerationTypeId: 00490 s = "(unsigned int) "; 00491 break; 00492 00493 case cable::Type::FundamentalTypeId: 00494 // No cast needed... 00495 s = ""; 00496 break; 00497 00498 case cable::Type::ArrayTypeId: 00499 s = "ERROR_ArrayTypeId_not_yet_implemented"; 00500 LogError(me_InternalError, << s.c_str()); 00501 break; 00502 00503 case cable::Type::ClassTypeId: 00504 s = "ERROR_passing_class__"; 00505 s += cable::ClassType::SafeDownCast(t)->GetClass()->GetName(); 00506 s += "__by_value_not_allowed"; 00507 LogError(me_InternalError, << s.c_str()); 00508 break; 00509 00510 case cable::Type::PointerTypeId: 00511 nested_type = cable::PointerType::SafeDownCast(t)->GetTarget(); 00512 00513 // IntPtr maps to I4 on 32-bit windows and I8 on 64-bit windows... 00514 // 00515 if (IsObject(nested_type)) 00516 { 00517 s = "(int) "; 00518 } 00519 else if (IsChar(nested_type)) 00520 { 00521 s = "(int) "; 00522 } 00523 else if (IsVoid(nested_type)) 00524 { 00525 s = "(int) "; 00526 } 00527 else if (cable::Type::FundamentalTypeId == nested_type->GetTypeId()) 00528 { 00529 s = "(int) "; 00530 } 00531 else if (cable::Type::PointerTypeId == nested_type->GetTypeId()) 00532 { 00533 s = "(int) /* pointer */"; 00534 } 00535 else 00536 { 00537 s = "ERROR_PointerTypeId_not_yet_implemented_for_nested_type"; 00538 LogError(me_InternalError, << s.c_str()); 00539 } 00540 break; 00541 00542 case cable::Type::ReferenceTypeId: 00543 s = "ERROR_ReferenceTypeId_not_yet_implemented"; 00544 LogError(me_InternalError, << s.c_str()); 00545 break; 00546 00547 case cable::Type::OffsetTypeId: 00548 case cable::Type::MethodTypeId: 00549 case cable::Type::FunctionTypeId: 00550 default: 00551 s = "ERROR_No_Variant_type_for_cable_Type_TypeId"; 00552 LogError(me_InternalError, << s.c_str()); 00553 break; 00554 } 00555 00556 return s; 00557 } 00558 00559 00560 //---------------------------------------------------------------------------- 00561 void MummyCsharpShadowLayerGenerator::EmitClassImplementationForShadowLayer(gxsys_ios::ostream &os, const cable::Class *c, const gxsys_stl::vector<cable::Method*>& wrapped_methods, cable::Method* factoryM, cable::Method* disposalM, cable::Method* registerM, cable::Method* unRegisterM) 00562 { 00563 unsigned int i = 0; 00564 gxsys_stl::string s(GetShadowClassName(c)); 00565 gxsys_ios::ostringstream oss; 00566 gxsys_stl::string vargs; 00567 00568 // Shadow class always has factory method and DisconnectShadowDelegates: 00569 // 00570 Emit(os, "\n"); 00571 Emit(os, "\n"); 00572 Emit(os, "//----------------------------------------------------------------------------\n"); 00573 Emit(os, "/* static */\n"); 00574 Emit(os, s.c_str()); 00575 Emit(os, "* "); 00576 Emit(os, s.c_str()); 00577 Emit(os, "::"); 00578 Emit(os, "CreateShadow("); 00579 Emit(os, GetPrimaryDelegateCxxType(c).c_str()); 00580 Emit(os, " primary)"); 00581 Emit(os, "\n"); 00582 Emit(os, "{\n"); 00583 00584 EmitIndent(os); 00585 Emit(os, s.c_str()); 00586 Emit(os, "* rv = new "); 00587 Emit(os, s.c_str()); 00588 Emit(os, ";\n"); 00589 00590 EmitIndent(os); 00591 Emit(os, "rv->PrimaryDelegate = primary;\n"); 00592 00593 EmitIndent(os); 00594 Emit(os, "rv->SecondaryDelegate = "); 00595 if (factoryM) 00596 { 00597 Emit(os, c->GetName()); 00598 Emit(os, "::"); 00599 Emit(os, factoryM->GetName()); 00600 Emit(os, "()"); 00601 } 00602 else 00603 { 00604 Emit(os, "0"); 00605 } 00606 Emit(os, ";\n"); 00607 Emit(os, "\n"); 00608 00609 EmitIndent(os); 00610 Emit(os, "if (rv->PrimaryDelegate)\n"); 00611 EmitIndent(os, 2); 00612 Emit(os, "{\n"); 00613 Emit(os, "#ifdef "); 00614 Emit(os, s.c_str()); 00615 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00616 EmitIndent(os, 2); 00617 Emit(os, "rv->PrimaryDelegate->AddRef();\n"); 00618 Emit(os, "#else\n"); 00619 Emit(os, "#endif\n"); 00620 EmitIndent(os, 2); 00621 Emit(os, "}\n"); 00622 Emit(os, "\n"); 00623 00624 EmitIndent(os); 00625 Emit(os, "return rv;\n"); 00626 00627 Emit(os, "}\n"); 00628 00629 Emit(os, "\n"); 00630 Emit(os, "\n"); 00631 Emit(os, "//----------------------------------------------------------------------------\n"); 00632 Emit(os, "void "); 00633 Emit(os, s.c_str()); 00634 Emit(os, "::"); 00635 Emit(os, "DisconnectShadowDelegates()"); 00636 Emit(os, "\n"); 00637 Emit(os, "{\n"); 00638 00639 EmitIndent(os); 00640 Emit(os, "if (this->PrimaryDelegate)\n"); 00641 EmitIndent(os, 2); 00642 Emit(os, "{\n"); 00643 Emit(os, "#ifdef "); 00644 Emit(os, s.c_str()); 00645 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00646 EmitIndent(os, 2); 00647 Emit(os, "this->PrimaryDelegate->Release();\n"); 00648 Emit(os, "#else\n"); 00649 Emit(os, "#endif\n"); 00650 EmitIndent(os, 2); 00651 Emit(os, "}\n"); 00652 EmitIndent(os); 00653 Emit(os, "this->PrimaryDelegate = 0;\n"); 00654 Emit(os, "\n"); 00655 00656 if (disposalM) 00657 { 00658 EmitIndent(os); 00659 Emit(os, "if (this->SecondaryDelegate)\n"); 00660 EmitIndent(os, 2); 00661 Emit(os, "{\n"); 00662 EmitIndent(os, 2); 00663 Emit(os, "this->SecondaryDelegate->"); 00664 Emit(os, disposalM->GetName()); 00665 Emit(os, "();\n"); 00666 EmitIndent(os, 2); 00667 Emit(os, "}\n"); 00668 } 00669 00670 EmitIndent(os); 00671 Emit(os, "this->SecondaryDelegate = 0;\n"); 00672 00673 Emit(os, "\n"); 00674 Emit(os, "}\n"); 00675 00676 // And overrides of all the virtual wrapped methods: 00677 // 00678 i = 0; 00679 00680 for (gxsys_stl::vector<cable::Method*>::const_iterator mit = wrapped_methods.begin(); 00681 mit != wrapped_methods.end(); ++mit) 00682 { 00683 if ((*mit)->GetVirtual()) 00684 { 00685 unsigned int argi = 0; 00686 unsigned int cArgs = (*mit)->GetFunctionType()->GetNumberOfArguments(); 00687 cable::Type *retType = (*mit)->GetFunctionType()->GetReturns(); 00688 bool voidReturn = false; 00689 if (IsVoid(retType)) 00690 { 00691 voidReturn = true; 00692 } 00693 00694 Emit(os, "\n"); 00695 Emit(os, "\n"); 00696 Emit(os, "//----------------------------------------------------------------------------\n"); 00697 EmitClassMethodDeclarationForShadowLayer(os, c, *mit, i+1, 0, s.c_str()); 00698 Emit(os, "\n"); 00699 Emit(os, "{\n"); 00700 00701 if (!voidReturn) 00702 { 00703 EmitIndent(os); 00704 Emit(os, retType->GetCxxType().GetName().c_str()); 00705 Emit(os, " rv = "); 00706 if (cable::Type::PointerTypeId == retType->GetTypeId()) 00707 { 00708 Emit(os, "0"); 00709 } 00710 else if (cable::Type::FundamentalTypeId == retType->GetTypeId()) 00711 { 00712 Emit(os, "("); 00713 Emit(os, retType->GetCxxType().GetName().c_str()); 00714 Emit(os, ") 0"); 00715 } 00716 else 00717 { 00718 Emit(os, retType->GetCxxType().GetName().c_str()); 00719 Emit(os, "()"); 00720 } 00721 Emit(os, ";\n"); 00722 } 00723 00724 EmitIndent(os); 00725 Emit(os, "HRESULT msl_hr = E_UNEXPECTED;\n"); 00726 Emit(os, "\n"); 00727 00728 EmitIndent(os); 00729 Emit(os, "if (this->PrimaryDelegate && !this->CallingPrimary_"); 00730 Emit(os, (*mit)->GetName()); 00731 Emit(os, "_"); 00732 EmitUint(os, i+1); 00733 Emit(os, ")\n"); 00734 00735 EmitIndent(os, 2); 00736 Emit(os, "{\n"); 00737 00738 EmitIndent(os, 2); 00739 Emit(os, "this->CallingPrimary_"); 00740 Emit(os, (*mit)->GetName()); 00741 Emit(os, "_"); 00742 EmitUint(os, i+1); 00743 Emit(os, " = true;\n"); 00744 Emit(os, "\n"); 00745 00746 Emit(os, "#ifdef "); 00747 Emit(os, s.c_str()); 00748 Emit(os, "_USE_IDISPATCH_AS_PRIMARY\n"); 00749 EmitIndent(os, 2); 00750 Emit(os, "IDispatch *msl_pDisp = (IDispatch *) this->PrimaryDelegate;\n"); 00751 EmitIndent(os, 2); 00752 Emit(os, "msl_pDisp->AddRef();\n"); 00753 Emit(os, "\n"); 00754 EmitIndent(os, 2); 00755 Emit(os, "DISPID msl_dispid = (DISPID) -1;\n"); 00756 00757 EmitIndent(os, 2); 00758 Emit(os, "OLECHAR *msl_name = L\""); 00759 Emit(os, (*mit)->GetName()); 00760 Emit(os, "\";\n"); 00761 00762 if (cArgs!=0) 00763 { 00764 EmitIndent(os, 2); 00765 Emit(os, "VARIANTARG msl_vargs["); 00766 oss.rdbuf()->str(""); 00767 oss << cArgs << gxsys_ios::ends; 00768 vargs = oss.str(); 00769 Emit(os, vargs.c_str()); 00770 Emit(os, "];\n"); 00771 } 00772 00773 EmitIndent(os, 2); 00774 Emit(os, "DISPPARAMS msl_params;\n"); 00775 EmitIndent(os, 2); 00776 Emit(os, "VARIANT msl_result;\n"); 00777 EmitIndent(os, 2); 00778 Emit(os, "EXCEPINFO msl_excep;\n"); 00779 EmitIndent(os, 2); 00780 Emit(os, "UINT msl_arg = (UINT) -1;\n"); 00781 Emit(os, "\n"); 00782 EmitIndent(os, 2); 00783 Emit(os, "msl_hr = msl_pDisp->GetIDsOfNames(\n"); 00784 EmitIndent(os, 3); 00785 Emit(os, "IID_NULL,\n"); 00786 EmitIndent(os, 3); 00787 Emit(os, "&msl_name,\n"); 00788 EmitIndent(os, 3); 00789 Emit(os, "1,\n"); 00790 EmitIndent(os, 3); 00791 Emit(os, "LOCALE_USER_DEFAULT,\n"); 00792 EmitIndent(os, 3); 00793 Emit(os, "&msl_dispid);\n"); 00794 Emit(os, "\n"); 00795 00796 EmitIndent(os, 2); 00797 Emit(os, "if (SUCCEEDED(msl_hr))\n"); 00798 EmitIndent(os, 3); 00799 Emit(os, "{\n"); 00800 00801 for (argi= 0; argi<cArgs; ++argi) 00802 { 00803 oss.rdbuf()->str(""); 00804 oss << "&msl_vargs[" << (cArgs-1-argi) << "]" << gxsys_ios::ends; 00805 vargs = oss.str(); 00806 00807 EmitIndent(os, 3); 00808 Emit(os, "VariantInit("); 00809 Emit(os, vargs.c_str()); 00810 Emit(os, ");\n"); 00811 00812 EmitIndent(os, 3); 00813 Emit(os, "V_VT("); 00814 Emit(os, vargs.c_str()); 00815 Emit(os, ") = VT_"); 00816 Emit(os, GetVariantTypeString((*mit)->GetFunctionType()->GetArgument(argi)).c_str()); 00817 Emit(os, ";\n"); 00818 00819 EmitIndent(os, 3); 00820 Emit(os, "V_"); 00821 Emit(os, GetVariantTypeString((*mit)->GetFunctionType()->GetArgument(argi)).c_str()); 00822 Emit(os, "("); 00823 Emit(os, vargs.c_str()); 00824 Emit(os, ") = "); 00825 Emit(os, GetVariantTypeCastingString((*mit)->GetFunctionType()->GetArgument(argi)).c_str()); 00826 Emit(os, GetArgName((*mit)->GetFunctionType(), argi)); 00827 Emit(os, ";\n"); 00828 00829 Emit(os, "\n"); 00830 } 00831 00832 EmitIndent(os, 3); 00833 Emit(os, "msl_params.rgvarg = "); 00834 if (0 == cArgs) 00835 { 00836 Emit(os, "0"); 00837 } 00838 else 00839 { 00840 Emit(os, "&msl_vargs[0]"); 00841 } 00842 Emit(os, ";\n"); 00843 EmitIndent(os, 3); 00844 Emit(os, "msl_params.rgdispidNamedArgs = 0;\n"); 00845 EmitIndent(os, 3); 00846 Emit(os, "msl_params.cArgs = "); 00847 if (0 == cArgs) 00848 { 00849 Emit(os, "0"); 00850 } 00851 else 00852 { 00853 Emit(os, "sizeof(msl_vargs)/sizeof(msl_vargs[0])"); 00854 } 00855 Emit(os, ";\n"); 00856 EmitIndent(os, 3); 00857 Emit(os, "msl_params.cNamedArgs = 0;\n"); 00858 Emit(os, "\n"); 00859 EmitIndent(os, 3); 00860 Emit(os, "VariantInit(&msl_result);\n"); 00861 Emit(os, "\n"); 00862 EmitIndent(os, 3); 00863 Emit(os, "memset(&msl_excep, 0, sizeof(msl_excep));\n"); 00864 Emit(os, "\n"); 00865 EmitIndent(os, 3); 00866 Emit(os, "msl_hr = msl_pDisp->Invoke(msl_dispid, IID_NULL, LOCALE_USER_DEFAULT,\n"); 00867 EmitIndent(os, 4); 00868 Emit(os, "DISPATCH_METHOD, &msl_params, &msl_result, &msl_excep, &msl_arg);\n"); 00869 Emit(os, "\n"); 00870 00871 if (!voidReturn) 00872 { 00873 EmitIndent(os, 3); 00874 Emit(os, "if (SUCCEEDED(msl_hr))\n"); 00875 EmitIndent(os, 4); 00876 Emit(os, "{\n"); 00877 EmitIndent(os, 4); 00878 Emit(os, "rv = ("); 00879 Emit(os, retType->GetCxxType().GetName().c_str()); 00880 Emit(os, ") V_"); 00881 Emit(os, GetVariantTypeString(retType).c_str()); 00882 Emit(os, "(&msl_result);\n"); 00883 EmitIndent(os, 4); 00884 Emit(os, "}\n"); 00885 Emit(os, "\n"); 00886 } 00887 00888 EmitIndent(os, 3); 00889 Emit(os, "VariantClear(&msl_result);\n"); 00890 00891 for (argi= 0; argi<cArgs; ++argi) 00892 { 00893 oss.rdbuf()->str(""); 00894 oss << "&msl_vargs[" << argi << "]" << gxsys_ios::ends; 00895 vargs = oss.str(); 00896 00897 EmitIndent(os, 3); 00898 Emit(os, "VariantClear("); 00899 Emit(os, vargs.c_str()); 00900 Emit(os, ");\n"); 00901 } 00902 00903 EmitIndent(os, 3); 00904 Emit(os, "}\n"); 00905 Emit(os, "\n"); 00906 00907 EmitIndent(os, 2); 00908 Emit(os, "msl_pDisp->Release();\n"); 00909 Emit(os, "#else\n"); 00910 Emit(os, "#endif\n"); 00911 Emit(os, "\n"); 00912 00913 EmitIndent(os, 2); 00914 Emit(os, "this->CallingPrimary_"); 00915 Emit(os, (*mit)->GetName()); 00916 Emit(os, "_"); 00917 EmitUint(os, i+1); 00918 Emit(os, " = false;\n"); 00919 00920 EmitIndent(os, 2); 00921 Emit(os, "}\n"); 00922 Emit(os, "\n"); 00923 00924 00925 EmitIndent(os); 00926 Emit(os, "if (FAILED(msl_hr) || this->CallingPrimary_"); 00927 Emit(os, (*mit)->GetName()); 00928 Emit(os, "_"); 00929 EmitUint(os, i+1); 00930 Emit(os, ")\n"); 00931 00932 EmitIndent(os, 2); 00933 Emit(os, "{\n"); 00934 00935 // Do NOT delegate Register or UnRegister calls to the 00936 // SecondaryDelegate... Only pass them up to the parent 00937 // class implementation on *this* object. The SecondaryDelegate 00938 // is only held by us for delegating non-ref-counting calls 00939 // to... 00940 // 00941 int secondaryIndent = 3; 00942 00943 if (*mit != registerM && *mit != unRegisterM) 00944 { 00945 secondaryIndent = 3; 00946 00947 EmitIndent(os, 2); 00948 Emit(os, "if (this->SecondaryDelegate)\n"); 00949 00950 EmitIndent(os, 3); 00951 Emit(os, "{\n"); 00952 00953 EmitIndent(os, 3); 00954 if (!voidReturn) 00955 { 00956 Emit(os, "rv = "); 00957 } 00958 Emit(os, "this->SecondaryDelegate->"); 00959 Emit(os, (*mit)->GetName()); 00960 Emit(os, "("); 00961 00962 for (argi= 0; argi<cArgs; ++argi) 00963 { 00964 Emit(os, GetArgName((*mit)->GetFunctionType(), argi)); 00965 00966 if (argi<cArgs-1) 00967 { 00968 Emit(os, ", "); 00969 } 00970 } 00971 Emit(os, ");\n"); 00972 00973 EmitIndent(os, 3); 00974 Emit(os, "}\n"); 00975 00976 EmitIndent(os, 2); 00977 Emit(os, "else\n"); 00978 00979 EmitIndent(os, 3); 00980 Emit(os, "{\n"); 00981 } 00982 else 00983 { 00984 secondaryIndent = 2; 00985 } 00986 00987 00988 // Only call the base class if it's not a pure virtual. If it's a pure 00989 // virtual, then the method we are in may be the only implementation. 00990 // If that's the case (as in vtkCommand::Execute) then it's a mistake 00991 // if the primary delegate has not already handled it. 00992 // 00993 if ((*mit)->GetPureVirtual()) 00994 { 00995 EmitIndent(os, secondaryIndent); 00996 Emit(os, "// pure virtual method in parent class...\n"); 00997 00998 if (*mit == registerM || *mit == unRegisterM) 00999 { 01000 EmitIndent(os, secondaryIndent); 01001 Emit(os, "// Register and UnRegister methods should *not* be\n"); 01002 EmitIndent(os, secondaryIndent); 01003 Emit(os, "// pure virtual methods in a shadowed class...\n"); 01004 01005 LogError(me_PureVirtualMethodNotAllowed, 01006 << "Register and UnRegister methods *cannot* be pure " 01007 << "virtual methods in a shadowed class..." 01008 ); 01009 } 01010 } 01011 else 01012 { 01013 EmitIndent(os, secondaryIndent); 01014 if (!voidReturn) 01015 { 01016 Emit(os, "rv = "); 01017 } 01018 Emit(os, "this->"); 01019 Emit(os, c->GetQualifiedName().c_str()); 01020 Emit(os, "::"); 01021 Emit(os, (*mit)->GetName()); 01022 Emit(os, "("); 01023 01024 for (argi= 0; argi<cArgs; ++argi) 01025 { 01026 Emit(os, GetArgName((*mit)->GetFunctionType(), argi)); 01027 01028 if (argi<cArgs-1) 01029 { 01030 Emit(os, ", "); 01031 } 01032 } 01033 Emit(os, ");\n"); 01034 } 01035 01036 if (*mit != registerM && *mit != unRegisterM) 01037 { 01038 EmitIndent(os, 3); 01039 Emit(os, "}\n"); 01040 } 01041 01042 01043 EmitIndent(os, 2); 01044 Emit(os, "}\n"); 01045 01046 01047 if (!voidReturn) 01048 { 01049 Emit(os, "\n"); 01050 01051 EmitIndent(os); 01052 Emit(os, "return rv;\n"); 01053 } 01054 01055 Emit(os, "}\n"); 01056 } 01057 01058 ++i; 01059 } 01060 01061 01062 // Constructor: 01063 // 01064 Emit(os, "\n"); 01065 Emit(os, "\n"); 01066 Emit(os, "//----------------------------------------------------------------------------\n"); 01067 Emit(os, s.c_str()); 01068 Emit(os, "::"); 01069 Emit(os, s.c_str()); 01070 Emit(os, "()\n"); 01071 Emit(os, "{\n"); 01072 01073 // Initialize pointers to 0 and bool flags to false: 01074 // 01075 EmitIndent(os); 01076 Emit(os, "this->PrimaryDelegate = 0;\n"); 01077 01078 EmitIndent(os); 01079 Emit(os, "this->SecondaryDelegate = 0;\n"); 01080 01081 i = 0; 01082 for (gxsys_stl::vector<cable::Method*>::const_iterator mit = wrapped_methods.begin(); 01083 mit != wrapped_methods.end(); ++mit) 01084 { 01085 if ((*mit)->GetVirtual()) 01086 { 01087 EmitIndent(os); 01088 Emit(os, "this->CallingPrimary_"); 01089 Emit(os, (*mit)->GetName()); 01090 Emit(os, "_"); 01091 EmitUint(os, i+1); 01092 Emit(os, " = false;\n"); 01093 } 01094 01095 ++i; 01096 } 01097 01098 if (ClassIsA(c, "vtkObject")) 01099 { 01100 Emit(os, "\n"); 01101 Emit(os, "#ifdef VTK_DEBUG_LEAKS\n"); 01102 01103 EmitIndent(os); 01104 Emit(os, "vtkDebugLeaks::ConstructClass(\""); 01105 Emit(os, c->GetName()); 01106 Emit(os, "\");\n"); 01107 01108 Emit(os, "#endif\n"); 01109 } 01110 01111 Emit(os, "}\n"); 01112 01113 01114 // Destructor: 01115 // 01116 Emit(os, "\n"); 01117 Emit(os, "\n"); 01118 Emit(os, "//----------------------------------------------------------------------------\n"); 01119 Emit(os, s.c_str()); 01120 Emit(os, "::~"); 01121 Emit(os, s.c_str()); 01122 Emit(os, "()\n"); 01123 Emit(os, "{\n"); 01124 EmitIndent(os); 01125 Emit(os, "this->DisconnectShadowDelegates();\n"); 01126 Emit(os, "}\n"); 01127 01128 01129 // And one extra export layer style function to create an instance of the 01130 // shadow class: 01131 // 01132 Emit(os, "\n"); 01133 Emit(os, "\n"); 01134 Emit(os, "//----------------------------------------------------------------------------\n"); 01135 Emit(os, "extern \"C\" MUMMY_DLL_EXPORT\n"); 01136 01137 Emit(os, s.c_str()); 01138 Emit(os, "* "); 01139 Emit(os, s.c_str()); 01140 Emit(os, "_CreateShadow("); 01141 Emit(os, GetPrimaryDelegateCxxType(c).c_str()); 01142 Emit(os, " primary)\n"); 01143 01144 Emit(os, "{\n"); 01145 01146 EmitIndent(os); 01147 Emit(os, s.c_str()); 01148 Emit(os, "* rv = "); 01149 Emit(os, s.c_str()); 01150 Emit(os, "::CreateShadow(primary);\n"); 01151 01152 EmitIndent(os); 01153 Emit(os, "return rv;\n"); 01154 01155 Emit(os, "}\n"); 01156 } 01157 01158 01159 //---------------------------------------------------------------------------- 01160 void MummyCsharpShadowLayerGenerator::EmitClassForShadowLayer(gxsys_ios::ostream &os, const cable::Class *c) 01161 { 01162 // Gather wrapped elements: 01163 // 01164 gxsys_stl::vector<cable::Method*> wrapped_methods; 01165 cable::Method *factoryM = 0; 01166 cable::Method *disposalM = 0; 01167 cable::Method *registerM = 0; 01168 cable::Method *unRegisterM = 0; 01169 01170 this->GetCsharpGenerator()->GatherWrappedMethods(c, wrapped_methods, factoryM, disposalM, registerM, unRegisterM, true); 01171 01172 // For the purposes of the shadow layer, make sure the Register and UnRegister 01173 // methods are emitted (same as any other wrapped method) in the shadow class: 01174 // 01175 wrapped_methods.insert(wrapped_methods.begin(), unRegisterM); 01176 wrapped_methods.insert(wrapped_methods.begin(), registerM); 01177 01178 EmitClassDeclarationForShadowLayer(os, c, wrapped_methods, factoryM, disposalM, registerM, unRegisterM); 01179 01180 EmitClassImplementationForShadowLayer(os, c, wrapped_methods, factoryM, disposalM, registerM, unRegisterM); 01181 }