Enhance MultipliedObjectManager with robust error handling and reference management

This commit is contained in:
2025-02-24 10:27:52 +01:00
parent 622094fbe9
commit 91e2bf4b61

View File

@@ -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));
}
} }
} }
} }