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:
Matthias Koefferlein
2017-02-21 23:47:48 +01:00
parent c15179aa19
commit 92fd33744d
1297 changed files with 28436 additions and 66 deletions
+59
View File
@@ -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; }
+5 -1
View File
@@ -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} ();")