def generateCallbackFunction(self, ifaceName, name, exception, ret, argInfo): global retv # Workaround for Python 1.x retv = ret rtype = ternary(ret == None, lambda: None, lambda: GetTypeInformation(retv)) global rtypev rtypev = rtype rname = ternary(rtype == None, lambda: "void", lambda: rtypev.cppReturnSignatureType) argsig = '' for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo): argt = GetTypeInformation(argType) if argsig != '': argsig = argsig + ', ' global argtv argtv = argt argsig = '%s%s arg%d' % (argsig, ternary(argOut, lambda: argtv.cppOutSignatureType, lambda: argtv.cppInSignatureType), i) self.cxx.out('%s %s(%s)' % (rname, name, argsig)) self.cxx.out(' throw(std::exception&)') self.cxx.out('{') self.cxx.inc_indent() self.cxx.out('ObjRef<CDA_GenericsService> cgs = CreateGenericsServiceInternal();') self.cxx.out('std::vector<iface::CGRS::GenericValue*> inValSeq;') self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > inValSeqReleaser(inValSeq, ' +\ 'new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));') for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo): if argIn: self.cxx.out('{') self.cxx.inc_indent() argt = GetTypeInformation(argType) # Note: Objects can actually have one of two incompatible interfaces - callback or normal. self.cxx.out('iface::%s* genval;' % argt.genericIface) self.cxx.out(argt.convertNativeToGeneric('%sarg%d' % (argt.deref(argOut), i), 'genval')) self.cxx.out('inValSeq.push_back(genval);') self.cxx.dec_indent() self.cxx.out('}') self.cxx.out('std::vector<iface::CGRS::GenericValue*> outValSeq;') self.cxx.out('scoped_destroy<std::vector<iface::CGRS::GenericValue*> > outValSeqReleaser(outValSeq, new container_destructor<std::vector<iface::CGRS::GenericValue*> >(new objref_destructor<iface::CGRS::GenericValue>()));') self.cxx.out('bool wasException = false;') self.cxx.out('ObjRef<iface::CGRS::GenericValue> genret = mValue->invokeOnInterface("%s", "%s", inValSeq, outValSeq, &wasException);' % (ifaceName, name)) self.cxx.out('if (wasException) throw %s();' % exception) self.cxx.out('std::vector<iface::CGRS::GenericValue*>::iterator outVali = outValSeq.begin();') for (i, (argType, argIn, argOut)) in zip(range(0, len(argInfo)), argInfo): if argOut: argt = GetTypeInformation(argType) self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genout%d, (*outVali), %s);' % (i, argt.genericIface)) self.cxx.out(argt.convertGenericToNative('genout%d' % i, '%sarg%d' % (argt.deref(1), i))) self.cxx.out('outVali++;') if rtype != None and not isinstance(rtype, VoidType): self.cxx.out('DECLARE_QUERY_INTERFACE_OBJREF(genreti, genret, %s);' % rtype.genericIface) self.cxx.out(rtype.makeStorage('retval')) self.cxx.out(rtype.convertGenericToNative('genreti', 'retval')) self.cxx.out(rtype.returnStorage('retval')) self.cxx.dec_indent() self.cxx.out('}')