From 914f6ba20f519b97086a052371aee3a447d3f897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD=D0=BE=D0=B2=20=D0=98=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD?= Date: Wed, 21 Aug 2024 22:39:22 +0200 Subject: [PATCH] fix: fix memory leaks --- .../ViewModels/CreatureListViewModel.cs | 8 +++++ .../ViewModels/CreatureMapViewModel.cs | 10 +++++++ .../ViewModels/DropListViewModel.cs | 7 +++++ .../ViewModels/DropMapViewModel.cs | 15 +++++++--- .../ViewModels/HeroSummaryInfoViewModel.cs | 1 + .../Application/ViewModels/MainViewModel.cs | 29 ++++++++++++++++--- Client/Application/ViewModels/MapViewModel.cs | 5 ++++ .../ViewModels/PathNodeViewModel.cs | 5 ++++ .../ViewModels/TargetSummaryInfoViewModel.cs | 8 +++++ 9 files changed, 80 insertions(+), 8 deletions(-) diff --git a/Client/Application/ViewModels/CreatureListViewModel.cs b/Client/Application/ViewModels/CreatureListViewModel.cs index c585297..8e03d98 100644 --- a/Client/Application/ViewModels/CreatureListViewModel.cs +++ b/Client/Application/ViewModels/CreatureListViewModel.cs @@ -62,6 +62,14 @@ namespace Client.Application.ViewModels this.pathMover = pathMover; } + public void UnsubscribeAll() + { + creature.PropertyChanged -= Creature_PropertyChanged; + creature.Transform.Position.PropertyChanged -= Position_PropertyChanged; + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + hero.PropertyChanged -= Hero_PropertyChanged; + } + private void HeroPosition_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { OnPropertyChanged("Distance"); diff --git a/Client/Application/ViewModels/CreatureMapViewModel.cs b/Client/Application/ViewModels/CreatureMapViewModel.cs index 7d6dc8b..ab04580 100644 --- a/Client/Application/ViewModels/CreatureMapViewModel.cs +++ b/Client/Application/ViewModels/CreatureMapViewModel.cs @@ -109,6 +109,16 @@ namespace Client.Application.ViewModels MouseRightClickCommand = new RelayCommand(async (o) => await OnMouseRightClick(o)); } + public void UnsubscribeAll() + { + creature.PropertyChanged -= Creature_PropertyChanged; + creature.Transform.PropertyChanged -= Transform_PropertyChanged; + creature.Transform.Position.PropertyChanged -= Position_PropertyChanged; + creature.VitalStats.PropertyChanged -= VitalStats_PropertyChanged; + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + hero.PropertyChanged -= Hero_PropertyChanged; + } + private void VitalStats_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "Hp" || e.PropertyName == "MaxHp") diff --git a/Client/Application/ViewModels/DropListViewModel.cs b/Client/Application/ViewModels/DropListViewModel.cs index a94183c..8aab018 100644 --- a/Client/Application/ViewModels/DropListViewModel.cs +++ b/Client/Application/ViewModels/DropListViewModel.cs @@ -92,6 +92,13 @@ namespace Client.Application.ViewModels MouseRightClickCommand = new RelayCommand(async (o) => await OnMouseRightClick(o)); } + public void UnsubscribeAll() + { + drop.PropertyChanged -= Drop_PropertyChanged; + drop.Transform.Position.PropertyChanged -= DropPosition_PropertyChanged; + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + } + private void HeroPosition_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { OnPropertyChanged("Distance"); diff --git a/Client/Application/ViewModels/DropMapViewModel.cs b/Client/Application/ViewModels/DropMapViewModel.cs index 9d7283c..dfe7591 100644 --- a/Client/Application/ViewModels/DropMapViewModel.cs +++ b/Client/Application/ViewModels/DropMapViewModel.cs @@ -73,24 +73,31 @@ namespace Client.Application.ViewModels this.hero = hero; this.worldHandler = worldHandler; this.pathMover = pathMover; - drop.PropertyChanged += Creature_PropertyChanged; - drop.Transform.Position.PropertyChanged += Position_PropertyChanged; + drop.PropertyChanged += Drop_PropertyChanged; + drop.Transform.Position.PropertyChanged += DropPosition_PropertyChanged; hero.Transform.Position.PropertyChanged += HeroPosition_PropertyChanged; MouseLeftClickCommand = new RelayCommand(OnMouseLeftClick); MouseRightClickCommand = new RelayCommand(async (o) => await OnMouseRightClick(o)); } + public void UnsubscribeAll() + { + drop.PropertyChanged -= Drop_PropertyChanged; + drop.Transform.Position.PropertyChanged -= DropPosition_PropertyChanged; + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + } + private void HeroPosition_PropertyChanged(object? sender, PropertyChangedEventArgs e) { OnPropertyChanged("Position"); } - private void Position_PropertyChanged(object? sender, PropertyChangedEventArgs e) + private void DropPosition_PropertyChanged(object? sender, PropertyChangedEventArgs e) { OnPropertyChanged("Position"); } - private void Creature_PropertyChanged(object? sender, PropertyChangedEventArgs e) + private void Drop_PropertyChanged(object? sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Name" || e.PropertyName == "Amount") { diff --git a/Client/Application/ViewModels/HeroSummaryInfoViewModel.cs b/Client/Application/ViewModels/HeroSummaryInfoViewModel.cs index d401963..f3182a4 100644 --- a/Client/Application/ViewModels/HeroSummaryInfoViewModel.cs +++ b/Client/Application/ViewModels/HeroSummaryInfoViewModel.cs @@ -105,6 +105,7 @@ namespace Client.Application.ViewModels } else if (target != null && hero.Target == null) { + target.UnsubscribeAll(); target = null; OnPropertyChanged("Target"); } diff --git a/Client/Application/ViewModels/MainViewModel.cs b/Client/Application/ViewModels/MainViewModel.cs index e1fc58d..36be4c5 100644 --- a/Client/Application/ViewModels/MainViewModel.cs +++ b/Client/Application/ViewModels/MainViewModel.cs @@ -6,6 +6,7 @@ using Client.Domain.Entities; using Client.Domain.Events; using Client.Domain.Service; using Client.Domain.ValueObjects; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -72,7 +73,12 @@ namespace Client.Application.ViewModels public void Handle(CreatureDeletedEvent @event) { - Creatures.RemoveAll(x => x.Id == @event.Id); + var creature = Creatures.Where(x => x.Id == @event.Id).FirstOrDefault(); + if (creature != null) + { + creature.UnsubscribeAll(); + Creatures.Remove(creature); + } RemoveCreature(@event.Id); } @@ -87,8 +93,18 @@ namespace Client.Application.ViewModels public void Handle(DropDeletedEvent @event) { - Drops.RemoveAll(x => x.Id == @event.Id); - Map.Drops.RemoveAll(x => x.Id == @event.Id); + var drop = Drops.Where(x => x.Id == @event.Id).FirstOrDefault(); + if (drop != null) + { + drop.UnsubscribeAll(); + Drops.Remove(drop); + } + var mapDrop = Map.Drops.Where(x => x.Id == @event.Id).FirstOrDefault(); + if (mapDrop != null) + { + mapDrop.UnsubscribeAll(); + Map.Drops.Remove(mapDrop); + } } public void Handle(ChatMessageCreatedEvent @event) @@ -156,7 +172,12 @@ namespace Client.Application.ViewModels private void RemoveCreature(uint id) { - Map.Creatures.RemoveAll(x => x.Id == id); + var creature = Map.Creatures.Where(x => x.Id == id).FirstOrDefault(); + if (creature != null) + { + creature.UnsubscribeAll(); + Map.Creatures.Remove(creature); + } } private void OnToggleAI(object? sender) diff --git a/Client/Application/ViewModels/MapViewModel.cs b/Client/Application/ViewModels/MapViewModel.cs index 4743b28..e28cb33 100644 --- a/Client/Application/ViewModels/MapViewModel.cs +++ b/Client/Application/ViewModels/MapViewModel.cs @@ -230,11 +230,16 @@ namespace Client.Application.ViewModels { foreach (var item in e.OldItems) { + Path[0].UnsubscribeAll(); Path.RemoveAt(0); } } else if (e.Action == NotifyCollectionChangedAction.Reset) { + foreach (var item in Path) + { + item.UnsubscribeAll(); + } Path.RemoveAll(); } } diff --git a/Client/Application/ViewModels/PathNodeViewModel.cs b/Client/Application/ViewModels/PathNodeViewModel.cs index adfb4e2..47cedc1 100644 --- a/Client/Application/ViewModels/PathNodeViewModel.cs +++ b/Client/Application/ViewModels/PathNodeViewModel.cs @@ -69,6 +69,11 @@ namespace Client.Application.ViewModels hero.Transform.Position.PropertyChanged += HeroPosition_PropertyChanged; } + public void UnsubscribeAll() + { + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + } + private void HeroPosition_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { OnPropertyChanged("From"); diff --git a/Client/Application/ViewModels/TargetSummaryInfoViewModel.cs b/Client/Application/ViewModels/TargetSummaryInfoViewModel.cs index b8d51aa..f384ac3 100644 --- a/Client/Application/ViewModels/TargetSummaryInfoViewModel.cs +++ b/Client/Application/ViewModels/TargetSummaryInfoViewModel.cs @@ -38,6 +38,14 @@ namespace Client.Application.ViewModels this.hero = hero; } + public void UnsubscribeAll() + { + creature.PropertyChanged -= Creature_PropertyChanged; + creature.Transform.Position.PropertyChanged -= Position_PropertyChanged; + creature.VitalStats.PropertyChanged -= VitalStats_PropertyChanged; + hero.Transform.Position.PropertyChanged -= HeroPosition_PropertyChanged; + } + private void VitalStats_PropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e) { if (e.PropertyName == "Hp")