twidgets_unown.nim 1.5 KB

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