Scheduler.java revision e2c2daa717063899e30b0cafd4d81e60a36d6b0f
1package com.xtremelabs.robolectric.util; 2 3import java.util.ArrayList; 4import java.util.Collections; 5import java.util.List; 6import java.util.ListIterator; 7 8public class Scheduler { 9 private List<PostedRunnable> postedRunnables = new ArrayList<PostedRunnable>(); 10 private long currentTime = 0; 11 private boolean paused = false; 12 13 14 public void pause() { 15 paused = true; 16 } 17 18 public void unPause() { 19 paused = false; 20 advanceToLastPostedRunnable(); 21 } 22 23 public boolean isPaused() { 24 return paused; 25 } 26 27 public void postDelayed(Runnable runnable, long delayMillis) { 28 if (paused || delayMillis > 0) { 29 postedRunnables.add(new PostedRunnable(runnable, currentTime + delayMillis)); 30 Collections.sort(postedRunnables); 31 } else { 32 runnable.run(); 33 } 34 } 35 36 public void post(Runnable runnable) { 37 postDelayed(runnable, 0); 38 } 39 40 public void remove(Runnable runnable) { 41 ListIterator<PostedRunnable> iterator = postedRunnables.listIterator(); 42 while (iterator.hasNext()) { 43 PostedRunnable next = iterator.next(); 44 if (next.runnable == runnable) { 45 iterator.remove(); 46 } 47 } 48 } 49 50 public boolean advanceToLastPostedRunnable() { 51 if (enqueuedTaskCount() < 1) { 52 return false; 53 } 54 55 return advanceTo(postedRunnables.get(postedRunnables.size() - 1).scheduledTime); 56 } 57 58 public boolean advanceToNextPostedRunnable() { 59 if (enqueuedTaskCount() < 1) { 60 return false; 61 } 62 63 return advanceTo(postedRunnables.get(0).scheduledTime); 64 } 65 66 public boolean advanceBy(long intervalMs) { 67 long endingTime = currentTime + intervalMs; 68 return advanceTo(endingTime); 69 } 70 71 public boolean advanceTo(long endingTime) { 72 if (endingTime - currentTime < 0 || enqueuedTaskCount() < 1) { 73 return false; 74 } 75 76 int runCount = 0; 77 while (nextTaskIsScheduledBefore(endingTime)) { 78 runOneTask(); 79 ++runCount; 80 } 81 currentTime = endingTime; 82 83 return runCount > 0; 84 } 85 86 public boolean runOneTask() { 87 if (enqueuedTaskCount() < 1) { 88 return false; 89 } 90 91 PostedRunnable postedRunnable = postedRunnables.remove(0); 92 currentTime = postedRunnable.scheduledTime; 93 postedRunnable.run(); 94 return true; 95 } 96 97 public boolean runTasks(int howMany) { 98 if (enqueuedTaskCount() < howMany) { 99 return false; 100 } 101 102 while (howMany > 0) { 103 PostedRunnable postedRunnable = postedRunnables.remove(0); 104 currentTime = postedRunnable.scheduledTime; 105 postedRunnable.run(); 106 howMany--; 107 } 108 return true; 109 } 110 111 public int enqueuedTaskCount() { 112 return postedRunnables.size(); 113 } 114 115 public boolean areAnyRunnable() { 116 return nextTaskIsScheduledBefore(currentTime); 117 } 118 119 public void reset() { 120 postedRunnables.clear(); 121 paused = false; 122 } 123 124 class PostedRunnable implements Comparable<PostedRunnable> { 125 Runnable runnable; 126 long scheduledTime; 127 128 PostedRunnable(Runnable runnable, long scheduledTime) { 129 this.runnable = runnable; 130 this.scheduledTime = scheduledTime; 131 } 132 133 @Override 134 public int compareTo(PostedRunnable postedRunnable) { 135 return (int) (scheduledTime - postedRunnable.scheduledTime); 136 } 137 138 public void run() { 139 runnable.run(); 140 } 141 } 142 143 private boolean nextTaskIsScheduledBefore(long endingTime) { 144 return enqueuedTaskCount() > 0 && postedRunnables.get(0).scheduledTime <= endingTime; 145 } 146} 147