When adding elements to a table, the .add() function does not behave as
expected in various cases, making it really shit and difficult to use.
Instead, we keep our own index and just add one by one. It works, and
it's easy to understand.
This may lead to indices which are nil, i.e. non-fully-sequential
tables, but I can't be asked to worry about it because that shouldn't be
an issue when we use .set() everywhere.
Adds `Util.DebugExecutionTime()`, which returns a table of
`function_name: milliseconds`, in which each function's execution time
is averaged over all time.
You can call this function like so:
```lua
-- event to print the debug times
MP.RegisterEvent("printStuff", "printStuff")
-- prints the execution time of all event handlers
function printStuff()
print(Util.DebugExecutionTime())
end
-- run every 5 seconds (or 10, or 60, whatever makes sense for you
MP.CreateEventTimer("printStuff", 5000)
```
Pretty print function:
```lua
function printDebugExecutionTime()
local stats = Util.DebugExecutionTime()
local pretty = "DebugExecutionTime:\n"
local longest = 0
for name, t in pairs(stats) do
if #name > longest then
longest = #name
end
end
for name, t in pairs(stats) do
pretty = pretty .. string.format("%" .. longest + 1 .. "s: %12f +/- %12f (min: %12f, max: %12f) (called %d time(s))\n", name, t.mean, t.stdev, t.min, t.max, t.n)
end
print(pretty)
end
```
`Util.DebugExecutionTime()` returns a table, where each key is an event
handler function name, and each value is a table consisting of `mean`
(simple average), `stddev` (standard deviation aka mean of the
variance), `min` and `max`, all in milliseconds, as well as `n` as the
number of samples taken.
Before, a lot of common errors went unnoticed, due to insufficient
compiler diagnostics. This commit fixes this by adding a lot of new
diagnostics, and fixing the issues found by this.
The event loop tries to run no faster than every 10ms. If it detects
that it goes faster, it would incorrectly calculate the difference, and
then wait (what I assume was) way too long or too short.
Either way, now it's fixed and it correctly works, even when introducing
new lua states.
While this doesn't make a difference with usual setups, it does if the
server path exists but is a symlink. In that case, the
create_directories call fails, and the server aborts.
this fixes that. :^)
There are two CallStrategies:
- BestEffort (default): Will try to get your event to trigger at the specified
interval, but will refuse to queue handlers if a handler takes too
long.
- Precise: Will enqueue event handlers at the exact interval specified.
Can lead to the queue filling up if the handler takes longer than the
interval.