diff --git a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs index 2e2a629..497ed27 100644 --- a/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs +++ b/Projects/TerraTech/TerraTech/ObjectFieldMultiplier.cs @@ -328,14 +328,39 @@ namespace TerraTech { private readonly Action> _configureObject; public MultipliedObjectManager(Action> configureObject) { + if (configureObject == null) + throw new ArgumentNullException("configureObject"); + _configureObject = configureObject; _managedObjects = new Dictionary>(); } + 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(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 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 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 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 fieldNames = null) { - MultipliedObject 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 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 fieldNames = null) { - MultipliedObject 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 obj; + if (_managedObjects.TryGetValue(instance, out obj)) + obj.RestoreTo(fieldNames); + } catch (Exception e) { + Console.WriteLine(String.Format("Error in RestoreTo: {0}", e)); + } } } }