Open HertzDevil opened 4 years ago
I'm not sure if we should go with a QObject-only approach. I currently see two possibilities that'd work for everything:
final
- Which isn't used in Qt afaik, but in general, I think it'll become more popular with time. I'm not familiar with the modern Crystal memory layout, so I presume we can't frankenstein a Crystal object and the C++ object into something C++ and Crystal can work at once with (This'd make self == @unwrap
).SIP is to PyQt5 what Bindgen is to qt5.cr, and it seems they took the second approach: https://github.com/eduardosm/sip-4.19.7/blob/master/siplib/objmap.c
Their wrapper structs look rather fat too, despite Python being dynamically typed (or perhaps that is the reason). I imagine the #to_crystal
code would remain largely the same, the major difference being where the CrystalAny
is stored.
Regarding Boehm GC: defining #finalize
should be the same as using GC_register_finalizer_ignore_self
or passing a C++ finalizer function next to UseGC
.
Regarding Boehm GC: defining #finalize should be the same as using GC_register_finalizer_ignore_self or passing a C++ finalizer function next to UseGC.
Yup, that'd be fine. However, I'm not sure if this works even for structures that didn't go through Boehms new
/malloc()
.
Once a Crystal wrapper type reaches C++, it loses its Crystal type information because only
@unwrap
remains, which is the pointer to the original C++ instance; something must keep track of the Crystal instance in a C++ instance.QObject
, the base class of most virtual classes, doesn't offer anyvoid *
instance variable, but it has dynamic properties. So my idea is:CrystalVariant
to a different name likeCrystalAny
, since it can store any Crystal value, but isn't really a drop-in replacement forQVariant
;QVariant
normally, removing the entire type configuration inconfig/types.yml
;qvariant_to_crystal
andcrystal_to_qvariant
to Crystal manually;Qt::Object
, convert the instance into aQt::Variant
storing aCrystalAny
;_bindgen_value
for example (since Crystal wrappers never callsuper
in their#initialize
methods, this will be stored exactly once), most likely through a code body hook;Qt::Object#to_crystal(T.class)
insrc/qt5/object.cr
, which reads the dynamic property and converts it back to a Crystal value of typeT
, and similarly for the non-throwing#to_crystal?
. Suppose thatMyWidget < Qt::Widget < Qt::Object
. Then calling#to_crystal?(MyWidget)
would be something like:#to_crystal
works even for descendents of abstract wrapper types. IfMyGraphicsItem, Qt::GraphicsItemImpl < Qt::GraphicsItem
:This will be helpful whenever a Qt function returns a Qt object where subclassing is expected. It also makes
Qt::Variant
usable (to be fair I see no problems with Qt's original interface, but more importantly the type shouldn't give the impression that Crystal types are already integrated within the Qt meta-object system).Any thoughts on this?