Skip to content

Commit

Permalink
Revert "Implement Blockly.Events.filter in linear time (#1205)"
Browse files Browse the repository at this point in the history
This reverts commit 9102848.
  • Loading branch information
paulkaplan committed Oct 20, 2017
1 parent b4b721d commit 8263afc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 161 deletions.
64 changes: 36 additions & 28 deletions core/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,37 +174,45 @@ Blockly.Events.filter = function(queueIn, forward) {
// Undo is merged in reverse order.
queue.reverse();
}
var mergedQueue = [];
var hash = Object.create(null);
// Merge duplicates.
for (var i = 0, event; event = queue[i]; i++) {
if (!event.isNull()) {
var key = [event.type, event.blockId, event.workspaceId].join(' ');
var lastEvent = hash[key];
if (!lastEvent) {
hash[key] = event;
mergedQueue.push(event);
} else if (event.type == Blockly.Events.MOVE) {
// Merge move events.
lastEvent.newParentId = event.newParentId;
lastEvent.newInputName = event.newInputName;
lastEvent.newCoordinate = event.newCoordinate;
} else if (event.type == Blockly.Events.CHANGE &&
event.element == lastEvent.element &&
event.name == lastEvent.name) {
// Merge change events.
lastEvent.newValue = event.newValue;
} else if (event.type == Blockly.Events.UI &&
event.element == 'click' &&
(lastEvent.element == 'commentOpen' ||
lastEvent.element == 'mutatorOpen' ||
lastEvent.element == 'warningOpen')) {
// Merge click events.
lastEvent.newValue = event.newValue;
// Merge duplicates. O(n^2), but n should be very small.
for (var i = 0, event1; event1 = queue[i]; i++) {
for (var j = i + 1, event2; event2 = queue[j]; j++) {
if (event1.type == event2.type &&
event1.blockId == event2.blockId &&
event1.workspaceId == event2.workspaceId) {
if (event1.type == Blockly.Events.MOVE) {
// Merge move events.
event1.newParentId = event2.newParentId;
event1.newInputName = event2.newInputName;
event1.newCoordinate = event2.newCoordinate;
queue.splice(j, 1);
j--;
} else if (event1.type == Blockly.Events.CHANGE &&
event1.element == event2.element &&
event1.name == event2.name) {
// Merge change events.
event1.newValue = event2.newValue;
queue.splice(j, 1);
j--;
} else if (event1.type == Blockly.Events.UI &&
event2.element == 'click' &&
(event1.element == 'commentOpen' ||
event1.element == 'mutatorOpen' ||
event1.element == 'warningOpen')) {
// Merge change events.
event1.newValue = event2.newValue;
queue.splice(j, 1);
j--;
}
}
}
}
queue = mergedQueue;
// Remove null events.
for (var i = queue.length - 1; i >= 0; i--) {
if (queue[i].isNull()) {
queue.splice(i, 1);
}
}
if (!forward) {
// Restore undo order.
queue.reverse();
Expand Down
133 changes: 0 additions & 133 deletions tests/jsunit/event_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -392,136 +392,3 @@ function test_varBackard_runForward() {
checkVariableValues(workspace, 'name1', 'type1', 'id1');
eventTest_tearDown();
}

function test_events_filter() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var events = [
new Blockly.Events.BlockCreate(block1),
new Blockly.Events.BlockMove(block1),
new Blockly.Events.BlockChange(block1, 'field', 'VAR', 'item', 'item1'),
new Blockly.Events.Ui(block1, 'click')
];
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(4, filteredEvents.length); // no event should have been removed.
// test that the order hasn't changed
assertTrue(filteredEvents[0] instanceof Blockly.Events.BlockCreate);
assertTrue(filteredEvents[1] instanceof Blockly.Events.BlockMove);
assertTrue(filteredEvents[2] instanceof Blockly.Events.BlockChange);
assertTrue(filteredEvents[3] instanceof Blockly.Events.Ui);
}

function test_events_filterForward() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var events = [
new Blockly.Events.BlockCreate(block1),
];
helper_addMoveEvent(events, block1, 1, 1);
helper_addMoveEvent(events, block1, 2, 2);
helper_addMoveEvent(events, block1, 3, 3);
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(2, filteredEvents.length); // duplicate moves should have been removed.
// test that the order hasn't changed
assertTrue(filteredEvents[0] instanceof Blockly.Events.BlockCreate);
assertTrue(filteredEvents[1] instanceof Blockly.Events.BlockMove);
assertEquals(3, filteredEvents[1].newCoordinate.x);
assertEquals(3, filteredEvents[1].newCoordinate.y);
eventTest_tearDownWithMockBlocks();
}

function test_events_filterBackward() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var events = [
new Blockly.Events.BlockCreate(block1),
];
helper_addMoveEvent(events, block1, 1, 1);
helper_addMoveEvent(events, block1, 2, 2);
helper_addMoveEvent(events, block1, 3, 3);
var filteredEvents = Blockly.Events.filter(events, false);
assertEquals(2, filteredEvents.length); // duplicate event should have been removed.
// test that the order hasn't changed
assertTrue(filteredEvents[0] instanceof Blockly.Events.BlockCreate);
assertTrue(filteredEvents[1] instanceof Blockly.Events.BlockMove);
assertEquals(1, filteredEvents[1].newCoordinate.x);
assertEquals(1, filteredEvents[1].newCoordinate.y);
eventTest_tearDownWithMockBlocks();
}

function test_events_filterDifferentBlocks() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var block2 = workspace.newBlock('field_variable_test_block', '2');
var events = [
new Blockly.Events.BlockCreate(block1),
new Blockly.Events.BlockMove(block1),
new Blockly.Events.BlockCreate(block2),
new Blockly.Events.BlockMove(block2)
];
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(4, filteredEvents.length); // no event should have been removed.
eventTest_tearDownWithMockBlocks();
}

function test_events_mergeMove() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var events = [];
helper_addMoveEvent(events, block1, 0, 0);
helper_addMoveEvent(events, block1, 1, 1);
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(1, filteredEvents.length); // second move event merged into first
assertEquals(1, filteredEvents[0].newCoordinate.x);
assertEquals(1, filteredEvents[0].newCoordinate.y);
eventTest_tearDownWithMockBlocks();
}

function test_events_mergeChange() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var events = [
new Blockly.Events.Change(block1, 'field', 'VAR', 'item', 'item1'),
new Blockly.Events.Change(block1, 'field', 'VAR', 'item1', 'item2')
];
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(1, filteredEvents.length); // second change event merged into first
assertEquals('item', filteredEvents[0].oldValue);
assertEquals('item2', filteredEvents[0].newValue);
eventTest_tearDownWithMockBlocks();
}

function test_events_mergeUi() {
eventTest_setUpWithMockBlocks();
var block1 = workspace.newBlock('field_variable_test_block', '1');
var block2 = workspace.newBlock('field_variable_test_block', '2');
var block3 = workspace.newBlock('field_variable_test_block', '3');
var events = [
new Blockly.Events.Ui(block1, 'commentOpen', 'false', 'true'),
new Blockly.Events.Ui(block1, 'click', 'false', 'true'),
new Blockly.Events.Ui(block2, 'mutatorOpen', 'false', 'true'),
new Blockly.Events.Ui(block2, 'click', 'false', 'true'),
new Blockly.Events.Ui(block3, 'warningOpen', 'false', 'true'),
new Blockly.Events.Ui(block3, 'click', 'false', 'true')
];
var filteredEvents = Blockly.Events.filter(events, true);
assertEquals(3, filteredEvents.length); // click event merged into corresponding *Open event
assertEquals('commentOpen', filteredEvents[0].element);
assertEquals('mutatorOpen', filteredEvents[1].element);
assertEquals('warningOpen', filteredEvents[2].element);
eventTest_tearDownWithMockBlocks();
}

/**
* Helper function to simulate block move events.
*
* @param {!Array.<Blockly.Events.Abstract>} events a queue of events.
* @param {!Blockly.Block} block the block to be moved
* @param {number} newX new X coordinate of the block
* @param {number} newY new Y coordinate of the block
*/
function helper_addMoveEvent(events, block, newX, newY) {
events.push(new Blockly.Events.BlockMove(block));
block.xy_ = new goog.math.Coordinate(newX, newY);
events[events.length-1].recordNew();
}

0 comments on commit 8263afc

Please # to comment.