Thursday, May 11, 2017

android - Thread runs faster on a faster processor... how to control Thread speed


I have a thread that uses TimeUnit.MILLISECONDS.sleep(5);


Problem is when I load my app on a faster phone say with a snapdragon, it runs at lightning speed.


Is there a way to control this speed so processor speed is not an attributing factor?


Thanks!



Answer




He'res the class I wrote for this purpose. Use it by first calling start() and then sleepRequiredTime() in your gameloop. call getTimeSinceLastSleep() for elapsed time.


runsPrSecondHint will dictate your wanted FPS. I'm not sure this solution is perfect though, so any input from others is welcome.


package com.ngame.spacegame.utils;

public class ThreadSleepManager {

private int m_runsPrSecondHint;
private float m_maxAllowedSleepTime;
private boolean m_running;


private long m_startTime = 0;
private long m_lastSleepTime = 0;

private int[] m_lastRuntimes;
private int m_runtimeToWriteToIndex = 0;
private int m_averageSleepTime = 0;
private int m_timeSinceLastSleep = 0;

private static final int AVERAGE_POOL = 10;


public ThreadSleepManager( int runsPrSecondHint ) {
m_runsPrSecondHint = runsPrSecondHint;

m_maxAllowedSleepTime = 1000.0f / m_runsPrSecondHint;
initLastRuntimes();
}

private void initLastRuntimes() {
m_lastRuntimes = new int[AVERAGE_POOL];
for ( int i : m_lastRuntimes ) {

m_lastRuntimes[ i ] = (int)m_maxAllowedSleepTime;
}
}

public int getTimeSinceLastSleep() {
return m_timeSinceLastSleep;
}

public int getAverageSleepTime() {
return m_averageSleepTime;

}

public void start() {
m_startTime = System.currentTimeMillis();
m_lastSleepTime = m_startTime;
}

/**
* Sleeps an optimal amount of time for trying
* to have the current thread calling run at m_runsPrSecondHint

*/
public void sleepRequiredTime() {
assert( m_running == true );
long currentTime = System.currentTimeMillis();
m_timeSinceLastSleep = (int) (currentTime - m_lastSleepTime);

// Update data used for average sleep time calculation
m_lastRuntimes[ m_runtimeToWriteToIndex ] = m_timeSinceLastSleep;
m_runtimeToWriteToIndex = ( m_runtimeToWriteToIndex + 1 ) % AVERAGE_POOL;


// Sleep long enough for the average time since last sleep to stay as close as
// possible to m_maxAllowedSleepTime
m_averageSleepTime = calcAverageTimeSinceLastSleep();

int timeToSleep = (int) (m_maxAllowedSleepTime - m_averageSleepTime);
if( timeToSleep > 0 ) {
try {
Thread.sleep( timeToSleep );
}
catch( InterruptedException e ) {


}
}

m_lastSleepTime = currentTime;
}

private int calcAverageTimeSinceLastSleep() {
int sum_sleep_time = 0;


for ( int runtime : m_lastRuntimes ) {
sum_sleep_time += runtime;
}

return sum_sleep_time / m_lastRuntimes.length;
}

}


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...