1 /* 2 * AbstractTimer.java 3 * 4 * Created on 28 de Março de 2007, 17:02 5 * 6 * To change this template, choose Tools | Template Manager 7 * and open the template in the editor. 8 */ 9 10 package tempcontroller.base; 11 12 import java.util.HashSet; 13 import java.util.Iterator; 14 import java.util.Set; 15 16 /** 17 * Implementação auxiliar de um Timer. Controla o tempo decorrido. 18 */ 19 public abstract class AbstractTimer implements ITimer { 20 /** 21 * Tempo decorrido antes do último pause ou stop. 22 */ 23 private long tempoDecorridoAntigo; 24 25 /** 26 * Início do último 'start' ou 'continue'. 27 */ 28 private long inicio; 29 30 /** 31 * Quantidade de tempo que o Timer tem 32 * que contar até encerrar sua contagem. 33 */ 34 private long tempoTotal; 35 36 /** 37 * Quantidade de tempo entre cada evento de Tick. 38 */ 39 private long tick; 40 41 /** 42 * Conjunto de ouvintes do timer. 43 */ 44 private Set<IOuvinteTimer> ouvintes = null; 45 46 /** 47 * Estado inicial do Timer. 48 */ 49 private ITimer.Estado estado = ITimer.Estado.NAO_INICIADO; 50 51 /** 52 * Define o tempo total deste timer. Tempo total é a quantidade 53 * de tempo que o timer deve esperar até enviar um único evento 54 * de tempo total terminado. 55 * @param tempoTotalLocal Tempo total do timer. 56 */ 57 public void setTempoTotal(final long tempoTotalLocal) { 58 tempoTotal = tempoTotalLocal; 59 setTempoTotalImpl(tempoTotalLocal); 60 } 61 62 /** 63 * Obtém o tempo total deste timer. Tempo total é a quantidade 64 * de tempo que o timer deve esperar até enviar um único evento 65 * de tempo total terminado. 66 * @return O tempo total deste timer. 67 */ 68 public long getTempoTotal() { 69 return tempoTotal; 70 } 71 72 /** 73 * Define o tick do timer. Tick é o tempo que o timer 74 * deve esperar para enviar eventos de 'tick' periodicamente. 75 * @param tempo Quantidade de tempo do tick. 76 */ 77 public void setTick(final long tempo) { 78 tick = tempo; 79 setTickImpl(tempo); 80 } 81 82 /** 83 * Obtém o tick do timer. Tick é o tempo que o timer 84 * deve esperar para enviar eventos de 'tick' periodicamente. 85 * @return Quantidade de tempo do tick. 86 */ 87 public long getTick() { 88 return tick; 89 } 90 91 /** 92 * Adiciona um ouvinte do Timer. Este receberá os eventos 93 * de tick e de tempo total. 94 * @param ouvinte Ouvinte dos eventos deste timer. 95 */ 96 public void addOuvinteTimer(final IOuvinteTimer ouvinte) { 97 if (ouvintes == null) { 98 ouvintes = new HashSet<IOuvinteTimer>(); 99 } 100 if (!ouvintes.contains(ouvinte)) { 101 ouvintes.add(ouvinte); 102 } 103 } 104 105 /** 106 * Remove um ouvinte do conjunto de ouvintes deste timer. 107 * @param ouvinte Ouvinte que não quer mais receber 108 * eventos deste timer. 109 */ 110 public void removeOuvinteTimer(final IOuvinteTimer ouvinte) { 111 if (ouvintes != null) { 112 ouvintes.remove(ouvinte); 113 } 114 } 115 116 /** 117 * Notifica todos os ouvintes que o tempo total foi 118 * alcançado. 119 */ 120 protected void fireTempoTotalTerminado() { 121 Iterator<IOuvinteTimer> it = ouvintes.iterator(); 122 while (it.hasNext()) { 123 IOuvinteTimer ouvinte = it.next(); 124 ouvinte.tempoTotalTerminado(); 125 } 126 } 127 128 /** 129 * Notifica todos os ouvintes com um evento de tick. 130 */ 131 protected void fireTickDoTimer() { 132 Iterator<IOuvinteTimer> it = ouvintes.iterator(); 133 while (it.hasNext()) { 134 IOuvinteTimer ouvinte = it.next(); 135 ouvinte.tickDoTimer(); 136 } 137 } 138 139 /** 140 * Inicia a contagem do tempo. 141 */ 142 public void start() { 143 tempoDecorridoAntigo = 0; 144 privContinua(); 145 startImpl(); 146 } 147 148 /** 149 * Termina a contagem do tempo. 150 */ 151 public void stop() { 152 atualizaTempoDecorridoAntigo(); 153 estado = ITimer.Estado.NAO_INICIADO; 154 stopImpl(); 155 } 156 157 /** 158 * Pausa a contagem do tempo. 159 */ 160 public void pause() { 161 atualizaTempoDecorridoAntigo(); 162 estado = ITimer.Estado.PAUSADO; 163 pauseImpl(); 164 } 165 166 /** 167 * Atualiza o tempo de corrido antigo. Deve ser chamado a cada 168 * stop ou pause. 169 */ 170 private void atualizaTempoDecorridoAntigo() { 171 tempoDecorridoAntigo = tempoDecorridoAntigo 172 + (getCurrentTime() - inicio); 173 } 174 175 /** 176 * Retoma a contagem do tempo, depois de um pause. 177 */ 178 public void continua() { 179 privContinua(); 180 continuaImpl(); 181 } 182 183 /** 184 * Inicia a contagem do tempo. Deve ser 185 * chamada a cada continue ou start. 186 */ 187 private void privContinua() { 188 inicio = getCurrentTime(); 189 estado = ITimer.Estado.CRONOMETRANDO; 190 } 191 192 /** 193 * Obtém o tempo decorrido total. Ignora 194 * os períodos que o timer estava pausado. 195 * @return O tempo decorrido. 196 */ 197 public long getTempoDecorrido() { 198 long toReturn = 0; 199 if (estado.equals(ITimer.Estado.CRONOMETRANDO)) { 200 toReturn = (getCurrentTime() - inicio) + tempoDecorridoAntigo; 201 } else { 202 toReturn = tempoDecorridoAntigo; 203 } 204 return toReturn; 205 } 206 207 /** 208 * Obtém o estado atual do timer. 209 * @return O estado atual do timer. 210 */ 211 public ITimer.Estado getEstado() { 212 return estado; 213 } 214 215 /** 216 * Não faz nada. Chamado pelo método 217 * 'setTempoTotal' desta classe. 218 * Subclasses podem sobrepor este método 219 * para um controle próprio. 220 * @param tempoTotalLocal Tempo Total do timer. 221 */ 222 protected void setTempoTotalImpl(final long tempoTotalLocal) { 223 // Por default não faz nada. 224 } 225 226 /** 227 * Não faz nada. Chamdo pelo método 228 * 'start' desta classe. 229 * Subclasses podem sobrepor este método 230 * para um controle próprio. 231 */ 232 protected void startImpl() { 233 // Não faz nada. Subclasses podem implementar este método. 234 } 235 236 /** 237 * Não faz nada. Chamado pelo 238 * método 'stop' desta classe. 239 * Subclasses podem sobrepor este método 240 * para um controle próprio. 241 */ 242 protected void stopImpl() { 243 // Não faz nada. Subclasses podem implementar este método. 244 } 245 246 /** 247 * Não faz nada. Chamado pelo método 'setTick' desta 248 * classe. Subclasses podem sobrepor este método 249 * para controle próprio. 250 * @param tempo Quantidade de tempo do tick. 251 */ 252 protected void setTickImpl(final long tempo) { 253 // Não faz nada. Subclasses podem implementar este método. 254 } 255 256 /** 257 * Obtém o instante atual do relógio do sistema. 258 * Chamado diversas vezes por 259 * esta classe para implementar o controle do tempo. 260 * Por padrão, obtém o tempo atual através de 261 * <code>System.currentTimeMillis()</code> 262 * @return O valor do instante atual, de acordo com o relógio do 263 * systema. 264 */ 265 protected long getCurrentTime() { 266 return System.currentTimeMillis(); 267 } 268 269 /** 270 * Não faz nada. Chamado pelo método 'pause'. 271 * Subclasses podem implementar este método para 272 * um controle próprio. 273 */ 274 protected void pauseImpl() { 275 // Não faz nada. Subclasses podem sobrepor este 276 // método para um controle próprio. 277 } 278 279 /** 280 * Não faz nada. Chamado pelo método 'continua'. 281 * Subclasses podem sobrepor este método para um 282 * controle próprio. 283 */ 284 protected void continuaImpl() { 285 // Não faz nada. Subclasses podem sobrepor este 286 // método para um controle próprio. 287 } 288 }