using System.Collections.Generic; using Common.Base; using Common.Event; using Common.Helper; using MongoDB.Bson; namespace Model { public class TimerComponent : Component, IRunner { private class Timer { public ObjectId Id { get; set; } public long Time { get; set; } public int CallbackId { get; set; } public Env Env { get; set; } } private readonly Dictionary timers = new Dictionary(); /// /// key: time, value: timer id /// private readonly MultiMap timeId = new MultiMap(); private readonly Queue timeoutTimer = new Queue(); public ObjectId Add(long time, int callbackId, Env env) { Timer timer = new Timer { Id = ObjectId.GenerateNewId(), Time = time, CallbackId = callbackId, Env = env }; this.timers[timer.Id] = timer; this.timeId.Add(timer.Time, timer.Id); return timer.Id; } public void Remove(ObjectId id) { Timer timer; if (!this.timers.TryGetValue(id, out timer)) { return; } this.timeId.Remove(timer.Time, timer.Id); } public void Run() { long timeNow = TimeHelper.Now(); foreach (long time in this.timeId.Keys) { if (time > timeNow) { break; } timeoutTimer.Enqueue(time); } while (timeoutTimer.Count > 0) { long key = timeoutTimer.Dequeue(); List timeOutId = this.timeId[key]; foreach (ObjectId id in timeOutId) { Timer timer; if (!this.timers.TryGetValue(id, out timer)) { continue; } this.Remove(id); World.Instance.GetComponent>() .Run(timer.CallbackId, timer.Env); } } } } }