ui: add version to OpBlock to track invalidated blocks

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2019-06-02 15:38:00 +02:00
parent a4ccc861ac
commit 9f58ed0fea
2 changed files with 13 additions and 4 deletions
+1 -1
View File
@@ -24,7 +24,7 @@ const (
const ( const (
TypeBlockDefLen = 1 + 4 + 4 TypeBlockDefLen = 1 + 4 + 4
TypeBlockLen = 1 + 4 + 4 TypeBlockLen = 1 + 4 + 4 + 4
TypeTransformLen = 1 + 4*2 TypeTransformLen = 1 + 4*2
TypeLayerLen = 1 TypeLayerLen = 1
TypeRedrawLen = 1 + 8 TypeRedrawLen = 1 + 8
+12 -3
View File
@@ -14,6 +14,7 @@ type Ops struct {
} }
type opsData struct { type opsData struct {
version int
// Serialized ops. // Serialized ops.
data []byte data []byte
// Op references. // Op references.
@@ -76,8 +77,9 @@ type OpPush struct{}
type OpPop struct{} type OpPop struct{}
type OpBlock struct { type OpBlock struct {
ops *Ops ops *Ops
pc pc version int
pc pc
} }
type opBlockDef struct { type opBlockDef struct {
@@ -126,7 +128,7 @@ func (o *Ops) End() OpBlock {
bo := binary.LittleEndian bo := binary.LittleEndian
bo.PutUint32(data[1:], uint32(pc.data)) bo.PutUint32(data[1:], uint32(pc.data))
bo.PutUint32(data[5:], uint32(pc.refs)) bo.PutUint32(data[5:], uint32(pc.refs))
return OpBlock{ops: o, pc: start} return OpBlock{ops: o, pc: start, version: o.ops.version}
} }
// Reset clears the Ops. // Reset clears the Ops.
@@ -138,6 +140,7 @@ func (o *Ops) Reset() {
func (d *opsData) reset() { func (d *opsData) reset() {
d.data = d.data[:0] d.data = d.data[:0]
d.refs = d.refs[:0] d.refs = d.refs[:0]
d.version++
} }
func (d *opsData) write(op []byte, refs []interface{}) { func (d *opsData) write(op []byte, refs []interface{}) {
@@ -160,12 +163,14 @@ func (b *OpBlock) decode(data []byte, refs []interface{}) {
bo := binary.LittleEndian bo := binary.LittleEndian
dataIdx := int(bo.Uint32(data[1:])) dataIdx := int(bo.Uint32(data[1:]))
refsIdx := int(bo.Uint32(data[5:])) refsIdx := int(bo.Uint32(data[5:]))
version := int(bo.Uint32(data[9:]))
*b = OpBlock{ *b = OpBlock{
ops: refs[0].(*Ops), ops: refs[0].(*Ops),
pc: pc{ pc: pc{
data: dataIdx, data: dataIdx,
refs: refsIdx, refs: refsIdx,
}, },
version: version,
} }
} }
@@ -175,6 +180,7 @@ func (b OpBlock) Add(o *Ops) {
bo := binary.LittleEndian bo := binary.LittleEndian
bo.PutUint32(data[1:], uint32(b.pc.data)) bo.PutUint32(data[1:], uint32(b.pc.data))
bo.PutUint32(data[5:], uint32(b.pc.refs)) bo.PutUint32(data[5:], uint32(b.pc.refs))
bo.PutUint32(data[9:], uint32(b.version))
o.Write(data, []interface{}{b.ops}) o.Write(data, []interface{}{b.ops})
} }
@@ -212,6 +218,9 @@ func (r *OpsReader) Decode() ([]byte, []interface{}, bool) {
if ops.OpType(blockOps.data[op.pc.data]) != ops.TypeBlockDef { if ops.OpType(blockOps.data[op.pc.data]) != ops.TypeBlockDef {
panic("invalid block reference") panic("invalid block reference")
} }
if op.version != r.ops.version {
panic("invalid OpBlock reference to reset Ops")
}
var opDef opBlockDef var opDef opBlockDef
opDef.decode(blockOps.data[op.pc.data : op.pc.data+ops.TypeBlockDefLen]) opDef.decode(blockOps.data[op.pc.data : op.pc.data+ops.TypeBlockDefLen])
retPC := r.pc retPC := r.pc