Stats.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. --[[
  2. MIT License
  3. Copyright (c) 2019 Mitchell Davis <coding.jackalope@gmail.com>
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. --]]
  20. local Stats = {}
  21. local Data = {}
  22. local Pending = {}
  23. local Enabled = false
  24. local QueueEnabled = false
  25. local QueueDisable = false
  26. local Id = 1
  27. local QueueFlush = false
  28. local function GetCategory(Category)
  29. assert(Category ~= nil, "Nil category given to Stats system.")
  30. assert(Category ~= '', "Empty category given to Stats system.")
  31. assert(type(Category) == 'string', "Category given is not of type string. Type given is '" .. type(Category) .. "'.")
  32. if Data[Category] == nil then
  33. Data[Category] = {}
  34. end
  35. return Data[Category]
  36. end
  37. local function ResetCategory(Category)
  38. local Instance = Data[Category]
  39. if Instance ~= nil then
  40. for K, V in pairs(Instance) do
  41. V.LastTime = V.Time
  42. V.LastCallCount = V.CallCount
  43. V.MaxTime = math.max(V.MaxTime, V.Time)
  44. V.Time = 0.0
  45. V.CallCount = 0
  46. end
  47. end
  48. end
  49. local function GetItem(Name, Category)
  50. assert(Name ~= nil, "Nil name given to Stats system.")
  51. assert(Name ~= '', "Empty name given to Stats system.")
  52. local Cat = GetCategory(Category)
  53. if Cat[Name] == nil then
  54. local Instance = {}
  55. Instance.Time = 0.0
  56. Instance.MaxTime = 0.0
  57. Instance.CallCount = 0
  58. Instance.LastTime = 0.0
  59. Instance.LastCallCount = 0.0
  60. Cat[Name] = Instance
  61. end
  62. return Cat[Name]
  63. end
  64. function Stats.Begin(Name, Category)
  65. if not Enabled then
  66. return
  67. end
  68. local Handle = Id
  69. Id = Id + 1
  70. local Instance = {StartTime = love.timer.getTime(), Name = Name, Category = Category}
  71. Pending[Handle] = Instance
  72. return Handle
  73. end
  74. function Stats.End(Handle)
  75. if not Enabled then
  76. return
  77. end
  78. assert(Handle ~= nil, "Nil handle given to Stats.End.")
  79. local Instance = Pending[Handle]
  80. assert(Instance ~= nil, "Invalid handle given to Stats.End.")
  81. Pending[Handle] = nil
  82. local Elapsed = love.timer.getTime() - Instance.StartTime
  83. local Item = GetItem(Instance.Name, Instance.Category)
  84. Item.CallCount = Item.CallCount + 1
  85. Item.Time = Item.Time + Elapsed
  86. end
  87. function Stats.GetTime(Name, Category)
  88. if not Enabled then
  89. return 0.0
  90. end
  91. local Item = GetItem(Name, Category)
  92. return Item.Time > 0.0 and Item.Time or Item.LastTime
  93. end
  94. function Stats.GetMaxTime(Name, Category)
  95. if not Enabled then
  96. return 0.0
  97. end
  98. local Item = GetItem(Name, Category)
  99. return Item.MaxTime
  100. end
  101. function Stats.GetCallCount(Name, Category)
  102. if not Enabled then
  103. return 0
  104. end
  105. local Item = GetItem(Name, Category)
  106. return Item.CallCount > 0 and Item.CallCount or Item.LastCallCount
  107. end
  108. function Stats.Reset()
  109. if QueueEnabled then
  110. Enabled = true
  111. QueueEnabled = false
  112. end
  113. if QueueDisable then
  114. Enabled = false
  115. QueueDisable = false
  116. end
  117. if QueueFlush then
  118. Data = {}
  119. Pending = {}
  120. Id = 1
  121. QueueFlush = false
  122. end
  123. if not Enabled then
  124. return
  125. end
  126. local Message = nil
  127. for K, V in pairs(Pending) do
  128. if Message == nil then
  129. Message = "Stats.End were not called for the given stats: \n"
  130. end
  131. Message = Message .. "\t" .. tostring(V.Name) .. " in " .. tostring(V.Category) .. "\n"
  132. end
  133. assert(Message == nil, Message)
  134. for K, V in pairs(Data) do
  135. ResetCategory(K)
  136. end
  137. end
  138. function Stats.SetEnabled(IsEnabled)
  139. QueueEnabled = IsEnabled
  140. if not QueueEnabled then
  141. QueueDisable = true
  142. end
  143. end
  144. function Stats.IsEnabled()
  145. return Enabled
  146. end
  147. function Stats.GetCategories()
  148. local Result = {}
  149. for K, V in pairs(Data) do
  150. table.insert(Result, K)
  151. end
  152. return Result
  153. end
  154. function Stats.GetItems(Category)
  155. local Result = {}
  156. local Instance = GetCategory(Category)
  157. for K, V in pairs(Instance) do
  158. table.insert(Result, K)
  159. end
  160. return Result
  161. end
  162. function Stats.Flush()
  163. QueueFlush = true
  164. end
  165. return Stats