twidgets_unown.nim 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. discard """
  2. cmd: '''nim c -d:nimAllocStats --newruntime $file'''
  3. output: '''button
  4. clicked!
  5. (allocCount: 6, deallocCount: 6)'''
  6. """
  7. import system / ansi_c
  8. type
  9. Widget* = ref object of RootObj
  10. drawImpl: owned(proc (self: Widget))
  11. Button* = ref object of Widget
  12. caption: string
  13. onclick: owned(proc())
  14. Window* = ref object of Widget
  15. elements: seq[owned Widget]
  16. proc newButton(caption: string; onclick: owned(proc())): owned Button =
  17. proc draw(self: Widget) =
  18. let b = Button(self)
  19. echo b.caption
  20. #result = Button(drawImpl: draw, caption: caption, onclick: onclick)
  21. new(result)
  22. result.drawImpl = draw
  23. result.caption = caption
  24. result.onclick = onclick
  25. proc newWindow(): owned Window =
  26. proc windraw(self: Widget) =
  27. let w = Window(self)
  28. for e in unown(w.elements):
  29. let d = unown e.drawImpl
  30. if not d.isNil: d(e)
  31. result = Window(drawImpl: windraw, elements: @[])
  32. proc draw(w: Widget) =
  33. let d = unown w.drawImpl
  34. if not d.isNil: d(w)
  35. proc add*(w: Window; elem: owned Widget) =
  36. w.elements.add elem
  37. proc main =
  38. var w = newWindow()
  39. var b = newButton("button", nil)
  40. let u = unown b
  41. var clicked = "clicked"
  42. b.onclick = proc () =
  43. clicked.add "!"
  44. u.caption = clicked
  45. w.add b
  46. w.draw()
  47. # simulate button click:
  48. u.onclick()
  49. w.draw()
  50. # bug #11257
  51. var a: owned proc()
  52. if a != nil:
  53. a()
  54. dumpAllocStats:
  55. main()