mirror of
https://github.com/KLayout/klayout.git
synced 2026-08-29 01:14:35 +02:00
WIP: first solution for lost references issue
* The solution consists of attaching a bridge object to QObjects. If the host object is destroyed, the bridge object will notify the script client * The bridge object attachment is optimized so it only happens if required (but still too often ...) * The child object of QChildEvent gets a special handling since this object is almost dead in case of remove. This special handling consists of a special, stripped class which is used to only represent QObject in that particular case.
This commit is contained in:
@@ -192,6 +192,7 @@ drop_method "QObject", /QObject::findChild/ # template member
|
||||
drop_method "QObject", /QObject::findChildren/ # template member
|
||||
drop_method "QObject", /QObject::setUserData/ # QObjectUserData not available
|
||||
drop_method "QObject", /QObject::userData/ # QObjectUserData not available
|
||||
drop_method "QChildEvent", /QChildEvent::child/ # provided through a special implementation
|
||||
drop_method "QFile", /QFile::setDecodingFunction/ # uses callbacks
|
||||
drop_method "QFile", /QFile::setEncodingFunction/ # uses callbacks
|
||||
drop_method "QFile", /QFile::open.*IO_FILE/ # uses internal struct
|
||||
@@ -272,6 +273,64 @@ CODE
|
||||
gsi::method_ext("findChild", &find_child_impl, "@brief Specialisation for findChild (uses QObject as T).")
|
||||
DECL
|
||||
|
||||
# alternative implementation for QChildEvent::child
|
||||
# Reason: this method does not supply a true QObject pointer. Instead it will
|
||||
# deliver a pointer to an object that is almost destroyed. Normal RTTI will
|
||||
# not work on this. Neighter can it be attached an gsi::ObjectBase object.
|
||||
add_native_impl("QChildEvent", <<'CODE', <<'DECL')
|
||||
|
||||
namespace gsi
|
||||
{
|
||||
gsi::Class<QObject> &qtdecl_QObject ();
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct DummyQObject { };
|
||||
|
||||
class RawQObjectClass
|
||||
: public gsi::Class<QObject>
|
||||
{
|
||||
public:
|
||||
RawQObjectClass ()
|
||||
: gsi::Class<QObject> (gsi::qtdecl_QObject (), "QObject_Raw", gsi::Methods (), "@hide")
|
||||
{
|
||||
}
|
||||
|
||||
// Final class - because of missing RTTI, subclassing won't work.
|
||||
virtual const gsi::ClassBase *subclass_decl (const void *) const { return this; }
|
||||
virtual bool can_upcast (const void *) const { return false; }
|
||||
|
||||
// Does not bind to a particular type
|
||||
virtual bool is_of_type (const std::type_info & /*ti*/) const { return false; }
|
||||
virtual const std::type_info &type () const { return typeid (DummyQObject); }
|
||||
};
|
||||
}
|
||||
|
||||
static void _init_f_child (qt_gsi::GenericMethod *decl)
|
||||
{
|
||||
// Make the QChildEvent::child method return a special class which is final
|
||||
// and does not try to return a gsi::ObjectBase object.
|
||||
static RawQObjectClass s_cls;
|
||||
decl->set_return<QObject * > ();
|
||||
decl->ret_type ().set_cls (&s_cls);
|
||||
}
|
||||
|
||||
static void _call_f_child (const qt_gsi::GenericMethod * /*decl*/, void *cls, gsi::SerialArgs & /*args*/, gsi::SerialArgs &ret)
|
||||
{
|
||||
ret.write<QObject * > ((QObject *)((QChildEvent *)cls)->child ());
|
||||
}
|
||||
|
||||
CODE
|
||||
gsi::Methods(new qt_gsi::GenericMethod ("child",
|
||||
"@brief Method QObject *QChildEvent::child()\n"
|
||||
"NOTE: the object returned by this method is not memory managed. It may be destroyed internally without notice. \n"
|
||||
"The returned object shall not be stored or used outside the childEvent handler. "
|
||||
"If used outside this handler, the reference might get lost and the application may crash.\n"
|
||||
"Furthermore, the object returned will only represent a QObject, not any derived type.\n",
|
||||
true, &_init_f_child, &_call_f_child))
|
||||
DECL
|
||||
|
||||
# alternative implementation for QFont::Light, QFont::Bold, QFont::Normal, QFont::DemiBold, QFont::Black
|
||||
add_native_impl("QFont", <<'CODE', <<'DECL')
|
||||
static unsigned int font_const_light () { return (unsigned int) QFont::Light; }
|
||||
|
||||
@@ -2211,7 +2211,11 @@ END
|
||||
ofile.puts("}")
|
||||
ofile.puts("")
|
||||
|
||||
decl_type = "gsi::Class<#{cls}>"
|
||||
if is_qobject
|
||||
decl_type = "qt_gsi::QtNativeClass<#{cls}>"
|
||||
else
|
||||
decl_type = "gsi::Class<#{cls}>"
|
||||
end
|
||||
|
||||
if base_cls
|
||||
ofile.puts("gsi::Class<#{base_cls}> &qtdecl_#{base_clsn} ();")
|
||||
|
||||
Reference in New Issue
Block a user