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. 

Reply via email to