From 9ed8a0b7bd140e8056f69da9516efa1b2388e4f4 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 18 May 2024 14:58:41 +0200 Subject: [PATCH] Mejorado el sistema de SaveStateObjetosSimulables y trabajando en el usercontrol Descarte --- MainViewModel.cs | 79 +++++++++--- MainWindow.xaml.cs | 8 ++ ObjetosSim/UserControlFactory.cs | 73 +++++------ ObjetosSim/osBase.cs | 13 +- ObjetosSim/ucBasicExample.xaml.cs | 11 ++ ObjetosSim/ucBotella.xaml.cs | 20 ++- ObjetosSim/ucBoton.xaml.cs | 13 +- ObjetosSim/ucDescarte.xaml | 37 ++++++ ObjetosSim/ucDescarte.xaml.cs | 180 +++++++++++++++++++++++++++ ObjetosSim/ucFiller.xaml.cs | 50 ++++++-- ObjetosSim/ucGuia.xaml.cs | 15 ++- ObjetosSim/ucSensTemperatura.xaml.cs | 10 ++ ObjetosSim/ucTanque.xaml.cs | 10 ++ ObjetosSim/ucTransporteGuias.xaml.cs | 19 ++- ObjetosSim/ucTransporteTTop.xaml.cs | 13 +- ObjetosSim/ucVMmotorSim.xaml.cs | 11 +- Simulacion/FPhysics.cs | 118 ++++++++++++++---- 17 files changed, 575 insertions(+), 105 deletions(-) create mode 100644 ObjetosSim/ucDescarte.xaml create mode 100644 ObjetosSim/ucDescarte.xaml.cs diff --git a/MainViewModel.cs b/MainViewModel.cs index c54036d..132d3e9 100644 --- a/MainViewModel.cs +++ b/MainViewModel.cs @@ -249,19 +249,23 @@ namespace CtrEditor { if (parameter is TipoSimulable tipoSimulable) { - CrearObjetoSimulable(tipoSimulable.Tipo); + CrearObjetoSimulableEnCentroCanvas(tipoSimulable.Tipo); } } - public void CrearObjetoSimulable(Type tipoSimulable) + public void CrearObjetoSimulableEnCentroCanvas(Type tipoSimulable) + { + var CentroCanvas = MainWindow.ObtenerCentroCanvasMeters(); + CrearObjetoSimulable(tipoSimulable,CentroCanvas.X,CentroCanvas.Y); + } + + public osBase CrearObjetoSimulable(Type tipoSimulable,float Left,float Top) { // Crear una nueva instancia del osBase correspondiente osBase? NuevoOsBase = UserControlFactory.GetInstanceForType(tipoSimulable); - var CentroCanvas = MainWindow.ObtenerCentroCanvasPixels(); - - NuevoOsBase.Left = CentroCanvas.X; - NuevoOsBase.Top = CentroCanvas.Y; + NuevoOsBase.Left = Left; + NuevoOsBase.Top = Top; if (NuevoOsBase != null) { @@ -269,6 +273,7 @@ namespace CtrEditor // Añadir el nuevo osBase a la colección de objetos simulables ObjetosSimulables.Add(NuevoOsBase); } + return NuevoOsBase; } // Crear UserControl desde osBase : Nuevo o desde Deserealizacion @@ -292,6 +297,16 @@ namespace CtrEditor return false; } + public void RemoverObjetoSimulable(osBase osObjeto) + { + if (osObjeto != null && ObjetosSimulables.Contains(osObjeto)) + { + ObjetosSimulables.Remove(osObjeto); + if (osObjeto.VisualRepresentation != null) + MainWindow.EliminarUserControlDelCanvas(osObjeto.VisualRepresentation); + } + } + private void InitializeTipoSimulableList() { var baseType = typeof(osBase); @@ -340,8 +355,15 @@ namespace CtrEditor simulationManager.Step(); - foreach (var objetoSimulable in ObjetosSimulables) - objetoSimulable.UpdateControl((int)elapsedMilliseconds); + var objetosSimulablesCopy = new List(ObjetosSimulables); + + foreach (var objetoSimulable in objetosSimulablesCopy) + { + if (!objetoSimulable.RemoverDesdeSimulacion) + objetoSimulable.UpdateControl((int)elapsedMilliseconds); + else + RemoverObjetoSimulable(objetoSimulable); + } } @@ -393,8 +415,6 @@ namespace CtrEditor public void Save() { SaveStateObjetosSimulables(); - ImageSelected?.Invoke(this, datosDeTrabajo.Imagenes[_selectedImage]); // Dispara el evento con la nueva ruta de imagen - LoadStateObjetosSimulables(); } public void SaveStateObjetosSimulables() @@ -403,19 +423,33 @@ namespace CtrEditor { StopSimulation(); PLCViewModel.Disconnect(); + + // Crear copias temporales de las propiedades que serán anuladas + var tempVisualRepresentations = new Dictionary(); + var tempSimulationManagers = new Dictionary(); + var tempMainViewModels = new Dictionary(); + + foreach (var obj in ObjetosSimulables) + { + // Guardar referencias temporales + tempVisualRepresentations[obj] = obj.VisualRepresentation; + tempSimulationManagers[obj] = obj.simulationManager; + tempMainViewModels[obj] = obj._mainViewModel; + + // Anular propiedades para la serialización + obj.VisualRepresentation = null; + obj.simulationManager = null; + obj._mainViewModel = null; + } + var settings = new JsonSerializerSettings { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore, TypeNameHandling = TypeNameHandling.Auto }; - foreach (var obj in ObjetosSimulables) - { - obj.VisualRepresentation = null; - obj.simulationManager = null; - obj._mainViewModel = null; - } - // Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter + + // Crear un objeto que incluya tanto los ObjetosSimulables como el UnitConverter y PLC_ConnectionData var dataToSerialize = new SimulationData { ObjetosSimulables = ObjetosSimulables, @@ -423,11 +457,22 @@ namespace CtrEditor PLC_ConnectionData = PLCViewModel }; + // Serializar var serializedData = JsonConvert.SerializeObject(dataToSerialize, settings); File.WriteAllText(datosDeTrabajo.ObtenerPathImagenConExtension(_selectedImage, ".json"), serializedData); + + // Restaurar las propiedades originales de los objetos + foreach (var obj in ObjetosSimulables) + { + obj.VisualRepresentation = tempVisualRepresentations[obj]; + obj.simulationManager = tempSimulationManagers[obj]; + obj._mainViewModel = tempMainViewModels[obj]; + } } } + + public void LoadStateObjetosSimulables() { try diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 6b369a6..cb76df7 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -118,6 +118,14 @@ namespace CtrEditor } } + public void EliminarUserControlDelCanvas(UserControl userControl) + { + if (ImagenEnTrabajoCanvas.Children.Contains(userControl)) + { + ImagenEnTrabajoCanvas.Children.Remove(userControl); + } + } + private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { if (!_isDrawingCanvas) diff --git a/ObjetosSim/UserControlFactory.cs b/ObjetosSim/UserControlFactory.cs index f792f63..0d48e62 100644 --- a/ObjetosSim/UserControlFactory.cs +++ b/ObjetosSim/UserControlFactory.cs @@ -6,6 +6,7 @@ using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using CtrEditor.Simulacion; +using System.Reflection; namespace CtrEditor.ObjetosSim { @@ -13,60 +14,42 @@ namespace CtrEditor.ObjetosSim { public static UserControl? GetControlForType(Type tipoObjeto) { - if (tipoObjeto == typeof(osBotella)) - return new ucBotella(); - if (tipoObjeto == typeof(osTransporteTTop)) - return new ucTransporteTTop(); - if (tipoObjeto == typeof(osGuia)) - return new ucGuia(); - if (tipoObjeto == typeof(osTransporteGuias)) - return new ucTransporteGuias(); - //if (tipoObjeto == typeof(osTransporteCurva)) - // return new ucTransporteCurva(); - if (tipoObjeto == typeof(osVMmotorSim )) - return new ucVMmotorSim(); - if (tipoObjeto == typeof(osBoton)) - return new ucBoton(); - if (tipoObjeto == typeof(osTanque)) - return new ucTanque(); - if (tipoObjeto == typeof(osSensTemperatura)) - return new ucSensTemperatura(); - if (tipoObjeto == typeof(osFiller)) - return new ucFiller(); + // Obtener el nombre del tipo de objeto + string typeName = tipoObjeto.Name; + // Cambiar las primeras dos letras de 'os' a 'uc' + if (typeName.StartsWith("os")) + { + string newTypeName = "uc" + typeName.Substring(2); - // Puedes añadir más condiciones para otros tipos + // Obtener el ensamblado donde se encuentra el tipo UserControl + Assembly assembly = Assembly.GetExecutingAssembly(); + + // Buscar el tipo en los ensamblados cargados + Type? controlType = AppDomain.CurrentDomain.GetAssemblies() + .SelectMany(a => a.GetTypes()) + .FirstOrDefault(t => t.Name == newTypeName); + + if (controlType != null && typeof(UserControl).IsAssignableFrom(controlType)) + { + // Crear una instancia del tipo encontrado + return (UserControl?)Activator.CreateInstance(controlType); + } + } return null; } public static osBase? GetInstanceForType(Type tipoObjeto) { - if (tipoObjeto == typeof(osBotella)) - return new osBotella(); - if (tipoObjeto == typeof(osTransporteTTop)) - return new osTransporteTTop(); - if (tipoObjeto == typeof(osGuia)) - return new osGuia(); - if (tipoObjeto == typeof(osTransporteGuias)) - return new osTransporteGuias(); - //if (tipoObjeto == typeof(osTransporteCurva)) - // return new osTransporteCurva(); - if (tipoObjeto == typeof(osVMmotorSim)) - return new osVMmotorSim(); - if (tipoObjeto == typeof(osBoton)) - return new osBoton(); - if (tipoObjeto == typeof(osTanque)) - return new osTanque(); - if (tipoObjeto == typeof(osSensTemperatura)) - return new osSensTemperatura(); - if (tipoObjeto == typeof(osFiller)) - return new osFiller(); + // Verifica si el tipo pasado es un subtipo de osBase + if (!typeof(osBase).IsAssignableFrom(tipoObjeto)) + { + throw new ArgumentException("El tipo pasado no es un subtipo de osBase", nameof(tipoObjeto)); + } - - // Puedes añadir más condiciones para otros tipos - - return null; + // Crear una instancia del tipo especificado + return (osBase?)Activator.CreateInstance(tipoObjeto); } public static osBase? CreateInstanceAndPopulate(Type tipoObjeto, string jsonString) diff --git a/ObjetosSim/osBase.cs b/ObjetosSim/osBase.cs index 9d86fe7..b9357c8 100644 --- a/ObjetosSim/osBase.cs +++ b/ObjetosSim/osBase.cs @@ -27,7 +27,7 @@ namespace CtrEditor.ObjetosSim public interface IosBase { - string Nombre { get; } + string Nombre { get; } void UpdateControl(int elapsedMilliseconds); } @@ -49,6 +49,8 @@ namespace CtrEditor.ObjetosSim public abstract float Top { get; set; } public bool Inicializado = false; + public bool AutoCreated = false; + public bool RemoverDesdeSimulacion = false; // La simulacion indica que se debe remover [JsonIgnore] protected UserControl? _visualRepresentation = null; @@ -60,6 +62,7 @@ namespace CtrEditor.ObjetosSim public abstract void UpdateGeometryStep(); public abstract void UpdatePLC(PLCModel plc, int elapsedMilliseconds); public abstract void ucLoaded(); + public abstract void ucUnLoaded(); [JsonIgnore] public MainViewModel _mainViewModel; @@ -222,18 +225,18 @@ namespace CtrEditor.ObjetosSim return new Vector2((topLeft.X + bottomRight.X) / 2, (topLeft.Y + bottomRight.Y) / 2); } - public void UpdateRectangle(simRectangle simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + public void UpdateRectangle(simTransporte simRect, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { if (simRect != null) simRect.Create(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } - public simRectangle AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) + public simTransporte AddRectangle(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect, float Alto, float Ancho, float Angulo) { return simulationManager.AddRectangle(Ancho, Alto, GetRectangleCenter(wpfRect), Angulo); } - public void UpdateOrCreateLine(simLine simGuia, System.Windows.Shapes.Rectangle wpfRect) + public void UpdateOrCreateLine(simGuia simGuia, System.Windows.Shapes.Rectangle wpfRect) { if (simGuia != null) { @@ -244,7 +247,7 @@ namespace CtrEditor.ObjetosSim } } - public simLine AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect) + public simGuia AddLine(SimulationManagerFP simulationManager, System.Windows.Shapes.Rectangle wpfRect) { var coords = GetCenterLineVectors(wpfRect); return simulationManager.AddLine(coords.Start, coords.End); diff --git a/ObjetosSim/ucBasicExample.xaml.cs b/ObjetosSim/ucBasicExample.xaml.cs index da10b1b..fd1709b 100644 --- a/ObjetosSim/ucBasicExample.xaml.cs +++ b/ObjetosSim/ucBasicExample.xaml.cs @@ -122,6 +122,12 @@ namespace CtrEditor.ObjetosSim // crear el objeto de simulacion ActualizarLeftTop(); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } + } @@ -133,11 +139,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osBasicExample datos) { diff --git a/ObjetosSim/ucBotella.xaml.cs b/ObjetosSim/ucBotella.xaml.cs index 189c00f..50d16b8 100644 --- a/ObjetosSim/ucBotella.xaml.cs +++ b/ObjetosSim/ucBotella.xaml.cs @@ -31,7 +31,7 @@ namespace CtrEditor.ObjetosSim private float _mass; private Vector2 _centro = new Vector2(); // Centro private string _nombre = "Botella"; - private simCircle Simulacion_Botella; + private simBotella Simulacion_Botella; // Otros datos y métodos relevantes para la simulación @@ -63,6 +63,7 @@ namespace CtrEditor.ObjetosSim { _centro.X = value+Diametro/2; CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(CenterX)); OnPropertyChanged(nameof(Left)); } } @@ -73,6 +74,7 @@ namespace CtrEditor.ObjetosSim { _centro.Y = value + Diametro / 2; CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(CenterY)); OnPropertyChanged(nameof(Top)); } } @@ -145,7 +147,11 @@ namespace CtrEditor.ObjetosSim { CenterX = Simulacion_Botella.CenterX; CenterY = Simulacion_Botella.CenterY; + + if (Simulacion_Botella.Descartar) // Ha sido marcada para remover + RemoverDesdeSimulacion = true; } + public override void ucLoaded() { // El UserControl ya se ha cargado y podemos obtener las coordenadas para @@ -153,6 +159,12 @@ namespace CtrEditor.ObjetosSim ActualizarLeftTop(); Simulacion_Botella = simulationManager.AddCircle(Diametro, _centro, Mass); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(Simulacion_Botella); + } } @@ -164,11 +176,17 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } + public void Resize(float width, float height) { } public void Move(float LeftPixels, float TopPixels) { diff --git a/ObjetosSim/ucBoton.xaml.cs b/ObjetosSim/ucBoton.xaml.cs index 06f0870..2da959f 100644 --- a/ObjetosSim/ucBoton.xaml.cs +++ b/ObjetosSim/ucBoton.xaml.cs @@ -164,6 +164,11 @@ namespace CtrEditor.ObjetosSim // crear el objeto de simulacion ActualizarLeftTop(); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } } @@ -174,14 +179,18 @@ namespace CtrEditor.ObjetosSim public ucBoton() { InitializeComponent(); + this.DataContextChanged += OnDataContextChanged; this.Loaded += OnLoaded; - this.DataContextChanged += OnDataContextChanged; + this.Unloaded += OnUnloaded; } - private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { diff --git a/ObjetosSim/ucDescarte.xaml b/ObjetosSim/ucDescarte.xaml new file mode 100644 index 0000000..eaf43ba --- /dev/null +++ b/ObjetosSim/ucDescarte.xaml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + diff --git a/ObjetosSim/ucDescarte.xaml.cs b/ObjetosSim/ucDescarte.xaml.cs new file mode 100644 index 0000000..883172d --- /dev/null +++ b/ObjetosSim/ucDescarte.xaml.cs @@ -0,0 +1,180 @@ +using CtrEditor.Convertidores; +using CtrEditor.Siemens; +using CtrEditor.Simulacion; +using System.Windows; +using System.Windows.Controls; +using Microsoft.Xna.Framework; +namespace CtrEditor.ObjetosSim +{ + /// + /// Interaction logic for ucDescarte.xaml + /// + public class osDescarte : osBase + { + // Otros datos y métodos relevantes para la simulación + + private string _nombre = "Descarte"; + private float _diametro; + private Vector2 _centro = new Vector2(); // Centro + private simDescarte AreaDeDescarte; + + public override float Left + { + get => _centro.X - Diametro / 2; + set + { + _centro.X = value + Diametro / 2; + CanvasSetLeftinMeter(value); + OnPropertyChanged(nameof(CenterX)); + OnPropertyChanged(nameof(Left)); + } + } + public override float Top + { + get => _centro.Y - Diametro / 2; + set + { + _centro.Y = value + Diametro / 2; + CanvasSetTopinMeter(value); + OnPropertyChanged(nameof(CenterY)); + OnPropertyChanged(nameof(Top)); + } + } + + public float CenterX + { + get => _centro.X; + set + { + _centro.X = value; + CanvasSetLeftinMeter(Left); + OnPropertyChanged(nameof(CenterX)); + OnPropertyChanged(nameof(Left)); + } + } + public float CenterY + { + get => _centro.Y; + set + { + _centro.Y = value; + CanvasSetTopinMeter(Top); + OnPropertyChanged(nameof(CenterY)); + OnPropertyChanged(nameof(Top)); + } + } + + public float Diametro + { + get => _diametro; + set + { + _diametro = value; + AreaDeDescarte?.SetDiameter(Diametro); + OnPropertyChanged(nameof(Diametro)); + } + } + + public override string Nombre + { + get => _nombre; + set + { + if (_nombre != value) + { + _nombre = value; + OnPropertyChanged(nameof(Nombre)); + } + } + } + + private void ActualizarGeometrias() + { + if (AreaDeDescarte != null) + { + AreaDeDescarte.SetDiameter(Diametro); + AreaDeDescarte.SetPosition(CenterX, CenterY); + } + } + + public osDescarte() + { + Diametro = 1f; + } + + public override void UpdateGeometryStart() + { + // Se llama antes de la simulacion + ActualizarGeometrias(); + } + public override void UpdateGeometryStep() + { + } + public override void UpdatePLC(PLCModel plc, int elapsedMilliseconds) + { + } + + public override void UpdateControl(int elapsedMilliseconds) + { + + } + public override void ucLoaded() + { + // El UserControl ya se ha cargado y podemos obtener las coordenadas para + // crear el objeto de simulacion + ActualizarLeftTop(); + AreaDeDescarte = simulationManager.AddDescarte(Diametro, _centro); + } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(AreaDeDescarte); + } + + } + + public partial class ucDescarte : UserControl, IDataContainer + { + public osBase? Datos { get; set; } + + public ucDescarte() + { + InitializeComponent(); + this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; + } + private void OnLoaded(object sender, RoutedEventArgs e) + { + Datos?.ucLoaded(); + } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } + public void Resize(float width, float height) + { + if (Datos is osDescarte datos) + { + datos.Diametro = PixelToMeter.Instance.calc.PixelsToMeters(width); + } + } + public void Move(float LeftPixels, float TopPixels) + { + if (Datos != null) + { + Datos.Left = PixelToMeter.Instance.calc.PixelsToMeters(LeftPixels); + Datos.Top = PixelToMeter.Instance.calc.PixelsToMeters(TopPixels); + } + } + public void Rotate(float Angle) + { + } + public void Highlight(bool State) { } + public int ZIndex() + { + return 10; + } + } + +} diff --git a/ObjetosSim/ucFiller.xaml.cs b/ObjetosSim/ucFiller.xaml.cs index 25ddd32..0460c5a 100644 --- a/ObjetosSim/ucFiller.xaml.cs +++ b/ObjetosSim/ucFiller.xaml.cs @@ -38,7 +38,28 @@ namespace CtrEditor.ObjetosSim private string _tag_consenso; private bool _consenso; private float TiempoRestante; - private List Botellas = new List(); + private float _leftSalida; + private float _topSalida; + private List Botellas = new List(); + + public float OffsetLeftSalida + { + get => _leftSalida; + set + { + _leftSalida = value; + OnPropertyChanged(nameof(OffsetLeftSalida)); + } + } + public float OffsetTopSalida + { + get => _topSalida; + set + { + _topSalida = value; + OnPropertyChanged(nameof(OffsetTopSalida)); + } + } public bool Consenso { @@ -175,19 +196,24 @@ namespace CtrEditor.ObjetosSim public override void UpdateControl(int elapsedMilliseconds) { - if (Consenso && Velocidad_actual_percentual>0) + if (Consenso && Velocidad_actual_percentual > 0) { TiempoRestante -= elapsedMilliseconds / 1000.0f; if (TiempoRestante <= 0) { - TiempoRestante = Botellas_hora * (Velocidad_actual_percentual / 100.0f) / 3600.0f; - var PosSalida = new Vector2(Left, Top); + TiempoRestante = 3600 / (Botellas_hora * (Velocidad_actual_percentual / 100.0f)); - var UltimaBotellla = GetLastElement(Botellas); - if (UltimaBotellla != null && UltimaBotellla.Center != PosSalida) - Botellas.Add(simulationManager.AddCircle(Diametro_botella, PosSalida, 1)); + var UltimaBotellla = GetLastElement(Botellas); + if (UltimaBotellla == null || (UltimaBotellla != null && !(UltimaBotellla.Left == Left && UltimaBotellla.Top == Top))) + { + var Botella = _mainViewModel.CrearObjetoSimulable(typeof(osBotella), Left + OffsetLeftSalida, Top + OffsetTopSalida); + Botella.AutoCreated = true; + Botellas.Add((osBotella)Botella); + } } } + else + TiempoRestante = 0; } public override void ucLoaded() { @@ -195,6 +221,11 @@ namespace CtrEditor.ObjetosSim // crear el objeto de simulacion ActualizarLeftTop(); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } } @@ -206,11 +237,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osFiller datos) diff --git a/ObjetosSim/ucGuia.xaml.cs b/ObjetosSim/ucGuia.xaml.cs index 7ce67f8..bdc1815 100644 --- a/ObjetosSim/ucGuia.xaml.cs +++ b/ObjetosSim/ucGuia.xaml.cs @@ -33,7 +33,7 @@ namespace CtrEditor.ObjetosSim private float _angulo; private string _nombre = "Guia"; - private simLine Simulation_Guia; + private simGuia Simulation_Guia; public override float Left { @@ -131,6 +131,12 @@ namespace CtrEditor.ObjetosSim if (_visualRepresentation is ucGuia uc) Simulation_Guia = AddLine(simulationManager, uc.Guia); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(Simulation_Guia); + } } @@ -143,10 +149,15 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { - Datos?.ucLoaded(); + Datos?.ucLoaded(); + } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); } public void Resize(float width, float height) { diff --git a/ObjetosSim/ucSensTemperatura.xaml.cs b/ObjetosSim/ucSensTemperatura.xaml.cs index 132f78f..d38bcb3 100644 --- a/ObjetosSim/ucSensTemperatura.xaml.cs +++ b/ObjetosSim/ucSensTemperatura.xaml.cs @@ -172,6 +172,11 @@ namespace CtrEditor.ObjetosSim ActualizarLeftTop(); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } } @@ -183,11 +188,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osSensTemperatura datos) diff --git a/ObjetosSim/ucTanque.xaml.cs b/ObjetosSim/ucTanque.xaml.cs index ba7dae9..1a5b362 100644 --- a/ObjetosSim/ucTanque.xaml.cs +++ b/ObjetosSim/ucTanque.xaml.cs @@ -290,6 +290,11 @@ namespace CtrEditor.ObjetosSim ActualizarLeftTop(); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } } @@ -301,11 +306,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osTanque datos) diff --git a/ObjetosSim/ucTransporteGuias.xaml.cs b/ObjetosSim/ucTransporteGuias.xaml.cs index d8186b1..178c615 100644 --- a/ObjetosSim/ucTransporteGuias.xaml.cs +++ b/ObjetosSim/ucTransporteGuias.xaml.cs @@ -43,9 +43,9 @@ namespace CtrEditor.ObjetosSim private osBase _osMotor = null; private string _motor; - private simRectangle? TransporteCentral; - private simLine? Guia_Superior; - private simLine? Guia_Inferior; + private simTransporte? TransporteCentral; + private simGuia? Guia_Superior; + private simGuia? Guia_Inferior; @@ -227,6 +227,14 @@ namespace CtrEditor.ObjetosSim } Motor = Motor; // Forzar la busqueda } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(TransporteCentral); + simulationManager.Remove(Guia_Superior); + simulationManager.Remove(Guia_Inferior); + } } @@ -239,11 +247,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osTransporteGuias datos) diff --git a/ObjetosSim/ucTransporteTTop.xaml.cs b/ObjetosSim/ucTransporteTTop.xaml.cs index 1811a4b..89b8f56 100644 --- a/ObjetosSim/ucTransporteTTop.xaml.cs +++ b/ObjetosSim/ucTransporteTTop.xaml.cs @@ -30,7 +30,7 @@ namespace CtrEditor.ObjetosSim private osBase _osMotor = null; private string _motor; - private simRectangle Simulation_Transporte; + private simTransporte Simulation_Transporte; public string Motor { @@ -168,6 +168,12 @@ namespace CtrEditor.ObjetosSim if (_visualRepresentation is ucTransporteTTop uc) Simulation_Transporte = AddRectangle(simulationManager, uc.Transporte, Alto, Ancho, Angulo); } + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + simulationManager.Remove(Simulation_Transporte); + } } @@ -179,11 +185,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { if (Datos is osTransporteTTop datos) diff --git a/ObjetosSim/ucVMmotorSim.xaml.cs b/ObjetosSim/ucVMmotorSim.xaml.cs index d4acaef..c3f69a4 100644 --- a/ObjetosSim/ucVMmotorSim.xaml.cs +++ b/ObjetosSim/ucVMmotorSim.xaml.cs @@ -201,7 +201,11 @@ namespace CtrEditor.ObjetosSim ActualizarLeftTop(); } - + public override void ucUnLoaded() + { + // El UserControl se esta eliminando + // eliminar el objeto de simulacion + } } public partial class ucVMmotorSim : UserControl, IDataContainer @@ -212,11 +216,16 @@ namespace CtrEditor.ObjetosSim { InitializeComponent(); this.Loaded += OnLoaded; + this.Unloaded += OnUnloaded; } private void OnLoaded(object sender, RoutedEventArgs e) { Datos?.ucLoaded(); } + private void OnUnloaded(object sender, RoutedEventArgs e) + { + Datos?.ucUnLoaded(); + } public void Resize(float width, float height) { } public void Move(float LeftPixels, float TopPixels) { diff --git a/Simulacion/FPhysics.cs b/Simulacion/FPhysics.cs index 8990f67..b769b2d 100644 --- a/Simulacion/FPhysics.cs +++ b/Simulacion/FPhysics.cs @@ -13,16 +13,57 @@ using FarseerPhysics.Common; using System.Windows; using System.Diagnostics; using System.Windows.Documents; +using CtrEditor.ObjetosSim; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace CtrEditor.Simulacion { - public class simRectangle + + public class simDescarte + { + public Body Body { get; private set; } + private float _radius; + public World _world; + + public simDescarte(World world, float diameter, Vector2 position) + { + _world = world; + _radius = diameter / 2; + Create(position); + } + + public void SetPosition(float x, float y) + { + Body.SetTransform(new Vector2(x, y), Body.Rotation); + } + + public void SetDiameter(float diameter) + { + _radius = diameter / 2; + Create(Body.Position); // Recrear el círculo con el nuevo tamaño + } + + public void Create(Vector2 position) + { + if (Body != null) + { + _world.RemoveBody(Body); + } + Body = BodyFactory.CreateCircle(_world, _radius, 1f, position); + + Body.FixtureList[0].IsSensor = true; + Body.BodyType = BodyType.Static; + Body.UserData = this; // Importante para la identificación durante la colisión + } + } + + public class simTransporte { public Body Body { get; private set; } public float Speed { get; set; } // Velocidad para efectos de cinta transportadora public World _world; - public simRectangle(World world, float width, float height, Vector2 position, float angle = 0) + public simTransporte(World world, float width, float height, Vector2 position, float angle = 0) { _world = world; Create(width, height, position, angle); @@ -66,12 +107,12 @@ namespace CtrEditor.Simulacion } } - public class simLine + public class simGuia { public Body Body { get; private set; } public World _world; - public simLine(World world, Vector2 start, Vector2 end) + public simGuia(World world, Vector2 start, Vector2 end) { _world = world; Create(start, end); @@ -94,14 +135,15 @@ namespace CtrEditor.Simulacion } } - public class simCircle + public class simBotella { public Body Body { get; private set; } public World _world; private float _radius; private float _mass; + public bool Descartar = false; - public simCircle(World world, float diameter, Vector2 position, float mass) + public simBotella(World world, float diameter, Vector2 position, float mass) { _world = world; _radius = diameter / 2; @@ -180,9 +222,13 @@ namespace CtrEditor.Simulacion private bool HandleCollision(Fixture fixtureA, Fixture fixtureB, FarseerPhysics.Dynamics.Contacts.Contact contact) { - if (fixtureB.Body.UserData is simRectangle) + if (fixtureB.Body.UserData is simDescarte) { - simRectangle conveyor = fixtureB.Body.UserData as simRectangle; + Descartar = true; + return true; + } else if (fixtureB.Body.UserData is simTransporte) + { + simTransporte conveyor = fixtureB.Body.UserData as simTransporte; CircleShape circleShape = fixtureA.Shape as CircleShape; PolygonShape polygonShape = fixtureB.Shape as PolygonShape; @@ -219,7 +265,7 @@ namespace CtrEditor.Simulacion // Aquí puedes restablecer cualquier estado si es necesario al separarse de un simRectangle } - private void ApplyConveyorEffect(simRectangle conveyor, Fixture circleFixture, float porcentajeCompartido) + private void ApplyConveyorEffect(simTransporte conveyor, Fixture circleFixture, float porcentajeCompartido) { float speedMetersPerSecond = conveyor.Speed / 60.0f; Vector2 desiredVelocity = new Vector2((float)Math.Cos(conveyor.Body.Rotation), (float)Math.Sin(conveyor.Body.Rotation)) * speedMetersPerSecond; @@ -231,9 +277,10 @@ namespace CtrEditor.Simulacion { private World world; private Canvas simulationCanvas; - public List circles; - public List rectangles; - public List lines; + public List circles; + public List rectangles; + public List lines; + public List descartes; public Stopwatch stopwatch; public Canvas DebugCanvas { get => simulationCanvas; set => simulationCanvas = value; } @@ -241,9 +288,10 @@ namespace CtrEditor.Simulacion public SimulationManagerFP() { world = new World(new Vector2(0, 0)); // Vector2.Zero - circles = new List(); - rectangles = new List(); - lines = new List(); + circles = new List(); + rectangles = new List(); + lines = new List(); + descartes = new List(); stopwatch = new Stopwatch(); } @@ -268,27 +316,55 @@ namespace CtrEditor.Simulacion world.Step(elapsedMilliseconds / 1000.0f); } - public simCircle AddCircle(float diameter, Vector2 position, float mass) + public void Remove(object Objeto) { - simCircle circle = new simCircle(world, diameter, position, mass); + switch (Objeto) + { + case simBotella obj: + circles.Remove(obj); + break; + case simTransporte obj: + rectangles.Remove(obj); + break; + case simGuia obj: + lines.Remove(obj); + break; + case simDescarte obj: + descartes.Remove(obj); + break; + default: + throw new InvalidOperationException("Tipo no soportado"); + } + } + + public simBotella AddCircle(float diameter, Vector2 position, float mass) + { + simBotella circle = new simBotella(world, diameter, position, mass); circles.Add(circle); return circle; } - public simRectangle AddRectangle(float width, float height, Vector2 position, float angle) + public simTransporte AddRectangle(float width, float height, Vector2 position, float angle) { - simRectangle rectangle = new simRectangle(world, width, height, position, angle); + simTransporte rectangle = new simTransporte(world, width, height, position, angle); rectangles.Add(rectangle); return rectangle; } - public simLine AddLine(Vector2 start, Vector2 end) + public simGuia AddLine(Vector2 start, Vector2 end) { - simLine line = new simLine(world, start, end); + simGuia line = new simGuia(world, start, end); lines.Add(line); return line; } + public simDescarte AddDescarte(float diameter, Vector2 position) + { + simDescarte descarte = new simDescarte(world, diameter, position); + descartes.Add(descarte); + return descarte; + } + public void Debug_DrawInitialBodies() { ClearSimulationShapes();