Skip to content

Instantly share code, notes, and snippets.

@shanecelis
Last active July 6, 2020 07:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shanecelis/d4a26d21d9dc531bbd3e2bf33cb00259 to your computer and use it in GitHub Desktop.
Save shanecelis/d4a26d21d9dc531bbd3e2bf33cb00259 to your computer and use it in GitHub Desktop.
Limit rate of events based on time for Unity.
/* Original code[1] Copyright (c) 2009 Antti Huima[2]
Modified code[3] Copyright (c) 2020 Shane Celis[4]
Licensed under the MIT License[5]
Original code posted to this question[6] and answer[7] on stackoverflow.com.
This comment generated by code-cite[8].
[1]: https://stackoverflow.com/a/668327
[2]: https://stackoverflow.com/users/64376/antti-huima
[3]: https://gist.github.com/shanecelis/d4a26d21d9dc531bbd3e2bf33cb00259
[4]: http://twitter.com/shanecelis
[5]: https://opensource.org/licenses/MIT
[6]: https://stackoverflow.com/a/668327
[7]: https://github.com/shanecelis/code-cite
*/
using UnityEngine;
/** Limit rate of events based on time for Unity.
```
private RateLimiter limiter = new RateLimiter(1/60f); // Allow 1 event per 60 seconds
// or 1 event per minute.
// ...
// Called 60 times a second.
void Update() {
if (limiter.Allow()) {
Debug.Log("Without a limiter this message would be logged 60 times a second.");
}
}
```
*/
public class RateLimiter {
public float eventsPerSecond; // units: events / second
private float lastCheck = -1f; // units: seconds
private float allowance; // units: events / second
public RateLimiter(float eventsPerSecond) {
this.eventsPerSecond = eventsPerSecond;
allowance = eventsPerSecond;
}
// https://stackoverflow.com/questions/667508/whats-a-good-rate-limiting-algorithm
/** Can allow an event within the limiter's constraints? */
public bool Allow() {
if (lastCheck < 0)
lastCheck = Time.time - 1f/eventsPerSecond;
float current = Time.time;
float timePassed = current - lastCheck;
lastCheck = current;
float eventAllowance = timePassed * eventsPerSecond; // units: events
allowance += eventAllowance / timePassed; // units: events / second
if (allowance > eventsPerSecond)
allowance = eventsPerSecond;
if (eventAllowance < 1f) {
return false;
} else {
allowance -= 1f / timePassed;
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment