diff options
Diffstat (limited to 'tests/destructor/twidgets_unown.nim')
-rw-r--r-- | tests/destructor/twidgets_unown.nim | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/tests/destructor/twidgets_unown.nim b/tests/destructor/twidgets_unown.nim new file mode 100644 index 000000000..8653d5c28 --- /dev/null +++ b/tests/destructor/twidgets_unown.nim @@ -0,0 +1,72 @@ +discard """ + cmd: '''nim c -d:nimAllocStats --newruntime $file''' + output: '''button +clicked! +(allocCount: 6, deallocCount: 6)''' +""" + +import system / ansi_c + +type + Widget* = ref object of RootObj + drawImpl: owned(proc (self: Widget)) + + Button* = ref object of Widget + caption: string + onclick: owned(proc()) + + Window* = ref object of Widget + elements: seq[owned Widget] + + +proc newButton(caption: string; onclick: owned(proc())): owned Button = + proc draw(self: Widget) = + let b = Button(self) + echo b.caption + + #result = Button(drawImpl: draw, caption: caption, onclick: onclick) + new(result) + result.drawImpl = draw + result.caption = caption + result.onclick = onclick + +proc newWindow(): owned Window = + proc windraw(self: Widget) = + let w = Window(self) + for e in unown(w.elements): + let d = unown e.drawImpl + if not d.isNil: d(e) + + result = Window(drawImpl: windraw, elements: @[]) + +proc draw(w: Widget) = + let d = unown w.drawImpl + if not d.isNil: d(w) + +proc add*(w: Window; elem: owned Widget) = + w.elements.add elem + +proc main = + var w = newWindow() + + var b = newButton("button", nil) + let u = unown b + var clicked = "clicked" + b.onclick = proc () = + clicked.add "!" + u.caption = clicked + w.add b + + w.draw() + # simulate button click: + u.onclick() + + w.draw() + + # bug #11257 + var a: owned proc() + if a != nil: + a() + +dumpAllocStats: + main() |