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,15 +328,40 @@ 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 (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);
multipliedObject.CaptureFrom();
@@ -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) {
if (Main.debug.Value)
Console.WriteLine("{0}.OnDetaching", typeof(T).Name);
multipliedObject.LogValues("Restoring");
if (instance == null) {
Console.WriteLine("Attempted to detach null instance");
return;
}
try {
MultipliedObject<T> multipliedObject;
if (_managedObjects.TryGetValue(instance, out multipliedObject)) {
if (Main.debug.Value)
multipliedObject.LogValues("Restoring");
try {
RestoreTo(instance);
multipliedObject.LogValues("Restored");
_managedObjects.Remove(instance);
} 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
// 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) {
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) {
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));
}
}
}
}