/*
* Idozito.java
* az abszolút időtől nem csúszó, periodikus időzítést valósít meg
* by pts@fazekas.hu at 2001.03.??
* további doksi: a README-ben és e file legkülső class-ának fejkommentjében
*
* Kincskereső Kisgömböc (C) Early May 2001 by eNTitánok (Rév Szilvia,
* Szabó Péter <pts@inf.bme.hu>, Szurdi Miklós, Weizengruber Attila).
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package eNTitanok.util;
/**
* Egy vagy több, <code>Idozito.Idozitett</code> típusú objektum periodikus
* időzítését
* látja el, ügyelve arra, hogy hosszútávon se csússzunk el az abszolút időtől.
* Csak egyetlen Idozitett-re teszteltük. Csak Win32 alatt működik jól, Linux
* JDK1.3 alatt igenis csúszunk (,,lassulunk'', elmaradunk)
* @see eNTitanok.util.Idozito.Idozitett
*/
public class Idozito extends Thread {
protected volatile boolean futunk_e_meg=true;
// volatile int hatravan; // volatile: ne cache-elje
protected volatile long holtart;
protected volatile int varakozok;
protected long interval_ms;
public Idozito(int interval_ms_) { interval_ms=interval_ms_; }
public int getInterval() { return (int)interval_ms; }
public long getHoltart() { return holtart; }
public void var(long meddig) {
// kívülről hivandó, pl :Időzített-ből
do { // általában csak egyszer fut le a ciklusmag
synchronized(this) {
varakozok++;
try { super.wait(interval_ms); } catch (InterruptedException e) { }
varakozok--;
}
} while (meddig>holtart);
}
public static void alszik(int mennyit) {
// millisec
try { Thread.sleep(mennyit); } catch (InterruptedException e) {}
}
public void stopp() { futunk_e_meg=false; this.interrupt(); }
public void run() {
long logik, van, mennyit_alszom;
this.setPriority(MAX_PRIORITY);
mennyit_alszom=interval_ms;
logik=java.lang.System.currentTimeMillis();
while (futunk_e_meg) {
// System.out.println("Mennyit: "+mennyit_alszom+".");
try { java.lang.Thread.sleep(mennyit_alszom); } catch (InterruptedException e) { System.out.println("IR"); }
logik+=interval_ms;
van=java.lang.System.currentTimeMillis();
if (logik<van-200) mennyit_alszom=interval_ms*9/10;
else if (logik>van+200) mennyit_alszom=interval_ms;
//hatravan++;
holtart++;
if (varakozok>0) { synchronized(this) { super.notifyAll(); } }
}
} /// run()
public static class Idozitett {
protected Idozito idozito;
protected long megteve;
protected boolean utoljara_aludtunk;
protected long nem_rajzoltunk; // az utolsó rajzolás óta hányszor nem rajzoltunk
protected long nem_rajzoltunk_osszesen;
protected long rajzoltunk_osszesen;
protected long mikor_inditottak; // időpont ms-ben
public Idozitett(Idozito idozito) {
this.idozito=idozito;
ujraindit();
}
public boolean altass_el() {
if (megteve++<idozito.getHoltart()) {
Thread.yield();
return utoljara_aludtunk=false;
} else {
idozito.var(megteve);
return utoljara_aludtunk=true;
}
} /// altass_el()
public void lassu_muvelet() {
rajzoltunk_osszesen++;
nem_rajzoltunk=0;
altass_el();
}
public void gyors_muvelet() {
nem_rajzoltunk++;
nem_rajzoltunk_osszesen++;
altass_el();
}
public boolean lehet_lassu_muvelet() { // állapotlekérdezés
return utoljara_aludtunk || nem_rajzoltunk>50;
}
public void ujraindit() {
utoljara_aludtunk=true;
megteve=idozito.getHoltart();
// ^^ bugfix by pts@fazekas.hu at Wed May 16 09:44:12 CEST 2001
nem_rajzoltunk=nem_rajzoltunk_osszesen=0;
// ^^^ bugfix by pts@fazekas.hu at Mon Apr 23 08:55:29 CEST 2001
if (!idozito.isAlive()) idozito.start(); // tényleg isAlive kell ide??
mikor_inditottak=System.currentTimeMillis();
rajzoltunk_osszesen=1;
}
public long getMegteve() { return megteve; }
public long getEloirtPeriodus() { /*micros-ban*/ return 1000L*idozito.getInterval(); }
public long getSikerultPeriodus() { /*micros-ban*/
return megteve==0?0:1000L*(System.currentTimeMillis()-mikor_inditottak)/megteve;
}
public long getLassuMuveletSzazalek() {
return 100L*(rajzoltunk_osszesen)/(rajzoltunk_osszesen+nem_rajzoltunk_osszesen);
}
public long getGyorsMuvelet() { return rajzoltunk_osszesen; }
} /// class Idozitett
} /// class Idozito