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