📄 bgenbacksupport.py
字号:
from bgenOutput import *from bgenVariable import *class BackGeneratorGroup: def __init__(self): self.generators = [] def add(self, g, dupcheck=0): self.generators.append(g) def checkgenerate(self): for g in self.generators: if g.checkgenerate(): return True return False def generateDeclaration(self): for g in self.generators: g.generateDeclaration() def generate(self): for g in self.generators: g.generate() def generateAttributeExistenceTest(self): for g in self.generators: g.generateAttributeExistenceTest()class BackModule(BackGeneratorGroup): def __init__(self, name, includestuff = None, finalstuff = None): BackGeneratorGroup.__init__(self) self.name = name self.includestuff = includestuff self.finalstuff = finalstuff def addobject(self, od): self.add(od) def generateDeclaration(self): if not self.checkgenerate(): return OutHeader1("Declaration of C++ to Python callback module " + self.name) Output("#include \"Python.h\"") Output() if self.includestuff: Output("%s", self.includestuff) self.generateBridgeDeclarations() BackGeneratorGroup.generateDeclaration(self) def generateBridgeDeclarations(self): OutHeader1("Glue classes to maintain object identity") Output("class cpppybridge {") Output(" public:") Output(" virtual ~cpppybridge() {};") Output("};") Output() Output("#if 1") Output("extern PyTypeObject pycppbridge_Type;") Output() Output("extern cpppybridge *pycppbridge_getwrapper(PyObject *o);") Output("extern void pycppbridge_setwrapper(PyObject *o, cpppybridge *w);") Output() Output("inline bool pycppbridge_Check(PyObject *x)") OutLbrace() Output("return PyObject_TypeCheck(x, &pycppbridge_Type);") OutRbrace() Output() Output("#else") Output("inline bool pycppbridge_Check(PyObject *x) { return false; };") Output("inline cpppybridge *pycppbridge_getwrapper(PyObject *o) { return NULL; };") Output("inline void pycppbridge_setwrapper(PyObject *o, cpppybridge *w) {};") Output("#endif") Output() def generate(self): if not self.checkgenerate(): return OutHeader1("Callbacks Module " + self.name) if self.includestuff: Output("%s", self.includestuff) BackGeneratorGroup.generate(self) if self.finalstuff: Output() Output("%s", self.finalstuff) OutHeader1("End callbacks module " + self.name)class BackObjectDefinition(BackGeneratorGroup): baseclass = None # Can be overridden by subclasses def __init__(self, name, dummy, itselftype): """ObjectDefinition constructor. May be extended, but do not override. - name: the name of the C++ class we will implement - prefix: the prefix used for the object's functions and data, e.g. 'SndCh'. - itselftype: the C++ base class we need to implement XXX For official Python data types, rules for the 'Py' prefix are a problem. """ BackGeneratorGroup.__init__(self) self.name = name # Gross hack: assume itselftype is a pointer type. Bad bad. assert itselftype[-1] == '*' itselftype = itselftype[:-1] self.itselftype = itselftype #self.objecttype = name + 'Object' #self.typename = name + '_Type' #self.argref = "" # set to "*" if arg to <type>_New should be pointer #self.static = "static " # set to "" to make <type>_New and <type>_Convert public #self.modulename = None self.virtual_destructor = "virtual " # Or "", for non-virtual destructor if hasattr(self, "assertions"): self.assertions() if self.baseclass: self.baseconstructors = ["::%s(itself)" % self.baseclass] else: self.baseconstructors = [] self.othermethods = [] def add(self, g, dupcheck=0): BackGeneratorGroup.add(self, g, dupcheck) g.setClass(self.name) def generate(self): if not self.checkgenerate(): return OutHeader2("Class %s"%self.name) self.outputConstructor() self.outputDestructor() BackGeneratorGroup.generate(self) def generateDeclaration(self): if not self.checkgenerate(): return if self.baseclass: baseclass = "public %s, " % self.baseclass else: baseclass = "public cpppybridge, " Output("class %s : %spublic %s {", self.name, baseclass, self.itselftype) self.generateConDesDeclaration() BackGeneratorGroup.generateDeclaration(self) self.outputOtherMethods() DedentLevel() Output(" private:") IndentLevel() self.outputMembers() self.outputReturnVars() self.outputFriends() DedentLevel() Output("};") Output("#define BGEN_BACK_SUPPORT_%s", self.name) Output("inline %s *Py_WrapAs_%s(PyObject *o)", self.name, self.name) OutLbrace() Output("%s *rv = dynamic_cast<%s*>(pycppbridge_getwrapper(o));", self.name, self.name) Output("if (rv) return rv;") Output("rv = new %s(o);", self.name) Output("pycppbridge_setwrapper(o, rv);") Output("return rv;") OutRbrace() Output() def generateConDesDeclaration(self): # XXX Constructor needs to be private, with WrapAs a friend function Output("public:") IndentLevel() Output("%s(PyObject *itself);", self.name) Output("%s~%s();", self.virtual_destructor, self.name) Output() def outputOtherMethods(self): for om in self.othermethods: Output(om) def outputMembers(self): Output("PyObject *py_%s;", self.name) def outputReturnVars(self): rvdecls = [] for g in self.generators: rv = g.checkreturnvar() if rv: rvdecls.append(rv) for d in rvdecls: Output("%s;", d) def outputFriends(self): Output() Output("friend PyObject *%sObj_New(%s *itself);", self.name, self.itselftype) def outputConstructor(self): Output("%s::%s(PyObject *itself)", self.name, self.name) self.outputConstructorInitializers() OutLbrace() self.beginGIL() self.outputCheckConstructorArg() Output("py_%s = itself;", self.name) Output("Py_XINCREF(itself);") self.endGIL() OutRbrace() Output() def outputConstructorInitializers(self): if self.baseconstructors: # import pdb ; pdb.set_trace() con = ", ".join(self.baseconstructors) Output(":\t%s", con) def outputCheckConstructorArg(self): Output("if (itself)") OutLbrace() self.generateAttributeExistenceTest() OutRbrace() Output("if (itself == NULL) itself = Py_None;") Output() def outputDestructor(self): Output("%s::~%s()", self.name, self.name) OutLbrace() self.beginGIL() Output("Py_XDECREF(py_%s);", self.name) Output("py_%s = NULL;", self.name) self.endGIL() OutRbrace() Output() def beginGIL(self): #OutLbrace() Output("PyGILState_STATE _GILState = PyGILState_Ensure();") def endGIL(self): Output("PyGILState_Release(_GILState);") #OutRbrace() class BackMethodGenerator: def __init__(self, returntype, name, *argumentList, **conditionlist): self.returntype = returntype self.name = name self.argumentList = [] self.parseArgumentList(argumentList) self.classname = '' self.condition = conditionlist.get('condition') self.modifiers = conditionlist.get('modifiers', []) if 'const' in self.modifiers: self.const = ' const' else: self.const = '' self.virtual = 'virtual' in self.modifiers self.rvname = "_rv" self.rv = None self.return_keepref = False def setClass(self, name): self.classname = name
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -