1a2043a8fff01f3e2d9a5e30dd1cf5fb6a5342f4dTyler Schultzpackage com.xtremelabs.robolectric.util; 2f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 3f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillipsimport java.util.ArrayList; 4f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillipsimport java.util.Collections; 5f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillipsimport java.util.List; 6e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwireimport java.util.ListIterator; 7f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 8f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillipspublic class Scheduler { 9f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips private List<PostedRunnable> postedRunnables = new ArrayList<PostedRunnable>(); 10f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips private long currentTime = 0; 11b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz private boolean paused = false; 12b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz 13ac0c93f1c8ad77266671707889f56bea3770cd6fPhil Plante & Ryan Richard public long getCurrentTime() { 14ac0c93f1c8ad77266671707889f56bea3770cd6fPhil Plante & Ryan Richard return currentTime; 15ac0c93f1c8ad77266671707889f56bea3770cd6fPhil Plante & Ryan Richard } 16b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz 17b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz public void pause() { 18b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz paused = true; 19b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz } 20b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz 21b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz public void unPause() { 22b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz paused = false; 23b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz advanceToLastPostedRunnable(); 24b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz } 25f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 26a4f7d50f8e6f12d541421383544fe16c185e4bbcPhil Goodwin & Tyler Schultz public boolean isPaused() { 27a4f7d50f8e6f12d541421383544fe16c185e4bbcPhil Goodwin & Tyler Schultz return paused; 28a4f7d50f8e6f12d541421383544fe16c185e4bbcPhil Goodwin & Tyler Schultz } 29a4f7d50f8e6f12d541421383544fe16c185e4bbcPhil Goodwin & Tyler Schultz 30f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips public void postDelayed(Runnable runnable, long delayMillis) { 31b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz if (paused || delayMillis > 0) { 32b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz postedRunnables.add(new PostedRunnable(runnable, currentTime + delayMillis)); 33b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz Collections.sort(postedRunnables); 34b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz } else { 35b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz runnable.run(); 36b54505e42361f87b8ba24a785ae257f7d15feb2fPhil Goodwin & Tyler Schultz } 37f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 38f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 39f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips public void post(Runnable runnable) { 40f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz postDelayed(runnable, 0); 41f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 42f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 43478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky public void postAtFrontOfQueue(Runnable runnable) { 44478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky if (paused) { 45478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky postedRunnables.add(0, new PostedRunnable(runnable, currentTime)); 46478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky } else { 47478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky runnable.run(); 48478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky } 49478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky } 50478a40ed43134ef1568a19ab5233a5736a21c57bGlenn Jahnke & Lenny Turetsky 51e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire public void remove(Runnable runnable) { 52e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire ListIterator<PostedRunnable> iterator = postedRunnables.listIterator(); 53e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire while (iterator.hasNext()) { 54e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire PostedRunnable next = iterator.next(); 55e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire if (next.runnable == runnable) { 56e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire iterator.remove(); 57e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire } 58e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire } 59e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire } 60e2c2daa717063899e30b0cafd4d81e60a36d6b0fpivotal-jiwire 61f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz public boolean advanceToLastPostedRunnable() { 62f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz if (enqueuedTaskCount() < 1) { 63f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return false; 64f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 659c19f7ef7122cfa9e03ed4314da4ad2a115c7e71Christian Williams & Ryan Richard 66f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return advanceTo(postedRunnables.get(postedRunnables.size() - 1).scheduledTime); 67f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 68f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz 69f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz public boolean advanceToNextPostedRunnable() { 70f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz if (enqueuedTaskCount() < 1) { 71f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return false; 72f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 73f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz 74f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return advanceTo(postedRunnables.get(0).scheduledTime); 75f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 76f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 77f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz public boolean advanceBy(long intervalMs) { 78f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips long endingTime = currentTime + intervalMs; 79f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return advanceTo(endingTime); 80f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 81f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 82f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz public boolean advanceTo(long endingTime) { 83f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz if (endingTime - currentTime < 0 || enqueuedTaskCount() < 1) { 84f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return false; 85f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 86f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 87f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz int runCount = 0; 88f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz while (nextTaskIsScheduledBefore(endingTime)) { 89f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz runOneTask(); 90f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz ++runCount; 91f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 92f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz currentTime = endingTime; 93f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 94f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return runCount > 0; 95f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 969c19f7ef7122cfa9e03ed4314da4ad2a115c7e71Christian Williams & Ryan Richard 97f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz public boolean runOneTask() { 98f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz if (enqueuedTaskCount() < 1) { 99f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return false; 100f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 101f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz 102f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz PostedRunnable postedRunnable = postedRunnables.remove(0); 103f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz currentTime = postedRunnable.scheduledTime; 104f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz postedRunnable.run(); 105f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return true; 106f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 107f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 108ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard public boolean runTasks(int howMany) { 109ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard if (enqueuedTaskCount() < howMany) { 110ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard return false; 111ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard } 112ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard 113ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard while (howMany > 0) { 114ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard PostedRunnable postedRunnable = postedRunnables.remove(0); 115ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard currentTime = postedRunnable.scheduledTime; 116ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard postedRunnable.run(); 117ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard howMany--; 118ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard } 119ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard return true; 120ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard } 121ac15c9cd601029fa6af0045cec61a748d55f54c9Lowell Kirsh & Ryan Richard 122f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips public int enqueuedTaskCount() { 123f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips return postedRunnables.size(); 124f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 125f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 126006d40b0d212332682a30c80eb733a006455a4e7Phil Goodwin & Tyler Schultz public boolean areAnyRunnable() { 127006d40b0d212332682a30c80eb733a006455a4e7Phil Goodwin & Tyler Schultz return nextTaskIsScheduledBefore(currentTime); 128006d40b0d212332682a30c80eb733a006455a4e7Phil Goodwin & Tyler Schultz } 129006d40b0d212332682a30c80eb733a006455a4e7Phil Goodwin & Tyler Schultz 130abde7367c1c6a322c18803941e9118b1daea35fbChristian Williams public void reset() { 131abde7367c1c6a322c18803941e9118b1daea35fbChristian Williams postedRunnables.clear(); 132a4f7d50f8e6f12d541421383544fe16c185e4bbcPhil Goodwin & Tyler Schultz paused = false; 133abde7367c1c6a322c18803941e9118b1daea35fbChristian Williams } 134abde7367c1c6a322c18803941e9118b1daea35fbChristian Williams 135183675aba2229b620cc04156d5dbc5d95703b09eGlenn Jahnke & Phil Plante public int size() { 136183675aba2229b620cc04156d5dbc5d95703b09eGlenn Jahnke & Phil Plante return postedRunnables.size(); 137183675aba2229b620cc04156d5dbc5d95703b09eGlenn Jahnke & Phil Plante } 138183675aba2229b620cc04156d5dbc5d95703b09eGlenn Jahnke & Phil Plante 139f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips class PostedRunnable implements Comparable<PostedRunnable> { 140f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips Runnable runnable; 141f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips long scheduledTime; 142f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 143f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips PostedRunnable(Runnable runnable, long scheduledTime) { 144f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips this.runnable = runnable; 145f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips this.scheduledTime = scheduledTime; 146f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 147f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 148f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips @Override 149f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips public int compareTo(PostedRunnable postedRunnable) { 150f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips return (int) (scheduledTime - postedRunnable.scheduledTime); 151f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 152f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips 153f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips public void run() { 154f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips runnable.run(); 155f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 156f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips } 157f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz 158f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz private boolean nextTaskIsScheduledBefore(long endingTime) { 159f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz return enqueuedTaskCount() > 0 && postedRunnables.get(0).scheduledTime <= endingTime; 160f7c3a47b5eb49f49f450eb18822d51dc496fceefPhil Goodwin & Tyler Schultz } 161f8d3ea0e4553f6f391543eccb99485f9603c5804Christian Williams & Jay Phillips} 162