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;
|
||||
|
||||
public MultipliedObjectManager(Action<MultipliedObject<T>> configureObject) {
|
||||
if (configureObject == null)
|
||||
throw new ArgumentNullException("configureObject");
|
||||
|
||||
_configureObject = configureObject;
|
||||
_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) {
|
||||
if (!_managedObjects.ContainsKey(instance)) {
|
||||
if (Main.debug.Value)
|
||||
Console.WriteLine("{0}.OnAttached", typeof(T).Name);
|
||||
if (Main.debug.Value)
|
||||
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);
|
||||
_configureObject(multipliedObject);
|
||||
@@ -345,43 +370,84 @@ namespace TerraTech {
|
||||
|
||||
ApplyTo(instance);
|
||||
multipliedObject.LogValues("Patched");
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine(String.Format("Error in OnObjectAttached: {0}", e));
|
||||
}
|
||||
}
|
||||
|
||||
public void OnObjectDetached(T instance) {
|
||||
MultipliedObject<T> multipliedObject;
|
||||
if (_managedObjects.TryGetValue(instance, out multipliedObject)) {
|
||||
if (Main.debug.Value) {
|
||||
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
|
||||
multipliedObject.LogValues("Restoring");
|
||||
}
|
||||
if (Main.debug.Value)
|
||||
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
|
||||
if (instance == null) {
|
||||
Console.WriteLine("Attempted to detach null instance");
|
||||
return;
|
||||
}
|
||||
|
||||
RestoreTo(instance);
|
||||
multipliedObject.LogValues("Restored");
|
||||
_managedObjects.Remove(instance);
|
||||
try {
|
||||
MultipliedObject<T> multipliedObject;
|
||||
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) {
|
||||
if (Main.debug.Value)
|
||||
Console.WriteLine("Modifying {0} {1}", _managedObjects.Count, typeof(T).Name);
|
||||
foreach (var instance in _managedObjects.Keys
|
||||
.ToList()) { // ToList to avoid modification during enumeration
|
||||
RestoreTo(instance, fieldNames);
|
||||
ApplyTo(instance, fieldNames);
|
||||
|
||||
// Make a copy of the keys to avoid modification during enumeration
|
||||
var instances = _managedObjects.Keys.ToList();
|
||||
|
||||
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) {
|
||||
MultipliedObject<T> obj;
|
||||
if (_managedObjects.TryGetValue(instance, out obj))
|
||||
obj.ApplyTo(fieldNames);
|
||||
if (Main.debug.Value)
|
||||
Console.WriteLine("Applying {0}", typeof(T).Name);
|
||||
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) {
|
||||
MultipliedObject<T> obj;
|
||||
if (_managedObjects.TryGetValue(instance, out obj))
|
||||
obj.RestoreTo(fieldNames);
|
||||
if (Main.debug.Value)
|
||||
Console.WriteLine("Restoring {0}", typeof(T).Name);
|
||||
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