optimized VDOM implementation for uibench

This commit is contained in:
Andreas Rumpf 2017-05-01 09:58:10 +02:00
commit d3e1d28c89

View file

@ -106,8 +106,9 @@ type
# even index: key, odd index: value; done this way for memory efficiency: # even index: key, odd index: value; done this way for memory efficiency:
attrs: seq[cstring] attrs: seq[cstring]
events*: seq[(EventKind, EventHandler)] events*: seq[(EventKind, EventHandler)]
hash*: Hash when false:
validHash*: bool hash*: Hash
validHash*: bool
dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node dom*: Node ## the attached real DOM node. Can be 'nil' if the virtual node
## is not part of the virtual DOM anymore. ## is not part of the virtual DOM anymore.
@ -146,7 +147,11 @@ proc eq*(a, b: VNode): bool =
proc setAttr*(n: VNode; key: cstring; val: cstring = "") = proc setAttr*(n: VNode; key: cstring; val: cstring = "") =
if n.attrs.isNil: if n.attrs.isNil:
n.attrs = @[key, val] when true:
let x = @[key, val]
shallowCopy n.attrs, x
else:
n.attrs = @[key, val]
else: else:
for i in countup(0, n.attrs.len-2, 2): for i in countup(0, n.attrs.len-2, 2):
if n.attrs[i] == key: if n.attrs[i] == key:
@ -216,32 +221,33 @@ proc toString*(n: VNode; result: var string; indent: int) =
for i in 1..indent: result.add ' ' for i in 1..indent: result.add ' '
result.add "\L</" & $n.kind & ">" result.add "\L</" & $n.kind & ">"
proc calcHash*(n: VNode) = when false:
if n.validHash: return proc calcHash*(n: VNode) =
n.validHash = true if n.validHash: return
var h: Hash = ord n.kind n.validHash = true
if n.id != nil: var h: Hash = ord n.kind
h &= "id" if n.id != nil:
h &= n.id h &= "id"
if n.class != nil: h &= n.id
h &= "class" if n.class != nil:
h &= n.class h &= "class"
if n.key >= 0: h &= n.class
h &= "k" if n.key >= 0:
h &= n.key h &= "k"
for k, v in attrs(n): h &= n.key
h &= " " for k, v in attrs(n):
h &= k h &= " "
h &= "=" h &= k
h &= v h &= "="
if n.kind == VNodeKind.text or n.text != nil: h &= v
h &= "t" if n.kind == VNodeKind.text or n.text != nil:
h &= n.text h &= "t"
else: h &= n.text
for child in items(n): else:
calcHash(child) for child in items(n):
h &= child.hash calcHash(child)
n.hash = h h &= child.hash
n.hash = h
proc `$`*(n: VNode): cstring = proc `$`*(n: VNode): cstring =
var res = "" var res = ""