Maybe I'm missing the point because it seems so simple but isn't something like this enough?
public class Component
{
protected limit = 1.0f;
private float timer = 0.0f;
public virtual void Update(float dt)
{
timer += dt;
if(timer >= limit)
{
timer -= limit;
LimitedUpdate();
}
}
public virtual void LimitedUpdate() {}
}
And then you override LimitedUpdate
and put anything that you only want triggering from limit
to limit
seconds there.
Edit
And to fulfill the idea on your comment about making it into a centralized component and event driven (instead of polling driven):
public class ActionManager
{
private struct ActionEntry
{
public Action Action;
public float Limit;
public float Timer;
}
private Dictionary<string, ActionEntry> entries = new Dictionary<string, ActionEntry>();
public RegisterAction(string id, Action action, float limit = 1.0f)
{
// Note: I made Timer = limit so that the first call is 'free'
entries[id] = new ActionEntry { Action = action, Limit = limit, Timer = limit };
}
public void TryAction(string id)
{
if(entries[id].Timer >= entries[id].Limit)
{
entries[id].Action();
entries[id].Timer = 0.0f;
}
}
public void Update(float dt)
{
foreach(var entry in entries)
{
entry.Value.Timer += dt;
}
}
}