All pastes #47644 Raw Edit

Miscellany

public text v1 · immutable
#47644 ·published 2006-03-30 23:43 UTC
rendered paste body
Index: C:/workspace/L2_GameServer_c4/java/net/sf/l2j/gameserver/GameTimeController.java
===================================================================
--- C:/workspace/L2_GameServer_c4/java/net/sf/l2j/gameserver/GameTimeController.java	(revision 1694)
+++ C:/workspace/L2_GameServer_c4/java/net/sf/l2j/gameserver/GameTimeController.java	(working copy)
@@ -42,20 +42,20 @@
 public class GameTimeController
 {
 	static final Logger _log = Logger.getLogger(GameTimeController.class.getName());
-	
+
 	public static final int TICKS_PER_SECOND = 10;
 	public static final int MILLIS_IN_TICK = 1000 / TICKS_PER_SECOND;
-	
+
 	private static GameTimeController _instance = new GameTimeController();
-	
-    protected static int  _gameTicks;
+
+	protected static int _gameTicks;
 	protected static long _gameStartTime;
 	protected static boolean _isNight;
-	
-	private static List<L2Character> movingObjects = new FastList<L2Character>(); 
-	
-       protected static TimerThread _timer;
 
+	private static List<L2Character> movingObjects = new FastList<L2Character>();
+
+	protected static TimerThread _timer;
+
 	/**
 	 * one ingame day is 240 real minutes
 	 */
@@ -63,36 +63,34 @@
 	{
 		return _instance;
 	}
-	
+
 	private GameTimeController()
 	{
-		_gameStartTime = System.currentTimeMillis()- 3600000; // offset so that the server starts a day begin
-		_gameTicks = 3600000/MILLIS_IN_TICK; // offset so that the server starts a day begin
+		_gameStartTime = System.currentTimeMillis() - 3600000; // offset so that the server starts a day begin
+		_gameTicks = 3600000 / MILLIS_IN_TICK; // offset so that the server starts a day begin
 
 		_timer = new TimerThread();
 		_timer.start();
 
-		ClientScheduler.getInstance().scheduleLowAtFixedRate(
-				new TimerWatcher(), 0, 1000);
-		ClientScheduler.getInstance().scheduleLowAtFixedRate(
-				new BroadcastSunState(), 0, 60*60*1000
-				);
+		ClientScheduler.getInstance().scheduleLowAtFixedRate(new TimerWatcher(), 0, 1000);
+		ClientScheduler.getInstance().scheduleLowAtFixedRate(new BroadcastSunState(), 0, 60 * 60 * 1000);
 	}
-	
-	public boolean isNowNight() {
+
+	public boolean isNowNight()
+	{
 		return _isNight;
 	}
-	
+
 	public int getGameTime()
 	{
-		return (_gameTicks / (TICKS_PER_SECOND*10));
+		return (_gameTicks / (TICKS_PER_SECOND * 10));
 	}
-	
+
 	public static int getGameTicks()
 	{
 		return _gameTicks;
 	}
-	
+
 	/**
 	 * Add a L2Character to movingObjects of GameTimeController.<BR><BR>
 	 * 
@@ -102,12 +100,11 @@
 	 * @param cha The L2Character to add to movingObjects of GameTimeController
 	 * 
 	 */
-	public synchronized void registerMovingObject(L2Character cha) 
+	public synchronized void registerMovingObject(L2Character cha)
 	{
-		if (!movingObjects.contains(cha))
-			movingObjects.add(cha);
+		if (!movingObjects.contains(cha)) movingObjects.add(cha);
 	}
-	
+
 	/**
 	 * Move all L2Characters contained in movingObjects of GameTimeController.<BR><BR>
 	 * 
@@ -120,54 +117,53 @@
 	 * <li>Create a task to update the _knownObject and _knowPlayers of each L2Character that finished its movement and of their already known L2Object then notify AI with EVT_ARRIVED </li><BR><BR>
 	 * 
 	 */
-    protected synchronized void moveObjects() 
+	protected synchronized void moveObjects()
 	{
 		// Get all L2Character from the ArrayList movingObjects and put them into a table
 		L2Character[] chars = movingObjects.toArray(new L2Character[movingObjects.size()]);
-		
+
 		// Create an ArrayList to contain all L2Character that are arrived to destination
 		List<L2Character> ended = null;
-		
+
 		// Go throw the table containing L2Character in movement
-		for (int i=0; i < chars.length; i++) 
+		for (int i = 0; i < chars.length; i++)
 		{
-			
+
 			L2Character cha = chars[i];
-			
+
 			// Update the position of the L2Character and return True if the movement is finished
 			boolean end = cha.updatePosition(_gameTicks);
-			
+
 			// If movement is finished, the L2Character is removed from movingObjects and added to the ArrayList ended
 			if (end)
 			{
 				movingObjects.remove(cha);
-				if (ended == null)
-					ended = new FastList<L2Character>();
-				
+				if (ended == null) ended = new FastList<L2Character>();
+
 				ended.add(cha);
 			}
 		}
-		
+
 		// Create a task to update the _knownObject and _knowPlayers of each L2Character that finished its movement and of their already known L2Object 
 		// then notify AI with EVT_ARRIVED
 		if (ended != null)
 			ClientScheduler.getInstance().scheduleLow(new MovingObjectArrived(ended), 10);
-		
+
 	}
-	
+
 	public void stopTimer()
 	{
 		_timer._stop = true;
 	}
-	
+
 	class TimerThread extends Thread
 	{
 		protected boolean _stop;
-        protected Exception _error;
-		
+		protected Exception _error;
+
 		public TimerThread()
 		{
-                     super("GameTimeController");
+			super("GameTimeController");
 			setDaemon(true);
 			setPriority(MAX_PRIORITY);
 			_stop = false;
@@ -176,28 +172,39 @@
 
 		public void run()
 		{
-			try {
-                            int _oldTicks;
+			try
+			{				
 				for (;;)
 				{
-					long runtime = System.currentTimeMillis() - _gameStartTime;
-                                   _oldTicks=_gameTicks;
-					_gameTicks = (int)(runtime / MILLIS_IN_TICK);
-                                   if(_oldTicks!=_gameTicks) moveObjects(); 
-                                   else yield();
-                                   
-					runtime = System.currentTimeMillis() - _gameStartTime;
-					int sleepTime = 1 + MILLIS_IN_TICK - ((int)runtime) % MILLIS_IN_TICK; 
-					sleep( sleepTime ); 
-					if (_stop)
-						throw new Exception("stopTimer() was called");
+					int _oldTicks=_gameTicks; // save old ticks value to avoid moving objects 2x in same tick	
+					long runtime = System.currentTimeMillis() - _gameStartTime; // from server boot to now
+
+					_gameTicks = (int) (runtime / MILLIS_IN_TICK); // new ticks value (ticks now) 
+
+					if (_oldTicks != _gameTicks) moveObjects(); // XXX: if this makes objects go slower, remove it
+					// but I think it can't make that effect. is it better to call moveObjects() twice in same
+					// tick to make-up for missed tick ?   or is it better to ignore missed tick ?
+					// (will happen very rarely but it will happen ... on garbage collection definitely)
+
+					runtime = (System.currentTimeMillis() - _gameStartTime) - runtime;
+
+					// calculate sleep time... time needed to next tick minus time it takes to call moveObjects() 
+					int sleepTime = 1 + MILLIS_IN_TICK - ((int) runtime) % MILLIS_IN_TICK;
+
+					//_log.finest("TICK: "+_gameTicks);
+
+					sleep(sleepTime); // hope other threads will have much more cpu time available now
+					// SelectorThread most of all
+					if (_stop) throw new Exception("stopTimer() was called");
 				}
-			} catch (Exception e) {
+			}
+			catch (Exception e)
+			{
 				_error = e;
 			}
 		}
 	}
-	
+
 	class TimerWatcher implements Runnable
 	{
 		public void run()
@@ -205,38 +212,37 @@
 			if (!_timer.isAlive())
 			{
 				String time = (new SimpleDateFormat("HH:mm:ss")).format(new Date());
-				_log.warning(time+" TimerThread stop with following error. restart it.");
-				if (_timer._error != null)
-					_timer._error.printStackTrace();
-				
+				_log.warning(time + " TimerThread stop with following error. restart it.");
+				if (_timer._error != null) _timer._error.printStackTrace();
+
 				_timer = new TimerThread();
 				_timer.start();
 			}
 		}
 	}
-	
+
 	/**
 	 * Update the _knownObject and _knowPlayers of each L2Character that finished its movement and of their already known L2Object then notify AI with EVT_ARRIVED.<BR><BR>
 	 */
 	class MovingObjectArrived implements Runnable
 	{
 		final List<L2Character> ended;
-		
-		MovingObjectArrived(List<L2Character> ended) 
+
+		MovingObjectArrived(List<L2Character> ended)
 		{
 			this.ended = ended;
 		}
-		
-		public void run() 
+
+		public void run()
 		{
-			for (L2Character cha : ended) 
+			for (L2Character cha : ended)
 			{
 				cha.getKnownList().updateKnownObjects();
 				cha.getAI().notifyEvent(CtrlEvent.EVT_ARRIVED);
 			}
 		}
 	}
-	
+
 	/**
 	 * @param rise
 	 */
@@ -244,35 +250,34 @@
 	{
 		public void run()
 		{
-            int h = (getGameTime() / 60) % 24;                      // Time in hour
-            boolean tempIsNight = (h < Config.DAY_STATUS_SUN_RISE_AT || h >= Config.DAY_STATUS_SUN_SET_AT);
-            
-            if (tempIsNight != isNowNight())                        // If diff day/night state
-                _isNight = tempIsNight;                             // Set current day/night varible to value of temp varible
-            else
-                return;                                             // Do nothing if same state
+			int h = (getGameTime() / 60) % 24; // Time in hour
+			boolean tempIsNight = (h < Config.DAY_STATUS_SUN_RISE_AT || h >= Config.DAY_STATUS_SUN_SET_AT);
 
-            if (!Config.DAY_STATUS_FORCE_CLIENT_UPDATE)             // Do not force client to update their day/night status
-                return;
+			if (tempIsNight != isNowNight()) // If diff day/night state
+			_isNight = tempIsNight; // Set current day/night varible to value of temp varible
+			else return; // Do nothing if same state
 
-            if (SevenSigns.getInstance().isSealValidationPeriod())  // Do nothing if in Seal validation period 
-                return;
-            
-            // Force client day/night cycle to sync everyone's day/night state
-            ServerBasePacket packet;
-            if (isNowNight())                                       // If is now night
-            {
-                packet = new SunSet();                              // Set client day/night state to night
-                if (Config.DEBUG) _log.fine("SunSet");
-            }
-            else
-            {
-                packet = new SunRise();                             // Set client day/night state to day
-                if (Config.DEBUG) _log.fine("SunRise");
-            }
-            
-            for (L2PcInstance player : L2World.getInstance().getAllPlayers())
-                player.sendPacket(packet);
+			if (!Config.DAY_STATUS_FORCE_CLIENT_UPDATE) // Do not force client to update their day/night status
+				return;
+
+			if (SevenSigns.getInstance().isSealValidationPeriod()) // Do nothing if in Seal validation period 
+				return;
+
+			// Force client day/night cycle to sync everyone's day/night state
+			ServerBasePacket packet;
+			if (isNowNight()) // If is now night
+			{
+				packet = new SunSet(); // Set client day/night state to night
+				if (Config.DEBUG) _log.fine("SunSet");
+			}
+			else
+			{
+				packet = new SunRise(); // Set client day/night state to day
+				if (Config.DEBUG) _log.fine("SunRise");
+			}
+
+			for (L2PcInstance player : L2World.getInstance().getAllPlayers())
+				player.sendPacket(packet);
 		}
 	}
 }