void OnPeek(MetaResourceBase resource) { #if LOG_CONTENT_ACQUIRE log.Write("p " + //(ob != null ? ob.GetHashCode().ToString() : "null").PadRight(14) + " " + resource); #endif }
void OnResetAcquire(MetaResourceBase resource, object ob) { #if LOG_CONTENT log.Write("r+ " + (ob != null ? ob.GetHashCode().ToString() : "null").PadRight(14) + " " + resource); #endif }
static void VerifyMetaResourceType(MetaResourceBase metaResource) { if (metaResource == null) { return; } VerifyMetaResourceType(metaResource.GetType(), (error) => { throw new Exception(error); }); }
static void VerifyMetaResourceClone(MetaResourceBase metaResource) { if (metaResource == null) { return; } VerifyMetaResourceClone(metaResource, (MetaResourceBase)metaResource.Clone()); }
void OnDestroy(MetaResourceBase resource, object ob) { #if LOG_CONTENT log.Write("- " + (ob != null ? ob.GetHashCode().ToString() : "null").PadRight(14) + " " + resource); #endif #if CONTENT_STATISTICS pcNumberOfObjects.Decrement(); #endif }
void OnAcquire(MetaResourceBase resource) { #if LOG_CONTENT_ACQUIRE log.Write("a " + //(ob != null ? ob.GetHashCode().ToString() : "null").PadRight(14) + " " + resource); #endif #if CONTENT_STATISTICS pcTotalNumberOfReferences.Increment(); #endif }
void OnConstruct(MetaResourceBase resource, object ob) { #if LOG_CONTENT log.Write("+ " + (ob != null ? ob.GetHashCode().ToString() : "null").PadRight(14) + " " + (ob != null ? ob.GetType().Name : "null").PadRight(14) + " " + resource); #endif #if CONTENT_STATISTICS pcNumberOfObjects.Increment(); #endif }
/// <summary> /// Returns the requested resource, specified by the MetaResource. The resource /// has to be Released once it's no longer used. /// </summary> public T Acquire <T>(MetaResourceBase metaResource) where T : class { VerifyMetaResource(metaResource); if (resetting) { return(ResetAcquire <T>(metaResource)); } else { return(InnerAcquire <T>(metaResource)); } }
/// <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); }
static void VerifyMetaResourceClone(MetaResourceBase original, MetaResourceBase copy) { bool equals = Object.Equals(original, copy); foreach (var v in original.GetType().GetProperties()) { if (typeof(MetaResourceBase).IsAssignableFrom(v.PropertyType)) { var o = (MetaResourceBase)((MetaResourceBase)v.GetValue(original, null)); if (o != null) { var c = (MetaResourceBase)o.Clone(); VerifyMetaResourceClone(o, c); } } } if (!equals) { throw new Exception(original + " does not equal " + copy); } }
static void VerifyMetaResource(MetaResourceBase metaResource) { VerifyMetaResourceType(metaResource); VerifyMetaResourceClone(metaResource); }
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); }