diff --git a/diffDomTests.nim b/diffDomTests.nim index 2fa9ccf..fe808f6 100644 --- a/diffDomTests.nim +++ b/diffDomTests.nim @@ -176,6 +176,3 @@ proc onload(session: cstring) {.exportc.} = t += dtReset timeout = setTimeout(test7, t) - t += dtTest - timeout = setTimeout(reset, t) - t += dtReset diff --git a/karax.nim b/karax.nim index 43ed60b..2dc8847 100644 --- a/karax.nim +++ b/karax.nim @@ -109,16 +109,65 @@ proc equals(a, b: VNode): bool = a.class = b.class return true +proc getStringHash(s: string): uint64 = + result = 0 + for c in s: + result = (result * 257 + uint64(c)) mod 1000000007 + +proc calcHash(a : VNode) = + if a.validHash: + return + var result : uint64 = 0 + for i in a: + i.calcHash() + result = result + i.hash + a.validHash = true + a.hash = (getStringHash(getVNodeData(a)) * 71 + result) mod 1000000007 + proc equalsTree(a, b : VNode): bool = - if not equals(a, b): - return false - else: - if len(a) != len(b): - return false - for i in 0..len(a)-1: - if not equalsTree(a[i], b[i]): - return false - return true + if not a.validHash: + a.calcHash() + if not b.validHash: + b.calcHash() + + return a.hash == b.hash + + # if not equals(a, b): + # return false + # else: + # if len(a) != len(b): + # return false + # for i in 0..len(a)-1: + # if not equalsTree(a[i], b[i]): + # return false + # return true + + # kout cstring("a " & $int64(a.hash) & " " & "b " & $int64(b.hash)) + + # if not equals(a, b): + # if a.hash == b.hash: + # kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash)) + # kout cstring($int64(getStringHash(getVNodeData(a))) & " " & $int64(getStringHash(getVNodeData(b)))) + # for c in getVNodeData(a): + # kout cstring($int64(uint64(c))) + # kout "-------" + # for c in getVNodeData(b): + # kout cstring($int64(uint64(c))) + + # return false + # else: + # if len(a) != len(b): + # if a.hash == b.hash: + # kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash)) + # return false + # for i in 0..len(a)-1: + # if not equalsTree(a[i], b[i]): + # if a.hash == b.hash: + # kout cstring("false " & getVNodeData(a) & " " & $int64(a.hash) & " " & getVNodeData(b) & " " & $int64(b.hash)) + # return false + # if a.hash != b.hash: + # kout cstring("true " & getVNodeData(a) & " " & getVNodeData(b)) + # return true proc updateElement(parent, current: Node, newNode, oldNode: VNode) = if not equals(newNode, oldNode): @@ -137,7 +186,7 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode) = kout current.nodeName kout toTag[oldNode.kind] assert false - + var commonPrefix = 0 while commonPrefix < minLength and equalsTree(newNode[commonPrefix], oldNode[commonPrefix]): inc commonPrefix diff --git a/vdom.nim b/vdom.nim index 6d94d97..2e777ac 100644 --- a/vdom.nim +++ b/vdom.nim @@ -38,6 +38,8 @@ type # even index: key, odd index: value; done this way for memory efficiency: attrs: seq[cstring] events*: seq[(EventKind, EventHandler)] + hash*: uint64 + validHash*: bool proc value*(n: VNode): cstring = n.text proc `value=`*(n: VNode; v: cstring) = n.text = v @@ -129,6 +131,24 @@ proc toString*(n: VNode; result: var string; indent: int) = for i in 1..indent: result.add ' ' result.add "\L" +proc getVNodeData*(n: VNode): string = + result.add "<" & $n.kind + toStringAttr(id) + toStringAttr(class) + + #for k, v in attrs(n): + # result.add " " & $k & " = " & $v + + result.add ">" + if n.kind == VNodeKind.text: + result.add n.text + else: + if n.text != nil: + result.add " value = " + result.add n.text + result.add "" + + proc `$`*(n: VNode): cstring = var res = "" toString(n, res, 0)