/*
* Constrainer.java
*
* Copyright (C) 2008 AppleGrew
*
* 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 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 org.elite.jdcbot.util;
/**
* Created on 02-Jun-08<br>
* Its job is to constrain/limit the rate to a particular set value.
*
* @author AppleGrew
* @since 0.7.2
* @version 0.1.1
*/
public abstract class RateConstrainer {
private double targetConstrain = -1;
/**
* Sets the target rate. To disable contrain set this to <=0, or
* better call {@link #revokeConstrain()}.
* @param targetRate The target rate in units per <b>second</b>.
*/
public void setTargetConstrainValue(double targetRate) {
targetConstrain = targetRate;
}
/**
* Disables constrain on rate.
*
*/
public void revokeConstrain() {
targetConstrain = -1;
}
/**
* Will make the thread sleep to bring current rate near target rate.
* @param currentRate Current rate in units per <b>second</b>.
* @param currentTotalProgress Total amount of units.
*/
public void constrain(double currentRate, long currentTotalProgress) {
if (targetConstrain <= 0 || currentRate <= 0)
return;
/*
* ===================================================================
* Below is a note about how I deduced the formula to calculate the
* period of time to sleep so that rate can be constrained to a value.
* ===================================================================
*
* Let a = currentTotalProgress,
* r = currentRate, and
* R = targetConstrain.
*
* Now total duration over which r has been calculated (t) = a/r ...(1)
*
* If r > R the we must sleep to make r decrease to R.
*
* When we wake from sleep 'a' will still be the same but time would have increased, hence the final rate
* then would be (r*) = a/(t+x), where x is the period of time in seconds we slept.
* But we want r* to be R
* => R = a/(t+x)
* => R = a/( (a/r) + x) ...from (1)
* => x = (a/R) - (a/r) seconds
* => x = ( (a/R) - (a/r) ) * 1000 ms
*/
long sleepTime =
currentRate > targetConstrain ? (long) ((currentTotalProgress / targetConstrain - currentTotalProgress / currentRate) * 1000)
: 0;
if (sleepTime >= 1) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}