1. public interface GameTickListener {
  2.     public void update(int tickCount);
  3. }
  4.  
  5. //_______________________________________________________
  6. //_______________________________________________________
  7.  
  8. public interface GameTimeListener {
  9.     public void update(double timeDelta);
  10. }
  11.  
  12. //_______________________________________________________
  13. //_______________________________________________________
  14.  
  15. import java.util.Collection;
  16. import java.util.LinkedList;
  17.  
  18. public class TickListenerManager {
  19.  
  20.     private static final long SECOND_TO_NANO = 1_000_000_000L;
  21.     private final Collection<GameTickListener> tickListener = new LinkedList<>();
  22.     private final long frequency;
  23.  
  24.     public TickListenerManager(int frequency) {
  25.         this.frequency = frequency * SECOND_TO_NANO;
  26.     }
  27.  
  28.     public void addListener(GameTickListener listener) {
  29.         tickListener.add(listener);
  30.     }
  31.  
  32.     public boolean removeListener(GameTickListener listener) {
  33.         tickListener.remove(listener);
  34.         return tickListener.isEmpty();
  35.     }
  36.  
  37.     public void update(long totalTime, long delta) {
  38.         long ticks = (totalTime / frequency) - ((totalTime - delta) / frequency);
  39.         for (GameTickListener listener : tickListener) {
  40.             listener.update((int) ticks);
  41.         }
  42.     }
  43.  
  44.     public int getFrequency() {
  45.         return (int) (frequency / SECOND_TO_NANO);
  46.     }
  47. }
  48.  
  49. //_______________________________________________________
  50. //_______________________________________________________
  51.  
  52. import java.util.Collection;
  53. import java.util.HashMap;
  54. import java.util.LinkedList;
  55. import java.util.Map;
  56.  
  57. public class GameTime {
  58.  
  59.     private static class Start {
  60.  
  61.         private static final long time = System.nanoTime();
  62.     }
  63.     private static final long SECOND_TO_NANO = 1_000_000_000L;
  64.     private static final double NANO_TO_SECOND = 1. / SECOND_TO_NANO;
  65.    
  66.     public static final GameTime INSTANCE = new GameTime();
  67.    
  68.     private long elapsed = 0;
  69.    
  70.     private Map<Integer, TickListenerManager> tickListener = new HashMap<>();
  71.     private Collection<GameTimeListener> timeListener = new LinkedList<>();
  72.  
  73.     private GameTime() {
  74.     }
  75.  
  76.     public void update() {
  77.         long start = Start.time;
  78.  
  79.         long now = System.nanoTime();
  80.  
  81.         long delta = now - start - elapsed;
  82.  
  83.         updatedTimeListener(delta);
  84.         updatedTickListener(delta);
  85.  
  86.         elapsed += delta;
  87.     }
  88.  
  89.     private void updatedTimeListener(long nanoSeconds) {
  90.         double delta = nanoSeconds * NANO_TO_SECOND;
  91.         for (GameTimeListener listener : timeListener) {
  92.             listener.update(delta);
  93.         }
  94.     }
  95.  
  96.     private void updatedTickListener(long nanoSeconds) {
  97.         for (TickListenerManager lm : tickListener.values()) {
  98.             lm.update(elapsed, nanoSeconds);
  99.         }
  100.     }
  101.  
  102.     /**
  103.      *
  104.      * @param frequency of ticks in herz
  105.      * @return
  106.      */
  107.     public void addTickListener(int frequency, GameTickListener listener) {
  108.         TickListenerManager tlm = tickListener.get(frequency);
  109.         if(tlm == null)
  110.         {
  111.             tlm = new TickListenerManager(frequency);
  112.             tickListener.put(frequency, tlm);
  113.         }
  114.         tlm.addListener(listener);
  115.     }
  116.  
  117.     public void removeTickListener(GameTickListener listener) {
  118.          for (TickListenerManager lm : tickListener.values()) {
  119.             if(lm.removeListener(listener))
  120.             {
  121.                 tickListener.remove(lm.getFrequency());
  122.                 break;
  123.             }
  124.         }
  125.     }
  126.  
  127.     public void addTimeListener(GameTimeListener listener) {
  128.         timeListener.add(listener);
  129.     }
  130.  
  131.     public void removeTimeistener(GameTimeListener listener) {
  132.         timeListener.remove(listener);
  133.     }
  134.  
  135.     public double getGameTime() {
  136.         return elapsed * NANO_TO_SECOND;
  137.     }
  138.  
  139.     /**
  140.      *
  141.      * @param frequency of ticks in herz
  142.      * @return
  143.      */
  144.     public long getGameTicks(int frequency) {
  145.         return elapsed / (frequency * SECOND_TO_NANO);
  146.     }
  147. }