Skip to content

Commit eda9f0a

Browse files
authored
Merge pull request #10 from VladM7/viewmodel-cleanup
Viewmodel cleanup
2 parents d1c5b7c + 9aa6c80 commit eda9f0a

15 files changed

Lines changed: 900 additions & 645 deletions

App.xaml.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22
using Microsoft.Extensions.Configuration;
33
using Microsoft.Extensions.DependencyInjection;
44
using Microsoft.Extensions.Hosting;
5+
using Microsoft.Extensions.Options;
56
using Stack_Solver.Data;
67
using Stack_Solver.Data.Repositories;
8+
using Stack_Solver.Infrastructure;
9+
using Stack_Solver.Models;
710
using Stack_Solver.Services;
811
using Stack_Solver.ViewModels.Pages;
912
using Stack_Solver.ViewModels.Windows;
@@ -28,7 +31,11 @@ public partial class App
2831
// https://docs.microsoft.com/dotnet/core/extensions/logging
2932
private static readonly IHost _host = Host
3033
.CreateDefaultBuilder()
31-
.ConfigureAppConfiguration(c => { c.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)); })
34+
.ConfigureAppConfiguration(c =>
35+
{
36+
c.SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)!);
37+
c.AddJsonFile("defaults.json", optional: true, reloadOnChange: true);
38+
})
3239
.ConfigureServices((context, services) =>
3340
{
3441
services.AddNavigationViewPageProvider();
@@ -55,22 +62,31 @@ public partial class App
5562
services.AddSingleton<SKULibraryPage>();
5663
services.AddSingleton<SKULibraryViewModel>();
5764
services.AddSingleton<PalletBuilderPage>();
58-
services.AddSingleton<PalletBuilderViewModel>();
65+
services.AddSingleton<PalletBuilderViewModel>(sp => new PalletBuilderViewModel(
66+
sp.GetRequiredService<ISkuRepository>(),
67+
sp.GetRequiredService<IEventAggregator>(),
68+
sp.GetRequiredService<ILayerVisualizationService>(),
69+
sp.GetRequiredService<IOptions<GenerationOptions>>(),
70+
sp.GetRequiredService<IOptions<PalletDefaultsOptions>>()));
5971
services.AddSingleton<TruckLoadingPage>();
6072
services.AddSingleton<TruckLoadingViewModel>();
6173
services.AddSingleton<JobManagerPage>();
6274
services.AddSingleton<JobManagerViewModel>();
6375

76+
services.AddSingleton<IEventAggregator, EventAggregator>();
77+
services.AddSingleton<ILayerVisualizationService, LayerVisualizationService>();
78+
6479
services.AddDbContextFactory<ApplicationDbContext>(options =>
6580
{
6681
options.UseSqlite($"Data Source={AppPaths.DatabaseFile}");
6782
});
6883

69-
// Repositories
7084
services.AddSingleton<ISkuRepository, SkuRepository>();
71-
72-
// Initializer
7385
services.AddSingleton<DatabaseInitializer>();
86+
87+
// Bind options from host configuration
88+
services.Configure<GenerationOptions>(context.Configuration.GetSection("LayerGeneration"));
89+
services.Configure<PalletDefaultsOptions>(context.Configuration.GetSection("PalletDefaults"));
7490
}).Build();
7591

7692
/// <summary>

Infrastructure/EventAggregator.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
namespace Stack_Solver.Infrastructure
2+
{
3+
public interface IEventAggregator
4+
{
5+
void Publish<TMessage>(TMessage message);
6+
void Subscribe<TMessage>(Action<TMessage> handler);
7+
void Unsubscribe<TMessage>(Action<TMessage> handler);
8+
}
9+
10+
public class EventAggregator : IEventAggregator
11+
{
12+
private readonly Dictionary<Type, List<Delegate>> _handlers = [];
13+
14+
public void Publish<TMessage>(TMessage message)
15+
{
16+
var t = typeof(TMessage);
17+
if (_handlers.TryGetValue(t, out var list))
18+
{
19+
foreach (var h in list.ToArray())
20+
{
21+
try { ((Action<TMessage>)h).Invoke(message); }
22+
catch { }
23+
}
24+
}
25+
}
26+
27+
public void Subscribe<TMessage>(Action<TMessage> handler)
28+
{
29+
var t = typeof(TMessage);
30+
if (!_handlers.TryGetValue(t, out var list))
31+
{
32+
list = [];
33+
_handlers[t] = list;
34+
}
35+
if (!list.Contains(handler)) list.Add(handler);
36+
}
37+
38+
public void Unsubscribe<TMessage>(Action<TMessage> handler)
39+
{
40+
var t = typeof(TMessage);
41+
if (_handlers.TryGetValue(t, out var list))
42+
{
43+
list.Remove(handler);
44+
if (list.Count == 0) _handlers.Remove(t);
45+
}
46+
}
47+
}
48+
}

Models/GenerationOptions.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
{
33
public class GenerationOptions
44
{
5-
public int MaxSolverTime { get; set; } = 60;
6-
public int MaxCandidates { get; set; } = 2000;
5+
public int MaxSolverTime { get; set; }
6+
public int MaxCandidates { get; set; }
77

88
public GenerationOptions() { }
99

@@ -12,5 +12,11 @@ public GenerationOptions(int maxSolverTime, int maxCandidates)
1212
MaxSolverTime = maxSolverTime;
1313
MaxCandidates = maxCandidates;
1414
}
15+
16+
public static GenerationOptions From(GenerationOptions? source)
17+
{
18+
if (source == null) return new GenerationOptions();
19+
return new GenerationOptions(source.MaxSolverTime, source.MaxCandidates);
20+
}
1521
}
1622
}

Models/PalletDefaultsOptions.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace Stack_Solver.Models
2+
{
3+
public class PalletDefaultsOptions
4+
{
5+
public string? DefaultCatalog { get; set; }
6+
public string? DefaultPalletName { get; set; }
7+
public int PalletLength { get; set; } = 120;
8+
public int PalletWidth { get; set; } = 80;
9+
public double PalletHeight { get; set; } = 14.4;
10+
public int MaxStackHeight { get; set; } = 180;
11+
public int MaxStackWeight { get; set; } = 950;
12+
}
13+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using Stack_Solver.Helpers.Rendering;
2+
using Stack_Solver.Models.Layering;
3+
using Stack_Solver.Models.Supports;
4+
using System.Collections.ObjectModel;
5+
using System.Windows;
6+
using System.Windows.Media;
7+
using System.Windows.Media.Media3D;
8+
9+
namespace Stack_Solver.Services
10+
{
11+
public interface ILayerVisualizationService
12+
{
13+
void HighlightItem(Model3DGroup scene, PositionedItem? item, double palletHeight);
14+
void Build2DRectangles(Layer layer, SupportSurface pallet, int gridStep, ObservableCollection<Rect> target);
15+
}
16+
17+
public class LayerVisualizationService : ILayerVisualizationService
18+
{
19+
private Model3DGroup? _selectionHighlight;
20+
21+
public void HighlightItem(Model3DGroup scene, PositionedItem? item, double palletHeight)
22+
{
23+
if (_selectionHighlight != null)
24+
{
25+
scene.Children.Remove(_selectionHighlight);
26+
_selectionHighlight = null;
27+
}
28+
if (item == null) return;
29+
var sku = item.SkuType;
30+
double boxLength = item.Rotated ? sku.Width : sku.Length;
31+
double boxWidth = item.Rotated ? sku.Length : sku.Width;
32+
double boxHeight = sku.Height;
33+
double inflate = 0.6;
34+
var origin = new Point3D(item.X - inflate / 2.0, palletHeight + 0.01, item.Y - inflate / 2.0);
35+
var fillBrush = new SolidColorBrush(Color.FromArgb(40, 255, 255, 0));
36+
var edgeColor = Colors.Yellow;
37+
_selectionHighlight = GeometryCreator.CreateBoxWithEdges(origin, boxLength + inflate, boxHeight + inflate, boxWidth + inflate, fillBrush, edgeColor, 0.6);
38+
scene.Children.Add(_selectionHighlight);
39+
}
40+
41+
public void Build2DRectangles(Layer layer, SupportSurface pallet, int gridStep, ObservableCollection<Rect> target)
42+
{
43+
LayerGeometryBuilder.Build(layer, pallet, gridStep);
44+
target.Clear();
45+
if (layer.Geometry?.ItemRectangles != null)
46+
{
47+
double canvasHeight = pallet.Width;
48+
foreach (var r in layer.Geometry.ItemRectangles)
49+
{
50+
var display = new Rect(r.X, canvasHeight - (r.Y + r.Height), r.Width, r.Height);
51+
target.Add(display);
52+
}
53+
}
54+
}
55+
}
56+
}

Stack-Solver.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
<Page Remove="Tests\**" />
2424
</ItemGroup>
2525

26+
<ItemGroup>
27+
<Content Include="defaults.json">
28+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
29+
</Content>
30+
</ItemGroup>
31+
2632
<ItemGroup>
2733
<PackageReference Include="Google.OrTools" Version="9.14.6206" />
2834
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />

0 commit comments

Comments
 (0)