Enhance MultipliedObjectManager with robust error handling and reference management
This commit is contained in:
@@ -328,14 +328,39 @@ namespace TerraTech {
|
|||||||
private readonly Action<MultipliedObject<T>> _configureObject;
|
private readonly Action<MultipliedObject<T>> _configureObject;
|
||||||
|
|
||||||
public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) {
|
public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) {
|
||||||
|
if (configureObject == null)
|
||||||
|
throw new ArgumentNullException("configureObject");
|
||||||
|
|
||||||
_configureObject = configureObject;
|
_configureObject = configureObject;
|
||||||
_managedObjects = new Dictionary<T, MultipliedObject<T>>();
|
_managedObjects = new Dictionary<T, MultipliedObject<T>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SafeRemove(T instance) {
|
||||||
|
if (instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
_managedObjects.Remove(instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error removing instance from _managedObjects: {0}", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void OnObjectAttached(T instance) {
|
public void OnObjectAttached(T instance) {
|
||||||
if (!_managedObjects.ContainsKey(instance)) {
|
if (Main.debug.Value)
|
||||||
if (Main.debug.Value)
|
Console.WriteLine("{0}.OnAttached", typeof(T).Name);
|
||||||
Console.WriteLine("{0}.OnAttached", typeof(T).Name);
|
|
||||||
|
if (instance == null) {
|
||||||
|
Console.WriteLine("Attempted to attach null instance");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (_managedObjects.ContainsKey(instance)) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
Console.WriteLine("{0} already managed, skipping", typeof(T).Name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var multipliedObject = new MultipliedObject<T>(instance);
|
var multipliedObject = new MultipliedObject<T>(instance);
|
||||||
_configureObject(multipliedObject);
|
_configureObject(multipliedObject);
|
||||||
@@ -345,43 +370,84 @@ namespace TerraTech {
|
|||||||
|
|
||||||
ApplyTo(instance);
|
ApplyTo(instance);
|
||||||
multipliedObject.LogValues("Patched");
|
multipliedObject.LogValues("Patched");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error in OnObjectAttached: {0}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnObjectDetached(T instance) {
|
public void OnObjectDetached(T instance) {
|
||||||
MultipliedObject<T> multipliedObject;
|
if (Main.debug.Value)
|
||||||
if (_managedObjects.TryGetValue(instance, out multipliedObject)) {
|
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
|
||||||
if (Main.debug.Value) {
|
if (instance == null) {
|
||||||
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
|
Console.WriteLine("Attempted to detach null instance");
|
||||||
multipliedObject.LogValues("Restoring");
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RestoreTo(instance);
|
try {
|
||||||
multipliedObject.LogValues("Restored");
|
MultipliedObject<T> multipliedObject;
|
||||||
_managedObjects.Remove(instance);
|
if (_managedObjects.TryGetValue(instance, out multipliedObject)) {
|
||||||
|
if (Main.debug.Value)
|
||||||
|
multipliedObject.LogValues("Restoring");
|
||||||
|
|
||||||
|
try {
|
||||||
|
RestoreTo(instance);
|
||||||
|
multipliedObject.LogValues("Restored");
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error restoring values: {0}", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeRemove(instance);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error in OnObjectDetached: {0}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyAll(IEnumerable<string> fieldNames = null) {
|
public void ApplyAll(IEnumerable<string> fieldNames = null) {
|
||||||
if (Main.debug.Value)
|
if (Main.debug.Value)
|
||||||
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
|
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
|
||||||
foreach (var instance in _managedObjects.Keys
|
|
||||||
.ToList()) { // ToList to avoid modification during enumeration
|
// Make a copy of the keys to avoid modification during enumeration
|
||||||
RestoreTo(instance, fieldNames);
|
var instances = _managedObjects.Keys.ToList();
|
||||||
ApplyTo(instance, fieldNames);
|
|
||||||
|
foreach (var instance in instances) {
|
||||||
|
try {
|
||||||
|
RestoreTo(instance, fieldNames);
|
||||||
|
ApplyTo(instance, fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error applying to instance: {0}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyTo(T instance, IEnumerable<string> fieldNames = null) {
|
public void ApplyTo(T instance, IEnumerable<string> fieldNames = null) {
|
||||||
MultipliedObject<T> obj;
|
if (Main.debug.Value)
|
||||||
if (_managedObjects.TryGetValue(instance, out obj))
|
Console.WriteLine("Applying {0}", typeof(T).Name);
|
||||||
obj.ApplyTo(fieldNames);
|
if (instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MultipliedObject<T> obj;
|
||||||
|
if (_managedObjects.TryGetValue(instance, out obj))
|
||||||
|
obj.ApplyTo(fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error in ApplyTo: {0}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RestoreTo(T instance, IEnumerable<string> fieldNames = null) {
|
public void RestoreTo(T instance, IEnumerable<string> fieldNames = null) {
|
||||||
MultipliedObject<T> obj;
|
if (Main.debug.Value)
|
||||||
if (_managedObjects.TryGetValue(instance, out obj))
|
Console.WriteLine("Restoring {0}", typeof(T).Name);
|
||||||
obj.RestoreTo(fieldNames);
|
if (instance == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MultipliedObject<T> obj;
|
||||||
|
if (_managedObjects.TryGetValue(instance, out obj))
|
||||||
|
obj.RestoreTo(fieldNames);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Console.WriteLine(String.Format("Error in RestoreTo: {0}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user