Replacing finalizers with destructors for gintro seems to work in principle, at
least I got cairo_anim.nim running with a few hacks.
Problem is similar as with finalizers -- for callback vars owned by gtk we do
not want a finalizer or destroy call, while for ordinary use we want the call.
For finalizers I made the var global to prevent finalizer call. But for destroy
global pragma makes no difference. What I have is basically
type
Context00* = object
Context* = object of RootObj
impl*: ptr Context00
proc `=destroy`*(s: var Context) =
echo "=destroy called"
if s.impl != nil:
cairo_destroy(s.impl)
s.impl = nil
proc `=sink`*(s: var Context; x: Context) =
echo "=sink called"
if s.impl != nil and s.impl != x.impl:
cairo_destroy(s.impl)
s.impl = nil
s.impl = x.impl
Run
and the macro generated callback proc
proc connect_for_signal_cdecl_draw1(self: ptr Widget00; cr: ptr
cairo.Context00; data: pointer): gboolean {.cdecl.} =
let h: pointer = g_object_get_qdata(self, Quark)
var cr1: cairo.Context
cr1.impl = cr
drawingAreaDrawCb(cast[DrawingArea](h), cr1).ord.gboolean
Run
(Here drawingAreaDrawCb() is the user provided high level callback proc.)
Unfortunately at the end of connect proc =destroy is called for cr1, resulting
in freeing cr which is owned by gtk.
I tried sink and lent modifier for cr1, but that does not work, at least not in
macro. So there remain two solutions:
1: cr1.impl = nil at end of connect proc, so destroy is called but does nothing.
2: Use ContextXX* = object of Context for type of cr1, that prevents call of
=destroy currently, but I am not sure if that is guaranteed.