public void GenerateDelegateConverterImplementation(AST.Delegate type) { const string dName = "___del"; Strata = ApiStrata.ABI; var typeRef = TypeRef(type, false); var typeRefABI = TypeRef(type, true); Line($"HRESULT DW{type.ShortId}::AbiFunc({DeclParameters(type.GetABIParametersCpp(true))})"); Block(() => { Line($"auto {dName} = runtime_cast<DW{type.ShortId}>(__i_);"); Line($"if (!{dName}) return E_FAIL;"); Spacer(); ABIWrapperParameterValidation(type); ABIWrappedCall(type, null, $"{dName}->Func"); }); Spacer(); Strata = ApiStrata.Normal; Line("template<>"); Line($"{TypeRef(type, false)} ABIUtil<{typeRef}>::FromABI(void* fptr, IObject* ctx)"); //Line($"Delegate<{Signature(type, false)}> DW{type.ShortId}::Lookup({TypeRef(type)} fptr, IObject* ctx)"); Block(() => { Line( $@"if (fptr == &DW{type.ShortId}::AbiFunc) {{ auto wrapper = runtime_cast<DW{type.ShortId}>(ctx); if (!wrapper) throw Exception(""Unexpected context type for delegate translation""); return wrapper->Func; }} return [fn = ({typeRefABI})fptr, cp = com_ptr<IObject>(ctx)]({DeclParameters(type.Parameters)})"); if (!type.Return.IsVoid) { Code(" -> {0} ", VariableType(type.Return, AST.VariableContext.Return)); } Block(() => { CallToABIMethodBody(type.Rename("fn"), "cp.Get()"); }, ";"); }); Spacer(); Line("template<>"); Line("ABIOf<{0}> ABIUtil<{0}>::ToABI(const {0}& x)", typeRef); Block(() => { Line($"ABIOf<{typeRef}> x_abi;"); Line($"x_abi.Fn = &DW{type.ShortId}::AbiFunc;"); Line($"x_abi.Ctx = DW{type.ShortId}::GetWrapper(x);"); Line("return x_abi;"); }); }
public void GenerateDelegateConverterDeclaration(AST.Delegate type) { var name = "DW" + type.ShortId; Strata = ApiStrata.ABI; var dSig = Signature(type, false); Line( $@"class comid(""{type.Id}"") {name} : public ComObject<{name}, Object>, public ABI::DelegateWrapperBase<{name}, {dSig}> {{ public:"); Indent++; Line($"DW{type.ShortId}(const Delegate<{dSig}>& d) : DBase(d) {{ }}"); Line($"static Delegate<{dSig}> Lookup({TypeRef(type)} fptr, IObject* ctx);"); Line($"static HRESULT __stdcall AbiFunc({DeclParameters(type.GetABIParametersCpp(true))});"); Indent--; Line("};"); Spacer(); }