Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
DispatchPtr.cxx
Go to the documentation of this file.
1// Bindings
2#include "CPyCppyy.h"
3#define CPYCPPYY_INTERNAL 1
5#undef CPYCPPYY_INTERNAL
6#include "CPPInstance.h"
7#include "CPPScope.h"
8
9
10//-----------------------------------------------------------------------------
12{
13 if (fPyHardRef) return fPyHardRef;
14 if (fPyWeakRef) {
15 PyObject* disp = PyWeakref_GetObject(fPyWeakRef);
16 if (disp != Py_None) // dispatcher object disappeared?
17 return disp;
18 }
19 return nullptr;
20}
21
22//-----------------------------------------------------------------------------
23CPyCppyy::DispatchPtr::DispatchPtr(PyObject* pyobj, bool strong) : fPyHardRef(nullptr)
24{
25 if (strong) {
26 Py_INCREF(pyobj);
27 fPyHardRef = pyobj;
28 fPyWeakRef = nullptr;
29 } else {
30 fPyHardRef = nullptr;
31 fPyWeakRef = PyWeakref_NewRef(pyobj, nullptr);
32 }
33 ((CPPInstance*)pyobj)->SetDispatchPtr(this);
34}
35
36//-----------------------------------------------------------------------------
37CPyCppyy::DispatchPtr::DispatchPtr(const DispatchPtr& other, void* cppinst) : fPyWeakRef(nullptr)
38{
39 PyObject* pyobj = other.Get();
40 fPyHardRef = pyobj ? (PyObject*)((CPPInstance*)pyobj)->Copy(cppinst) : nullptr;
41 if (fPyHardRef) ((CPPInstance*)fPyHardRef)->SetDispatchPtr(this);
42}
43
44//-----------------------------------------------------------------------------
46// if we're holding a hard reference, or holding weak reference while being part
47// of a dispatcher intermediate, then this delete is from the C++ side, and Python
48// is "notified" by nulling out the reference and an exception will be raised on
49// continued access
50 if (fPyWeakRef) {
51 PyObject* pyobj = PyWeakref_GetObject(fPyWeakRef);
52 if (pyobj && pyobj != Py_None && ((CPPScope*)Py_TYPE(pyobj))->fFlags & CPPScope::kIsPython)
53 ((CPPInstance*)pyobj)->GetObjectRaw() = nullptr;
54 Py_DECREF(fPyWeakRef);
55 } else if (fPyHardRef) {
56 ((CPPInstance*)fPyHardRef)->GetObjectRaw() = nullptr;
57 Py_DECREF(fPyHardRef);
58 }
59}
60
61//-----------------------------------------------------------------------------
63{
64 if (this != &other) {
65 Py_XDECREF(fPyWeakRef); fPyWeakRef = nullptr;
66 Py_XDECREF(fPyHardRef);
67 PyObject* pyobj = other.Get();
68 fPyHardRef = pyobj ? (PyObject*)((CPPInstance*)pyobj)->Copy(cppinst) : nullptr;
69 if (fPyHardRef) ((CPPInstance*)fPyHardRef)->SetDispatchPtr(this);
70 }
71 return *this;
72}
73
74//-----------------------------------------------------------------------------
76{
77// Python maintains the hardref, so only allowed a weakref here
78 if (fPyHardRef) {
79 fPyWeakRef = PyWeakref_NewRef(fPyHardRef, nullptr);
80 Py_DECREF(fPyHardRef); fPyHardRef = nullptr;
81 }
82}
83
84//-----------------------------------------------------------------------------
86{
87// C++ maintains the hardref, keeping the PyObject alive w/o outstanding ref
88 if (fPyWeakRef) {
89 fPyHardRef = PyWeakref_GetObject(fPyWeakRef);
90 if (fPyHardRef == Py_None) fPyHardRef = nullptr;
91 Py_XINCREF(fPyHardRef);
92 Py_DECREF(fPyWeakRef); fPyWeakRef = nullptr;
93 }
94}
#define Py_TYPE(ob)
Definition CPyCppyy.h:196
_object PyObject
std::ios_base::fmtflags fFlags
DispatchPtr & assign(const DispatchPtr &other, void *cppinst)
PyObject * Get() const