/* * 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