summaryrefslogtreecommitdiff
path: root/Assets/Thirdparty/Tayx/Graphy - Ultimate Stats Monitor/Scripts/Fps/G_FpsMonitor.cs
blob: 4aadfa8fed75f60983c2e1501ded85ce6798d095 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/* ---------------------------------------
 * Author:          Martin Pane (martintayx@gmail.com) (@tayx94)
 * Collaborators:   Lars Aalbertsen (@Rockylars)
 * Project:         Graphy - Ultimate Stats Monitor
 * Date:            15-Dec-17
 * Studio:          Tayx
 * 
 * This project is released under the MIT license.
 * Attribution is not required, but it is always welcomed!
 * -------------------------------------*/

using UnityEngine;
using System.Runtime.CompilerServices;

namespace Tayx.Graphy.Fps
{
    public class G_FpsMonitor : MonoBehaviour
    {
        /* ----- TODO: ----------------------------
         * Add summaries to the variables.
         * Add summaries to the functions.
         * --------------------------------------*/

        #region Variables -> Serialized Private

        [SerializeField] private    int             m_averageSamples            = 200;

        #endregion

        #region Variables -> Private

        private GraphyManager                       m_graphyManager;

        private                     float           m_currentFps                = 0f;
        private                     float           m_avgFps                    = 0f;
        private                     float           m_minFps                    = 0f;
        private                     float           m_maxFps                    = 0f;

        private                     float[]         m_averageFpsSamples;
        private                     int             m_avgFpsSamplesOffset       = 0;
        private                     int             m_indexMask                 = 0;
        private                     int             m_avgFpsSamplesCapacity     = 0;
        private                     int             m_avgFpsSamplesCount        = 0;
        private                     int             m_timeToResetMinMaxFps      = 10;

        private                     float           m_timeToResetMinFpsPassed   = 0f;
        private                     float           m_timeToResetMaxFpsPassed   = 0f;

        private                     float           unscaledDeltaTime           = 0f;

        #endregion

        #region Properties -> Public

        public                      float           CurrentFPS  { get { return m_currentFps; } }
        public                      float           AverageFPS  { get { return m_avgFps;} }

        public                      float           MinFPS      { get { return m_minFps;} }
        public                      float           MaxFPS      { get { return m_maxFps;} }
        
        #endregion

        #region Methods -> Unity Callbacks

        private void Awake()
        {
            Init();
        }

        private void Update()
        {
            unscaledDeltaTime = Time.unscaledDeltaTime;

            m_timeToResetMinFpsPassed += unscaledDeltaTime;
            m_timeToResetMaxFpsPassed += unscaledDeltaTime;

            // Update fps and ms

            m_currentFps = 1 / unscaledDeltaTime;

            // Update avg fps

            m_avgFps = 0;

            m_averageFpsSamples[ToBufferIndex(m_avgFpsSamplesCount)] = m_currentFps;
            m_avgFpsSamplesOffset = ToBufferIndex(m_avgFpsSamplesOffset + 1);
            
            if (m_avgFpsSamplesCount < m_avgFpsSamplesCapacity)
            {
                m_avgFpsSamplesCount++;
            }

            for (int i = 0; i < m_avgFpsSamplesCount; i++)
            {
                m_avgFps += m_averageFpsSamples[i];
            }

            m_avgFps /= m_avgFpsSamplesCount;

            // Checks to reset min and max fps

            if (    m_timeToResetMinMaxFps    > 0 
                &&  m_timeToResetMinFpsPassed > m_timeToResetMinMaxFps)
            {
                m_minFps = 0;
                m_timeToResetMinFpsPassed = 0;
            }

            if (    m_timeToResetMinMaxFps    > 0 
                &&  m_timeToResetMaxFpsPassed > m_timeToResetMinMaxFps)
            {
                m_maxFps = 0;
                m_timeToResetMaxFpsPassed = 0;
            }

            // Update min fps

            if (m_currentFps < m_minFps || m_minFps <= 0)
            {
                m_minFps = m_currentFps;

                m_timeToResetMinFpsPassed = 0;
            }

            // Update max fps

            if (m_currentFps > m_maxFps || m_maxFps <= 0)
            {
                m_maxFps = m_currentFps;

                m_timeToResetMaxFpsPassed = 0;
            }
        }

        #endregion

        #region Methods -> Public

        public void UpdateParameters()
        {
            m_timeToResetMinMaxFps = m_graphyManager.TimeToResetMinMaxFps;
        }

        #endregion

        #region Methods -> Private

        private void Init()
        {
            m_graphyManager = transform.root.GetComponentInChildren<GraphyManager>();

            ResizeSamplesBuffer(m_averageSamples);
            
            UpdateParameters();
        }

        
        private void ResizeSamplesBuffer(int size)
        {
            m_avgFpsSamplesCapacity = Mathf.NextPowerOfTwo(size);

            m_averageFpsSamples = new float[m_avgFpsSamplesCapacity];
            
            m_indexMask = m_avgFpsSamplesCapacity - 1;
            m_avgFpsSamplesOffset = 0;
        }
        
#if NET_4_6 || NET_STANDARD_2_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        private int ToBufferIndex(int index)
        {
            return (index + m_avgFpsSamplesOffset) & m_indexMask;
        }
        
        #endregion
    }
}