WIP: some refactoring of the GSI Python binding (less static objects, new conversion operators, preparations for external use)

This commit is contained in:
Matthias Koefferlein 2018-06-09 01:50:16 +02:00
parent eca8697398
commit 2737e14b13
14 changed files with 106 additions and 85 deletions

View File

@ -19,7 +19,7 @@ QtNetwork.depends += QtCore
QtSql.depends += QtCore QtSql.depends += QtCore
QtWidgets.depends += QtGui QtWidgets.depends += QtGui
QtDesigner.depends += QtCore QtDesigner.depends += QtCore
QtMultimedia.depends += QtCore QtWidgets QtMultimedia.depends += QtCore QtWidgets QtNetwork
QtPrintSupport.depends += QtCore QtWidgets QtPrintSupport.depends += QtCore QtWidgets
QtSvg.depends += QtCore QtWidgets QtSvg.depends += QtCore QtWidgets
QtXmlPatterns.depends += QtCore QtXmlPatterns.depends += QtCore

View File

@ -542,7 +542,7 @@ PythonInterpreter::define_variable (const std::string &name, const std::string &
PythonPtr main_module (PyImport_AddModule ("__main__")); PythonPtr main_module (PyImport_AddModule ("__main__"));
PythonPtr dict (PyModule_GetDict (main_module.get ())); PythonPtr dict (PyModule_GetDict (main_module.get ()));
if (dict) { if (dict) {
PythonRef v (c2python<std::string> (value)); PythonRef v (c2python (value));
PyDict_SetItemString (dict.get (), name.c_str (), v.get ()); PyDict_SetItemString (dict.get (), name.c_str (), v.get ());
} }
} }

View File

@ -444,24 +444,24 @@ template <>
PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c) PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c)
{ {
if (c.is_double ()) { if (c.is_double ()) {
return c2python<double> (c.to_double ()); return c2python (c.to_double ());
} else if (c.is_bool ()) { } else if (c.is_bool ()) {
return c2python<bool> (c.to_bool ()); return c2python (c.to_bool ());
} else if (c.is_a_string ()) { } else if (c.is_a_string ()) {
return c2python<std::string> (c.to_string ()); return c2python (c.to_string ());
} else if (c.is_long ()) { } else if (c.is_long ()) {
return c2python<long> (c.to_long ()); return c2python (c.to_long ());
} else if (c.is_ulong ()) { } else if (c.is_ulong ()) {
return c2python<unsigned long> (c.to_ulong ()); return c2python (c.to_ulong ());
} else if (c.is_longlong ()) { } else if (c.is_longlong ()) {
return c2python<long long> (c.to_longlong ()); return c2python (c.to_longlong ());
} else if (c.is_ulonglong ()) { } else if (c.is_ulonglong ()) {
return c2python<unsigned long long> (c.to_ulonglong ()); return c2python (c.to_ulonglong ());
} else if (c.is_array ()) { } else if (c.is_array ()) {
PyObject *ret = PyDict_New (); PyObject *ret = PyDict_New ();
for (tl::Variant::const_array_iterator i = c.begin_array (); i != c.end_array (); ++i) { for (tl::Variant::const_array_iterator i = c.begin_array (); i != c.end_array (); ++i) {
PyDict_SetItem (ret, c2python<tl::Variant> (i->first), c2python<tl::Variant> (i->second)); PyDict_SetItem (ret, c2python (i->first), c2python (i->second));
} }
return ret; return ret;
@ -470,7 +470,7 @@ PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c)
PyObject *ret = PyList_New (c.get_list ().size ()); PyObject *ret = PyList_New (c.get_list ().size ());
size_t index = 0; size_t index = 0;
for (tl::Variant::const_iterator i = c.begin (); i != c.end (); ++i, ++index) { for (tl::Variant::const_iterator i = c.begin (); i != c.end (); ++i, ++index) {
PyList_SetItem (ret, index, c2python<tl::Variant> (*i)); PyList_SetItem (ret, index, c2python (*i));
} }
return ret; return ret;
@ -545,7 +545,7 @@ PyObject *c2python_func<const QString &>::operator() (const QString &qs)
} else { } else {
// TODO: can be done more efficently // TODO: can be done more efficently
std::string c (tl::to_string (qs)); std::string c (tl::to_string (qs));
return c2python<std::string> (c); return c2python (c);
} }
} }

View File

@ -24,8 +24,9 @@
#ifndef _HDR_pyaConvert #ifndef _HDR_pyaConvert
#define _HDR_pyaConvert #define _HDR_pyaConvert
#include "Python.h" #include <Python.h>
#include "pyaCommon.h"
#include "pyaModule.h" #include "pyaModule.h"
#include "pyaObject.h" #include "pyaObject.h"
#include "gsiClassBase.h" #include "gsiClassBase.h"
@ -63,14 +64,14 @@ class PYAObjectBase;
* @param can_destroy If true, the Python object can be destroyed explicitly * @param can_destroy If true, the Python object can be destroyed explicitly
* @return The Python object * @return The Python object
*/ */
PyObject * PYA_PUBLIC PyObject *
object_to_python (void *obj, PYAObjectBase *self, const gsi::ClassBase *cls, bool pass_obj, bool is_const, bool prefer_copy, bool can_destroy); object_to_python (void *obj, PYAObjectBase *self, const gsi::ClassBase *cls, bool pass_obj, bool is_const, bool prefer_copy, bool can_destroy);
/** /**
* @brief Translates an object to a Python object (PyObject) * @brief Translates an object to a Python object (PyObject)
* This version takes it's flags from the atype given. * This version takes it's flags from the atype given.
*/ */
PyObject * PYA_PUBLIC PyObject *
object_to_python (void *obj, PYAObjectBase *self, const gsi::ArgType &atype); object_to_python (void *obj, PYAObjectBase *self, const gsi::ArgType &atype);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -239,7 +240,7 @@ struct test_type_func<T *>
* @param loose If true, the type is checked more loosely. Use for second-pass matching. * @param loose If true, the type is checked more loosely. Use for second-pass matching.
*/ */
template <class T> template <class T>
inline bool test_type (PyObject * rval, bool loose) inline bool test_type (PyObject * rval, bool loose = false)
{ {
return test_type_func<T> () (rval, loose); return test_type_func<T> () (rval, loose);
} }
@ -248,7 +249,7 @@ inline bool test_type (PyObject * rval, bool loose)
* @brief Test a PyObject *for compatibility with a vector of the given type R * @brief Test a PyObject *for compatibility with a vector of the given type R
*/ */
template <class R> template <class R>
inline bool test_vector (PyObject *arr, bool loose) inline bool test_vector (PyObject *arr, bool loose = false)
{ {
if (PyList_Check (arr)) { if (PyList_Check (arr)) {
@ -283,13 +284,16 @@ inline bool test_vector (PyObject *arr, bool loose)
template <class T> template <class T>
struct python2c_func struct python2c_func
{ {
T operator() (PyObject *rval); T operator() (PyObject * /*rval*/)
{
tl_assert (false); // type not bound
}
}; };
template <> long python2c_func<long>::operator() (PyObject *rval); template <> PYA_PUBLIC long python2c_func<long>::operator() (PyObject *rval);
template <> unsigned long python2c_func<unsigned long>::operator() (PyObject *rval); template <> PYA_PUBLIC unsigned long python2c_func<unsigned long>::operator() (PyObject *rval);
template <> bool python2c_func<bool>::operator() (PyObject *rval); template <> PYA_PUBLIC bool python2c_func<bool>::operator() (PyObject *rval);
template <> char python2c_func<char>::operator() (PyObject *rval); template <> PYA_PUBLIC char python2c_func<char>::operator() (PyObject *rval);
template <class D, class C> template <class D, class C>
struct python2c_func_cast struct python2c_func_cast
@ -308,23 +312,23 @@ template <> struct python2c_func<unsigned short> : public python2c_func_cast<uns
template <> struct python2c_func<int> : public python2c_func_cast<int, long> { }; template <> struct python2c_func<int> : public python2c_func_cast<int, long> { };
template <> struct python2c_func<unsigned int> : public python2c_func_cast<unsigned int, long> { }; template <> struct python2c_func<unsigned int> : public python2c_func_cast<unsigned int, long> { };
template <> long long python2c_func<long long>::operator() (PyObject *rval); template <> PYA_PUBLIC long long python2c_func<long long>::operator() (PyObject *rval);
template <> unsigned long long python2c_func<unsigned long long>::operator() (PyObject *rval); template <> PYA_PUBLIC unsigned long long python2c_func<unsigned long long>::operator() (PyObject *rval);
#if defined(HAVE_64BIT_COORD) #if defined(HAVE_64BIT_COORD)
template <> __int128 python2c_func<__int128>::operator() (PyObject *rval); template <> __int128 python2c_func<__int128>::operator() (PyObject *rval);
#endif #endif
template <> double python2c_func<double>::operator() (PyObject *rval); template <> PYA_PUBLIC double python2c_func<double>::operator() (PyObject *rval);
template <> struct python2c_func<float> : public python2c_func_cast<float, double> { }; template <> struct python2c_func<float> : public python2c_func_cast<float, double> { };
template <> std::string python2c_func<std::string>::operator() (PyObject *rval); template <> PYA_PUBLIC std::string python2c_func<std::string>::operator() (PyObject *rval);
template <> QByteArray python2c_func<QByteArray>::operator() (PyObject *rval); template <> PYA_PUBLIC QByteArray python2c_func<QByteArray>::operator() (PyObject *rval);
template <> QString python2c_func<QString>::operator() (PyObject *rval); template <> PYA_PUBLIC QString python2c_func<QString>::operator() (PyObject *rval);
template <> struct python2c_func<void *> : public python2c_func_cast<void *, size_t> { }; template <> struct python2c_func<void *> : public python2c_func_cast<void *, size_t> { };
template <> tl::Variant python2c_func<tl::Variant>::operator() (PyObject *rval); template <> PYA_PUBLIC tl::Variant python2c_func<tl::Variant>::operator() (PyObject *rval);
template <class T> struct python2c_func<T &> template <class T> struct python2c_func<T &>
{ {
@ -593,10 +597,14 @@ struct c2python_func<float>
} }
}; };
template <> PyObject *c2python_func<const char *>::operator() (const char *); template <> PYA_PUBLIC PyObject *c2python_func<const char *>::operator() (const char *);
template <> PyObject *c2python_func<const QString &>::operator() (const QString &c);
template <> PyObject *c2python_func<const QByteArray &>::operator() (const QByteArray &c); template <> PYA_PUBLIC PyObject *c2python_func<const QString &>::operator() (const QString &c);
template <> PyObject *c2python_func<const std::string &>::operator() (const std::string &c); template <> struct c2python_func<QString> : public c2python_func<const QString &> { };
template <> PYA_PUBLIC PyObject *c2python_func<const QByteArray &>::operator() (const QByteArray &c);
template <> struct c2python_func<QByteArray> : public c2python_func<const QByteArray &> { };
template <> PYA_PUBLIC PyObject *c2python_func<const std::string &>::operator() (const std::string &c);
template <> struct c2python_func<std::string> : public c2python_func<const std::string &> { };
template <> template <>
struct c2python_func<void *> struct c2python_func<void *>
@ -608,7 +616,8 @@ struct c2python_func<void *>
} }
}; };
template <> PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c); template <> PYA_PUBLIC PyObject *c2python_func<const tl::Variant &>::operator() (const tl::Variant &c);
template <> struct c2python_func<tl::Variant> : public c2python_func<const tl::Variant &> { };
/** /**
* @brief Converts the Python object to the given type * @brief Converts the Python object to the given type

View File

@ -474,25 +474,25 @@ struct reader
void operator() (gsi::SerialArgs *rr, PythonRef *ret, PyObject * /*self*/, const gsi::ArgType &arg, tl::Heap *heap) void operator() (gsi::SerialArgs *rr, PythonRef *ret, PyObject * /*self*/, const gsi::ArgType &arg, tl::Heap *heap)
{ {
if (arg.is_ref ()) { if (arg.is_ref ()) {
*ret = c2python<R> (rr->template read<R &> (*heap)); *ret = c2python (rr->template read<R &> (*heap));
} else if (arg.is_cref ()) { } else if (arg.is_cref ()) {
*ret = c2python<R> (rr->template read<const R &> (*heap)); *ret = c2python (rr->template read<const R &> (*heap));
} else if (arg.is_ptr ()) { } else if (arg.is_ptr ()) {
R *p = rr->template read<R *> (*heap); R *p = rr->template read<R *> (*heap);
if (p) { if (p) {
*ret = c2python<R> (*p); *ret = c2python (*p);
} else { } else {
*ret = PythonRef (Py_None, false /*borrowed*/); *ret = PythonRef (Py_None, false /*borrowed*/);
} }
} else if (arg.is_cptr ()) { } else if (arg.is_cptr ()) {
const R *p = rr->template read<const R *> (*heap); const R *p = rr->template read<const R *> (*heap);
if (p) { if (p) {
*ret = c2python<R> (*p); *ret = c2python (*p);
} else { } else {
*ret = PythonRef (Py_None, false /*borrowed*/); *ret = PythonRef (Py_None, false /*borrowed*/);
} }
} else { } else {
*ret = c2python<R> (rr->template read<R> (*heap)); *ret = c2python (rr->template read<R> (*heap));
} }
} }
}; };
@ -512,7 +512,7 @@ struct reader<void *>
tl_assert (! arg.is_ref ()); tl_assert (! arg.is_ref ());
tl_assert (! arg.is_cptr ()); tl_assert (! arg.is_cptr ());
tl_assert (! arg.is_ptr ()); tl_assert (! arg.is_ptr ());
*ret = c2python<void *> (rr->read<void *> (*heap)); *ret = c2python (rr->read<void *> (*heap));
} }
}; };
@ -528,7 +528,7 @@ struct reader<gsi::StringType>
if (!a.get ()) { if (!a.get ()) {
*ret = PythonRef (Py_None, false /*borrowed*/); *ret = PythonRef (Py_None, false /*borrowed*/);
} else { } else {
*ret = c2python<std::string> (std::string (a->c_str (), a->size ())); *ret = c2python (std::string (a->c_str (), a->size ()));
} }
} }
}; };
@ -582,7 +582,7 @@ PyObject *object_from_variant (const tl::Variant &var, PYAObjectBase *self, cons
return object_to_python ((void *) var.to_user (), self, var.user_cls ()->gsi_cls (), pass_obj, is_const, prefer_copy, can_destroy); return object_to_python ((void *) var.to_user (), self, var.user_cls ()->gsi_cls (), pass_obj, is_const, prefer_copy, can_destroy);
} else { } else {
return c2python<tl::Variant> (var); return c2python (var);
} }
} }

View File

@ -35,18 +35,6 @@
namespace pya namespace pya
{ {
// -------------------------------------------------------------------
// A metatype object to identify the pya types
struct PYAMetaType : public PyTypeObject { };
static PYAMetaType PYA_MetaType;
struct PYATypeObject
: public PyTypeObject
{
const gsi::ClassBase *cls;
};
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// The lookup table for the method overload resolution // The lookup table for the method overload resolution
@ -930,7 +918,7 @@ object_default_ne_impl (PyObject *self, PyObject *args)
if (! res) { if (! res) {
return NULL; return NULL;
} else { } else {
return c2python<bool> (! python2c<bool> (res.get ())); return c2python (! python2c<bool> (res.get ()));
} }
} }
@ -947,7 +935,7 @@ object_default_ge_impl (PyObject *self, PyObject *args)
if (! res) { if (! res) {
return NULL; return NULL;
} else { } else {
return c2python<bool> (! python2c<bool> (res.get ())); return c2python (! python2c<bool> (res.get ()));
} }
} }
@ -971,7 +959,7 @@ object_default_le_impl (PyObject *self, PyObject *args)
if (! lt_res) { if (! lt_res) {
return NULL; return NULL;
} }
return c2python<bool> (python2c<bool> (eq_res.get ()) || python2c<bool> (lt_res.get ())); return c2python (python2c<bool> (eq_res.get ()) || python2c<bool> (lt_res.get ()));
} }
/** /**
@ -994,7 +982,7 @@ object_default_gt_impl (PyObject *self, PyObject *args)
if (! lt_res) { if (! lt_res) {
return NULL; return NULL;
} }
return c2python<bool> (! (python2c<bool> (eq_res.get ()) || python2c<bool> (lt_res.get ()))); return c2python (! (python2c<bool> (eq_res.get ()) || python2c<bool> (lt_res.get ())));
} }
/** /**
@ -1063,7 +1051,7 @@ object_destroyed (PyObject *self, PyObject *args)
return NULL; return NULL;
} }
return c2python<bool> (((PYAObjectBase *) self)->destroyed ()); return c2python (((PYAObjectBase *) self)->destroyed ());
} }
/** /**
@ -1076,7 +1064,7 @@ object_is_const (PyObject *self, PyObject *args)
return NULL; return NULL;
} }
return c2python<bool> (((PYAObjectBase *) self)->const_ref ()); return c2python (((PYAObjectBase *) self)->const_ref ());
} }
static PyObject * static PyObject *
@ -2149,6 +2137,7 @@ property_setter_func (PyObject *self, PyObject *value, void *closure)
// The PythonModule implementation // The PythonModule implementation
std::map<const gsi::MethodBase *, std::string> PythonModule::m_python_doc; std::map<const gsi::MethodBase *, std::string> PythonModule::m_python_doc;
std::vector<const gsi::ClassBase *> PythonModule::m_classes;
const std::string pymod_name ("pykl"); const std::string pymod_name ("pykl");
@ -2350,16 +2339,10 @@ PythonModule::make_classes (const char *mod_name)
m_base_class_name = m_mod_name + ".__Base"; m_base_class_name = m_mod_name + ".__Base";
// Late-initialize PYA_MetaType (we can do this multiple times as the initialization does not PyTypeObject *base_class = (PyTypeObject *) PyType_Type.tp_alloc (&PyType_Type, 0);
// change anything). PYATypeObject adds one pointer member at the end.
memcpy(&PYA_MetaType, &PyType_Type, sizeof (PyType_Type));
PYA_MetaType.tp_basicsize += sizeof (void *);
PYATypeObject *base_class = (PYATypeObject *) PyType_Type.tp_alloc (&PYA_MetaType, sizeof (PYATypeObject));
tl_assert (base_class != NULL); tl_assert (base_class != NULL);
mp_base_class = PythonRef ((PyObject *) base_class); mp_base_class = PythonRef ((PyObject *) base_class);
base_class->cls = 0; // base class
base_class->tp_base = &PyBaseObject_Type; base_class->tp_base = &PyBaseObject_Type;
base_class->tp_name = m_base_class_name.c_str (); base_class->tp_name = m_base_class_name.c_str ();
base_class->tp_basicsize = sizeof (PYAObjectBase); base_class->tp_basicsize = sizeof (PYAObjectBase);
@ -2442,6 +2425,11 @@ PythonModule::make_classes (const char *mod_name)
any = true; any = true;
// Create the actual class
m_classes.push_back (c.operator-> ());
PythonRef bases (PyTuple_New (1)); PythonRef bases (PyTuple_New (1));
PyObject *base = mp_base_class.get (); PyObject *base = mp_base_class.get ();
if (c->base () != 0) { if (c->base () != 0) {
@ -2455,16 +2443,21 @@ PythonModule::make_classes (const char *mod_name)
PythonRef dict (PyDict_New ()); PythonRef dict (PyDict_New ());
PyDict_SetItemString (dict.get (), "__module__", PythonRef (c2python (m_mod_name)).get ()); PyDict_SetItemString (dict.get (), "__module__", PythonRef (c2python (m_mod_name)).get ());
PyDict_SetItemString (dict.get (), "__doc__", PythonRef (c2python (c->doc ())).get ()); PyDict_SetItemString (dict.get (), "__doc__", PythonRef (c2python (c->doc ())).get ());
PyDict_SetItemString (dict.get (), "__gsi_id__", PythonRef (c2python (m_classes.size () - 1)).get ());
PythonRef args (PyTuple_New (3)); PythonRef args (PyTuple_New (3));
PyTuple_SetItem (args.get (), 0, c2python (c->name ())); PyTuple_SetItem (args.get (), 0, c2python (c->name ()));
PyTuple_SetItem (args.get (), 1, bases.release ()); PyTuple_SetItem (args.get (), 1, bases.release ());
PyTuple_SetItem (args.get (), 2, dict.release ()); PyTuple_SetItem (args.get (), 2, dict.release ());
PYATypeObject *type = (PYATypeObject *) PyObject_Call ((PyObject *) &PYA_MetaType, args.get (), NULL); PyTypeObject *type = (PyTypeObject *) PyObject_Call ((PyObject *) &PyType_Type, args.get (), NULL);
type->cls = c.operator-> (); if (type == NULL) {
check_error ();
tl_assert (false);
}
PythonClassClientData::initialize (*c, type); PythonClassClientData::initialize (*c, type);
tl_assert (type != NULL);
tl_assert (cls_for_type (type) == c.operator-> ()); // @@@
PyList_Append (all_list.get (), PythonRef (c2python (c->name ())).get ()); PyList_Append (all_list.get (), PythonRef (c2python (c->name ())).get ());
PyModule_AddObject (module, c->name ().c_str (), (PyObject *) type); PyModule_AddObject (module, c->name ().c_str (), (PyObject *) type);
@ -2888,7 +2881,7 @@ PythonModule::make_classes (const char *mod_name)
} else { } else {
PyObject *desc = PYAAmbiguousMethodDispatcher::create (attr_inst, attr_class); PyObject *desc = PYAAmbiguousMethodDispatcher::create (attr_inst, attr_class);
PythonRef name (c2python<std::string> (*a)); PythonRef name (c2python (*a));
// Note: we use GenericSetAttr since that one allows us setting attributes on built-in types // Note: we use GenericSetAttr since that one allows us setting attributes on built-in types
PyObject_GenericSetAttr ((PyObject *) type, name.get (), desc); PyObject_GenericSetAttr ((PyObject *) type, name.get (), desc);
@ -2910,14 +2903,19 @@ PythonModule::make_classes (const char *mod_name)
const gsi::ClassBase *PythonModule::cls_for_type (PyTypeObject *type) const gsi::ClassBase *PythonModule::cls_for_type (PyTypeObject *type)
{ {
while (type) { // GSI classes store their class index inside the __gsi_id__ attribute
// all pya class use our own metatype if (PyObject_HasAttrString ((PyObject *) type, "__gsi_id__")) {
if (type->ob_type == &PYA_MetaType) {
return ((PYATypeObject *)type)->cls; PyObject *cls_id = PyObject_GetAttrString ((PyObject *) type, "__gsi_id__");
if (cls_id != NULL && pya::test_type<size_t> (cls_id)) {
size_t i = pya::python2c<size_t> (cls_id);
if (i < m_classes.size ()) {
return m_classes [i];
}
} }
// not found - try base class
type = type->tp_base;
} }
return 0; return 0;
} }

View File

@ -112,6 +112,7 @@ private:
char *mp_mod_def; char *mp_mod_def;
static std::map<const gsi::MethodBase *, std::string> m_python_doc; static std::map<const gsi::MethodBase *, std::string> m_python_doc;
static std::vector<const gsi::ClassBase *> m_classes;
}; };
} }

View File

@ -32,6 +32,7 @@
#include "tlObject.h" #include "tlObject.h"
#include "pyaRefs.h" #include "pyaRefs.h"
#include "pyaCommon.h"
namespace pya namespace pya
{ {
@ -176,7 +177,7 @@ private:
* Note: the PYAObjectBase must be directly derived from PyObject so that * Note: the PYAObjectBase must be directly derived from PyObject so that
* a PyObject pointer can be cast to a PYAObjectBase pointer. * a PyObject pointer can be cast to a PYAObjectBase pointer.
*/ */
class PYAObjectBase class PYA_PUBLIC PYAObjectBase
: public PyObject : public PyObject
{ {
public: public:

View File

@ -114,13 +114,13 @@ PyObject *PythonRef::release ()
PythonPtr::PythonPtr () PythonPtr::PythonPtr ()
: mp_obj (NULL) : mp_obj (NULL)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
PythonPtr::PythonPtr (PyObject *obj) PythonPtr::PythonPtr (PyObject *obj)
: mp_obj (obj) : mp_obj (obj)
{ {
Py_XINCREF (obj); Py_XINCREF (obj);
} }

View File

@ -24,6 +24,8 @@
#ifndef _HDR_pyaRefs #ifndef _HDR_pyaRefs
#define _HDR_pyaRefs #define _HDR_pyaRefs
#include "pyaCommon.h"
struct _object; struct _object;
typedef _object PyObject; typedef _object PyObject;
@ -41,7 +43,7 @@ class PythonPtr;
* borrowed references too. * borrowed references too.
* PythonRef will basically become the owner of the referred object. * PythonRef will basically become the owner of the referred object.
*/ */
class PythonRef class PYA_PUBLIC PythonRef
{ {
public: public:
/** /**
@ -140,7 +142,7 @@ private:
* This reference represents borrowed references. Upon construction and destruction, this * This reference represents borrowed references. Upon construction and destruction, this
* object will automatically increment and decrement the reference count. * object will automatically increment and decrement the reference count.
*/ */
class PythonPtr class PYA_PUBLIC PythonPtr
{ {
public: public:
/** /**

View File

@ -8,4 +8,4 @@ SOURCES = \
HEADERS += \ HEADERS += \
LIBS += -lklayout_QtMultimedia LIBS += -lklayout_QtMultimedia -lklayout_QtNetwork

View File

@ -26,4 +26,9 @@
#include "../../gsiqt/qtbasic/gsiQtMultimediaExternals.h" #include "../../gsiqt/qtbasic/gsiQtMultimediaExternals.h"
FORCE_LINK_GSI_QTMULTIMEDIA FORCE_LINK_GSI_QTMULTIMEDIA
// This is required because QAction and QWidget are used are arguments in QtGui, but are
// defined in QtWidgets
#include "../../gsiqt/qtbasic/gsiQtNetworkExternals.h"
FORCE_LINK_GSI_QTNETWORK
DEFINE_PYMOD(QtMultimedia, "QtMultimedia", "KLayout/Qt module 'QtMultimedia'") DEFINE_PYMOD(QtMultimedia, "QtMultimedia", "KLayout/Qt module 'QtMultimedia'")

View File

@ -3,7 +3,9 @@ DESTDIR = $$OUT_PWD/..
LIBDIR = $$OUT_PWD/../.. LIBDIR = $$OUT_PWD/../..
DESTDIR_PYMOD = $$LIBDIR/pykl DESTDIR_PYMOD = $$LIBDIR/pykl
include($$PWD/../lib.pri) TEMPLATE = lib
include($$PWD/../klayout.pri)
INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC INCLUDEPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC
DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC DEPENDPATH += $$PYTHONINCLUDE $$TL_INC $$GSI_INC $$PYA_INC

View File

@ -35,5 +35,8 @@ equals(HAVE_QTBINDINGS, "1") {
} }
ALL_DIRS = $$SUBDIRS ALL_DIRS = $$SUBDIRS
SUBDIRS += unit_tests SUBDIRS += unit_tests
unit_tests.depends += $$ALL_DIRS SUBDIRS += bridge_sample
unit_tests.depends += $$ALL_DIRS bridge_sample