14b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar/* 24b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * Copyright (C) 2014 The Android Open Source Project 34b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * 44b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 54b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * you may not use this file except in compliance with the License. 64b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * You may obtain a copy of the License at 74b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * 84b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 94b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * 104b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * Unless required by applicable law or agreed to in writing, software 114b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 124b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * See the License for the specific language governing permissions and 144b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar * limitations under the License. 154b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar */ 164b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 174b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarpackage android.support.v7.widget; 184b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 194b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport java.util.List; 204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 214b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport android.support.v7.widget.AdapterHelper.UpdateOp; 224b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport static android.support.v7.widget.AdapterHelper.UpdateOp.ADD; 234b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport static android.support.v7.widget.AdapterHelper.UpdateOp.MOVE; 244b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport static android.support.v7.widget.AdapterHelper.UpdateOp.REMOVE; 254b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarimport static android.support.v7.widget.AdapterHelper.UpdateOp.UPDATE; 264b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 274b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyarclass OpReorderer { 284b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 294b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final Callback mCallback; 304b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 314b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar public OpReorderer(Callback callback) { 324b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar mCallback = callback; 334b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 344b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 354b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar void reorderOps(List<UpdateOp> ops) { 364b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // since move operations breaks continuity, their effects on ADD/RM are hard to handle. 374b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // we push them to the end of the list so that they can be handled easily. 384b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar int badMove; 394b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar while ((badMove = getLastMoveOutOfOrder(ops)) != -1) { 404b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar swapMoveOp(ops, badMove, badMove + 1); 414b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 424b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 434b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 444b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar private void swapMoveOp(List<UpdateOp> list, int badMove, int next) { 454b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final UpdateOp moveOp = list.get(badMove); 464b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final UpdateOp nextOp = list.get(next); 474b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar switch (nextOp.cmd) { 484b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar case REMOVE: 494b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar swapMoveRemove(list, badMove, moveOp, next, nextOp); 504b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar break; 514b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar case ADD: 524b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar swapMoveAdd(list, badMove, moveOp, next, nextOp); 534b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar break; 544b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar case UPDATE: 554b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar swapMoveUpdate(list, badMove, moveOp, next, nextOp); 564b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar break; 574b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 584b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 594b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 604b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar void swapMoveRemove(List<UpdateOp> list, int movePos, UpdateOp moveOp, 614b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar int removePos, UpdateOp removeOp) { 624b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar UpdateOp extraRm = null; 634b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // check if move is nulled out by remove 644b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar boolean revertedMove = false; 654b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final boolean moveIsBackwards; 664b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 674b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart < moveOp.itemCount) { 684b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveIsBackwards = false; 694b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (removeOp.positionStart == moveOp.positionStart 704b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar && removeOp.itemCount == moveOp.itemCount - moveOp.positionStart) { 714b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar revertedMove = true; 724b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 734b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else { 744b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveIsBackwards = true; 754b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (removeOp.positionStart == moveOp.itemCount + 1 && 764b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar removeOp.itemCount == moveOp.positionStart - moveOp.itemCount) { 774b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar revertedMove = true; 784b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 794b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 804b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 814b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // going in reverse, first revert the effect of add 824b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount < removeOp.positionStart) { 834b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar removeOp.positionStart--; 844b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else if (moveOp.itemCount < removeOp.positionStart + removeOp.itemCount) { 854b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // move is removed. 864b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar removeOp.itemCount --; 874b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.cmd = REMOVE; 884b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount = 1; 894b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (removeOp.itemCount == 0) { 904b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.remove(removePos); 914b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar mCallback.recycleUpdateOp(removeOp); 924b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 934b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // no need to swap, it is already a remove 944b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar return; 954b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 964b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 974b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // now affect of add is consumed. now apply effect of first remove 984b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart <= removeOp.positionStart) { 994b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar removeOp.positionStart++; 1004b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else if (moveOp.positionStart < removeOp.positionStart + removeOp.itemCount) { 1014b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final int remaining = removeOp.positionStart + removeOp.itemCount 1024b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar - moveOp.positionStart; 10321b345f101abc385496f42d250e580d21f1287b6Dake Gu extraRm = mCallback.obtainUpdateOp(REMOVE, moveOp.positionStart + 1, remaining, null); 1044b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar removeOp.itemCount = moveOp.positionStart - removeOp.positionStart; 1054b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1064b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 1074b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // if effects of move is reverted by remove, we are done. 1084b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (revertedMove) { 1094b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(movePos, removeOp); 1104b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.remove(removePos); 1114b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar mCallback.recycleUpdateOp(moveOp); 1124b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar return; 1134b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1144b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 1154b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // now find out the new locations for move actions 1164b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveIsBackwards) { 1174b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (extraRm != null) { 1184b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart > extraRm.positionStart) { 1194b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.positionStart -= extraRm.itemCount; 1204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1214b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount > extraRm.positionStart) { 1224b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount -= extraRm.itemCount; 1234b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1244b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1254b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart > removeOp.positionStart) { 1264b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.positionStart -= removeOp.itemCount; 1274b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1284b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount > removeOp.positionStart) { 1294b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount -= removeOp.itemCount; 1304b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1314b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else { 1324b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (extraRm != null) { 1334b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart >= extraRm.positionStart) { 1344b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.positionStart -= extraRm.itemCount; 1354b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1364b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount >= extraRm.positionStart) { 1374b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount -= extraRm.itemCount; 1384b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1394b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1404b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart >= removeOp.positionStart) { 1414b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.positionStart -= removeOp.itemCount; 1424b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1434b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount >= removeOp.positionStart) { 1444b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount -= removeOp.itemCount; 1454b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1464b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1474b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 1484b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(movePos, removeOp); 1494b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart != moveOp.itemCount) { 1504b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(removePos, moveOp); 1514b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else { 1524b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.remove(removePos); 1534b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1544b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (extraRm != null) { 1554b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.add(movePos, extraRm); 1564b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1574b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1584b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 1594b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar private void swapMoveAdd(List<UpdateOp> list, int move, UpdateOp moveOp, int add, 1604b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar UpdateOp addOp) { 1614b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar int offset = 0; 1624b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // going in reverse, first revert the effect of add 1634b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount < addOp.positionStart) { 1644b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar offset--; 1654b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1664b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart < addOp.positionStart) { 1674b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar offset++; 1684b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1694b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (addOp.positionStart <= moveOp.positionStart) { 1704b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.positionStart += addOp.itemCount; 1714b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1724b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (addOp.positionStart <= moveOp.itemCount) { 1734b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar moveOp.itemCount += addOp.itemCount; 1744b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1754b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar addOp.positionStart += offset; 1764b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(move, addOp); 1774b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(add, moveOp); 1784b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1794b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 1804b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar void swapMoveUpdate(List<UpdateOp> list, int move, UpdateOp moveOp, int update, 1814b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar UpdateOp updateOp) { 1824b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar UpdateOp extraUp1 = null; 1834b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar UpdateOp extraUp2 = null; 1844b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // going in reverse, first revert the effect of add 1854b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.itemCount < updateOp.positionStart) { 1864b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar updateOp.positionStart--; 1874b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else if (moveOp.itemCount < updateOp.positionStart + updateOp.itemCount) { 1884b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // moved item is updated. add an update for it 1894b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar updateOp.itemCount--; 19021b345f101abc385496f42d250e580d21f1287b6Dake Gu extraUp1 = mCallback.obtainUpdateOp(UPDATE, moveOp.positionStart, 1, updateOp.payload); 1914b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 1924b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar // now affect of add is consumed. now apply effect of first remove 1934b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (moveOp.positionStart <= updateOp.positionStart) { 1944b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar updateOp.positionStart++; 1954b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else if (moveOp.positionStart < updateOp.positionStart + updateOp.itemCount) { 1964b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final int remaining = updateOp.positionStart + updateOp.itemCount 1974b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar - moveOp.positionStart; 19821b345f101abc385496f42d250e580d21f1287b6Dake Gu extraUp2 = mCallback.obtainUpdateOp(UPDATE, moveOp.positionStart + 1, remaining, 19921b345f101abc385496f42d250e580d21f1287b6Dake Gu updateOp.payload); 2004b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar updateOp.itemCount -= remaining; 2014b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2024b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(update, moveOp); 2034b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (updateOp.itemCount > 0) { 2044b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.set(move, updateOp); 2054b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else { 2064b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.remove(move); 2074b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar mCallback.recycleUpdateOp(updateOp); 2084b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2094b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (extraUp1 != null) { 2104b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.add(move, extraUp1); 2114b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2124b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (extraUp2 != null) { 2134b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar list.add(move, extraUp2); 2144b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2154b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2164b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 2174b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar private int getLastMoveOutOfOrder(List<UpdateOp> list) { 2184b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar boolean foundNonMove = false; 2194b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar for (int i = list.size() - 1; i >= 0; i--) { 2204b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar final UpdateOp op1 = list.get(i); 2214b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (op1.cmd == MOVE) { 2224b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar if (foundNonMove) { 2234b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar return i; 2244b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2254b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } else { 2264b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar foundNonMove = true; 2274b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2284b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2294b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar return -1; 2304b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2314b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 2324b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar static interface Callback { 2334b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 23421b345f101abc385496f42d250e580d21f1287b6Dake Gu UpdateOp obtainUpdateOp(int cmd, int startPosition, int itemCount, Object payload); 2354b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar 2364b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar void recycleUpdateOp(UpdateOp op); 2374b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar } 2384b9b4d3fca81486051bac9aadb73d8865948c3bfYigit Boyar} 239