Notify observers when display buffer markers are invalidated

This commit is contained in:
Kevin Sawicki & Nathan Sobo
2013-02-26 14:57:00 -08:00
parent e36887900f
commit 42fe87a9a2
2 changed files with 61 additions and 13 deletions

View File

@@ -661,6 +661,7 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [5, 4]
newTailBufferPosition: [8, 4]
bufferChanged: false
valid: true
}
observeHandler.reset()
@@ -676,6 +677,7 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [5, 4]
newTailBufferPosition: [8, 4]
bufferChanged: true
valid: true
}
observeHandler.reset()
@@ -691,6 +693,7 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [8, 4]
newTailBufferPosition: [8, 4]
bufferChanged: false
valid: true
}
observeHandler.reset()
@@ -706,6 +709,7 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [5, 4]
newTailBufferPosition: [8, 4]
bufferChanged: false
valid: true
}
it "calls the callback whenever the marker tail's position changes in the buffer or on screen", ->
@@ -721,6 +725,7 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [8, 20]
newTailBufferPosition: [11, 20]
bufferChanged: false
valid: true
}
observeHandler.reset()
@@ -736,6 +741,40 @@ describe "DisplayBuffer", ->
newTailScreenPosition: [8, 23]
newTailBufferPosition: [11, 23]
bufferChanged: true
valid: true
}
it "calls the callback whenever the marker is invalidated or revalidated", ->
buffer.deleteRow(8)
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [5, 10]
oldHeadBufferPosition: [8, 10]
newHeadScreenPosition: [5, 10]
newHeadBufferPosition: [8, 10]
oldTailScreenPosition: [5, 4]
oldTailBufferPosition: [8, 4]
newTailScreenPosition: [5, 4]
newTailBufferPosition: [8, 4]
bufferChanged: true
valid: false
}
observeHandler.reset()
buffer.undo()
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [5, 10]
oldHeadBufferPosition: [8, 10]
newHeadScreenPosition: [5, 10]
newHeadBufferPosition: [8, 10]
oldTailScreenPosition: [5, 4]
oldTailBufferPosition: [8, 4]
newTailScreenPosition: [5, 4]
newTailBufferPosition: [8, 4]
bufferChanged: true
valid: true
}
it "does not call the callback for screen changes that don't change the position of the marker", ->

View File

@@ -7,6 +7,7 @@ class DisplayBufferMarker
bufferMarkerSubscription: null
headScreenPosition: null
tailScreenPosition: null
valid: true
constructor: ({@id, @displayBuffer}) ->
@buffer = @displayBuffer.buffer
@@ -57,11 +58,11 @@ class DisplayBufferMarker
observe: (callback) ->
@observeBufferMarkerIfNeeded()
@on 'position-changed', callback
@on 'changed', callback
cancel: => @unobserve(callback)
unobserve: (callback) ->
@off 'position-changed', callback
@off 'changed', callback
@unobserveBufferMarkerIfNeeded()
observeBufferMarkerIfNeeded: ->
@@ -69,13 +70,14 @@ class DisplayBufferMarker
@getHeadScreenPosition() # memoize current value
@getTailScreenPosition() # memoize current value
@bufferMarkerSubscription =
@buffer.observeMarker @id, ({oldHeadPosition, newHeadPosition, oldTailPosition, newTailPosition, bufferChanged}) =>
@buffer.observeMarker @id, ({oldHeadPosition, newHeadPosition, oldTailPosition, newTailPosition, bufferChanged, valid}) =>
@notifyObservers
oldHeadBufferPosition: oldHeadPosition
newHeadBufferPosition: newHeadPosition
oldTailBufferPosition: oldTailPosition
newTailBufferPosition: newTailPosition
bufferChanged: bufferChanged
valid: valid
@displayBuffer.markers[@id] = this
unobserveBufferMarkerIfNeeded: ->
@@ -83,28 +85,35 @@ class DisplayBufferMarker
@bufferMarkerSubscription.cancel()
delete @displayBuffer.markers[@id]
notifyObservers: ({oldHeadBufferPosition, oldTailBufferPosition, bufferChanged}) ->
notifyObservers: ({oldHeadBufferPosition, oldTailBufferPosition, bufferChanged, valid} = {}) ->
oldHeadScreenPosition = @getHeadScreenPosition()
@headScreenPosition = null
newHeadScreenPosition = @getHeadScreenPosition()
oldTailScreenPosition = @getTailScreenPosition()
@tailScreenPosition = null
newTailScreenPosition = @getTailScreenPosition()
valid ?= true
return if _.isEqual(newHeadScreenPosition, oldHeadScreenPosition) and _.isEqual(newTailScreenPosition, oldTailScreenPosition)
if valid
@headScreenPosition = null
newHeadScreenPosition = @getHeadScreenPosition()
@tailScreenPosition = null
newTailScreenPosition = @getTailScreenPosition()
else
newHeadScreenPosition = oldHeadScreenPosition
newTailScreenPosition = oldTailScreenPosition
return if valid is @valid and _.isEqual(newHeadScreenPosition, oldHeadScreenPosition) and _.isEqual(newTailScreenPosition, oldTailScreenPosition)
oldHeadBufferPosition ?= @getHeadBufferPosition()
newHeadBufferPosition = @getHeadBufferPosition()
newHeadBufferPosition = @getHeadBufferPosition() ? oldHeadBufferPosition
oldTailBufferPosition ?= @getTailBufferPosition()
newTailBufferPosition = @getTailBufferPosition()
newTailBufferPosition = @getTailBufferPosition() ? oldTailBufferPosition
@valid = valid
@trigger 'position-changed', {
@trigger 'changed', {
oldHeadScreenPosition, newHeadScreenPosition,
oldTailScreenPosition, newTailScreenPosition,
oldHeadBufferPosition, newHeadBufferPosition,
oldTailBufferPosition, newTailBufferPosition,
bufferChanged
valid
}
_.extend DisplayBufferMarker.prototype, EventEmitter