static void VerifyMetaResourceClone(MetaResourceBase metaResource) { if (metaResource == null) { return; } VerifyMetaResourceClone(metaResource, (MetaResourceBase)metaResource.Clone()); }
/// <summary> /// Temporary acquire of an object which does not need to be Released /// The object can only be guaranteed to be valid until the next Prune /// </summary> public T Peek <T>(MetaResourceBase metaResource) where T : class { if (metaResource == null) { return(default(T)); } OnPeek(metaResource); VerifyMetaResource(metaResource); // This is a small optimization, just see if the last acquired object was the same as this one, // in that case return it. Turns out often around half the acquires can be handled like this if (Object.Equals(lastAcquiredMetaResource, metaResource)) { lastAcquiredResource.LastAcquired = pruneK; return((T)lastAcquiredResource.Object); } var key = new Common.Tuple <MetaResourceBase, Type>(metaResource, typeof(T)); Resource o = null; #if THREAD_SAFE_CONTENT lock (lockObject) #endif if (contentByMetaResourceAndType.TryGetValue(key, out o)) { o.LastAcquired = pruneK; key.First = (MetaResourceBase)metaResource.Clone(); lastAcquiredMetaResource = key; lastAcquiredResource = o; return((T)o.Object); } T ob; if (resetting) { ob = ResetAcquire <T>(metaResource); } else { ob = Acquire <T>(metaResource); } Release(ob); return(ob); }
T ResetAcquire <T>(MetaResourceBase metaResource) where T : class { if (metaResource == null) { return(default(T)); } var key = new Common.Tuple <MetaResourceBase, Type>((MetaResourceBase)metaResource.Clone(), typeof(T)); Resource o; // This object has already been reset if (resetResourcesById.TryGetValue(key, out o)) { return((T)o.Object); } // This resource doesn't exists yet, create it bool ok = false; #if THREAD_SAFE_CONTENT lock (lockObject) #endif ok = contentByMetaResourceAndType.TryGetValue(key, out o); if (!ok) { return(InnerAcquire <T>(metaResource)); } var mapperKey = new Common.Tuple <Type, Type>(o.MetaResource.GetType(), o.Object.GetType()); o.Object = mappers[mapperKey].Do(MetaResourceDo.ResetDevice, o.MetaResource, this, o.Object); OnResetAcquire(o.MetaResource, o.Object); #if THREAD_SAFE_CONTENT lock (lockObject) #endif contentByResource.Add(o.Object, o); resetResourcesById.Add(key, o); return((T)o.Object); }
T InnerAcquire <T>(MetaResourceBase metaResource) where T : class { if (metaResource == null) { return(default(T)); } var key = new Common.Tuple <MetaResourceBase, Type>(metaResource, typeof(T)); // This is a small optimization, just see if the last acquired object was the same as this one, // in that case return it. Turns out often around half the acquires can be handled like this if (Object.Equals(lastAcquiredMetaResource, metaResource)) { OnAcquire(metaResource); lastAcquiredResource.References++; lastAcquiredResource.LastAcquired = pruneK; return((T)lastAcquiredResource.Object); } Resource o = null; #if THREAD_SAFE_CONTENT lock (lockObject) { #endif if (contentByMetaResourceAndType.TryGetValue(key, out o)) { OnAcquire(metaResource); o.References++; o.LastAcquired = pruneK; key.First = (MetaResourceBase)metaResource.Clone(); lastAcquiredMetaResource = key; lastAcquiredResource = o; return((T)o.Object); } key.First = (MetaResourceBase)metaResource.Clone(); #if DEBUG_CONTENT if (key.First.GetHashCode() != metaResource.GetHashCode()) { throw new Exception("Error in meta resource Clone or GetHashCode"); } if (!Object.Equals(key.First, metaResource)) { string diffs = ""; key.First.ReportEqualsDiffs(metaResource, (d) => diffs += "\n" + d); throw new Exception("Error in meta resource Clone or Equals\n\nDiffs:\n" + diffs); } #endif var mapperKey = new Common.Tuple <Type, Type>(metaResource.GetType(), typeof(T)); object ob = mappers[mapperKey].Do(MetaResourceDo.Construct, metaResource, this, null); OnConstruct(metaResource, ob); if (ob == null) { lastAcquiredMetaResource = new Common.Tuple <MetaResourceBase, Type>(null, null); lastAcquiredResource = null; return((T)ob); } #if DEBUG_CONTENT if (key.First.GetHashCode() != metaResource.GetHashCode()) { throw new Exception("MetaResource was changed during construction (No longer the same hash code)"); } if (!Object.Equals(key.First, metaResource)) { throw new Exception("MetaResource was changed during construction (No longer Equals)"); } #endif #if THREAD_SAFE_CONTENT //lock (lockObject) //{ #endif OnAcquire(metaResource); contentByMetaResourceAndType.Add(key, o = new Resource { MetaResource = metaResource, Object = ob, References = 1, LastAcquired = pruneK, FirstAcquired = pruneK }); #if DEBUG_CONTENT Resource debugR; if (contentByResource.TryGetValue(o.Object, out debugR)) { throw new Exception("Content by resource old: " + debugR.MetaResource + " new: " + o.MetaResource); } #endif contentByResource.Add(o.Object, o); #if THREAD_SAFE_CONTENT } #endif lastAcquiredMetaResource = key; lastAcquiredResource = o; return((T)o.Object); }