1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.android.torus.core.time
18 
19 import android.os.SystemClock
20 
21 /**
22  * Class in charge of controlling the delta time and the elapsed time. This will help with a
23  * common scenario in any Computer Graphics engine.
24  */
25 class TimeController {
26     companion object {
27         private val MIN_THRESHOLD_OVERFLOW = Float.MAX_VALUE / 1E20f
28         private const val MILLIS_TO_SECONDS = 1 / 1000f
29     }
30 
31     /**
32      * The elapsed time, since the last time it was reset, in seconds.
33      */
34     var elapsedTime = 0f
35         private set
36 
37     /**
38      * The delta time from the last frame, in milliseconds.
39      */
40     var deltaTimeMillis: Long = 0
41         private set
42 
43     private var lastTimeMillis: Long = 0
44 
45     init {
46         resetDeltaTime()
47     }
48 
49     /**
50      * Resets the delta time and last time since previous frame, and sets last time to
51      * [currentTimeMillis] and increases the elapsed time.
52      *
53      * @property currentTimeMillis The last known frame time, in milliseconds.
54      */
resetDeltaTimenull55     fun resetDeltaTime(currentTimeMillis: Long = SystemClock.elapsedRealtime()) {
56         lastTimeMillis = currentTimeMillis
57         elapsedTime += deltaTimeMillis * MILLIS_TO_SECONDS
58         deltaTimeMillis = 0
59     }
60 
61     /**
62      * Resets elapse time in case is bigger than the max value (to avoid overflow)
63      */
resetElapsedTimeIfNeedednull64     fun resetElapsedTimeIfNeeded() {
65         if (elapsedTime > MIN_THRESHOLD_OVERFLOW) {
66             elapsedTime = 0f
67         }
68     }
69 
70     /**
71      * Calculates the delta time (in milliseconds) based on the current time
72      * and the last saved time.
73      *
74      * @property currentTimeMillis The last known frame time, in milliseconds.
75      */
updateDeltaTimenull76     fun updateDeltaTime(currentTimeMillis: Long = SystemClock.elapsedRealtime()) {
77         deltaTimeMillis = currentTimeMillis - lastTimeMillis
78     }
79 }