HapticX / happyx

Macro-oriented asynchronous web-framework written in Nim with ♥
https://hapticx.github.io/happyx/
MIT License
540 stars 18 forks source link

double-calling of component field initialization procs 🐛 #244

Closed quimt closed 8 months ago

quimt commented 9 months ago

Describe the bug 🐛 Sometimes component fields initialize twice..and sometimes they don't. This matters in cases where components change external state on creation.

To Reproduce 👨‍🔬


var index = 0

proc newIndex(): int =
  result = index
  index += 1

type refIndex = ref object
  value*: int

var rindex = refIndex(value:0)
var sindex = refIndex(value:0)
var tindex = refIndex(value:0)
var uindex = refIndex(value:0)

proc nextIndex(r: refIndex): int =
  result = r.value
  r.value += 1

proc newIndexByRef(): int =
  result = rindex.value
  rindex.value += 1

component Index:
  index: int = newIndex()
  Rindex: int = newIndexByRef()
  myRefIndex: refIndex = sindex
  Sindex: int = myRefIndex.nextIndex()
  html:
    tDiv: "my index is {self.index.val}"
    tDiv(style="color:purple"): "my refIndex is {self.Rindex.val}"
    tDiv(style="color:orange"): "my internal refIndex is {self.Sindex.val}"
    tDiv(style="color:green"): "my refIndex from the main body is {uindex.nextIndex()}"

appRoutes("ROOT"):
  "/":
    Index
    Index
    Index
    for i in 1..3:
      tDiv(style="color:green"):
        "call from route: {tindex.nextIndex()}"

Each successive call of each type should count 0,1,2... but that is not what we see. image

Interestingly the double-calling disappears when it is based on a reference stored in another field.

noted on happyx@#head: https://github.com/HapticX/happyx/commit/1fbc1a93f750edc6a03daafc855658f316c25db5 maybe connected with resolution to #237?

Ethosa commented 8 months ago

So, this behavior is really weird.

Reason was here (I added .typeof.default and this now works as expected): image

image

Solved in the next commit :)