public bool Add(T key, ICacheable cacheable) { lock (syncRoot) { if (cacheable == null) { throw new ArgumentNullException("cacheable"); } CachableData dummy; if (sorted.TryGetValue(key, out dummy)) { return(false); } // Cacheable was cached, must throw exception if already cached. cacheable.Cached(); // Create data. CachableData data = new CachableData(); data.Data = cacheable; data.Score = initialScore; data.EvalData = new object[evaluators.Length]; for (int i = 0; i < evaluators.Length; i++) { data.EvalData[i] = evaluators[i].Data; } // Add touched event. data.Data.OnTouch += new Action <ICacheable>(delegate(ICacheable unused) { lock (syncRoot) { // Perform the touch. for (int j = 0; j < evaluators.Length; j++) { data.Score = evaluators[j].Touch(data.EvalData[j], data.Score); } // Touching certainly ensures at least 0.0f value. data.Score = Math.MathHelper.Max(0.0f, data.Score); data.Score = Math.MathHelper.Min(maxScore, data.Score); } }); // Resource is created in touched state, no need to re-touch. This // method may throw if key already exists, but we already prechecked for uniquness. sorted.Add(key, data); return(true); } }