From a187dfe041bec3639468c9e71858613b931fdde6 Mon Sep 17 00:00:00 2001 From: Jaewung Lee Date: Sat, 21 Sep 2024 11:45:54 +0800 Subject: [PATCH] Updates --- src/Jamesnet.Core/BaseResourceLoader.cs | 2 + src/Jamesnet.Core/Container.cs | 4 + src/Jamesnet.Core/ContainerProvider.cs | 4 +- .../DefaultViewModelInitializer.cs | 3 + src/Jamesnet.Core/IContainer.cs | 2 + src/Jamesnet.Core/IViewModelMapper.cs | 4 +- src/Jamesnet.Core/InjectAttribute.cs | 4 +- src/Jamesnet.Core/Jamesnet.Core.csproj | 6 +- src/Jamesnet.Core/LayerManager.cs | 3 + src/Jamesnet.Core/RelayCommand.cs | 1 + src/Jamesnet.Core/ViewModelBase.cs | 2 + src/Jamesnet.Core/ViewModelMapper.cs | 5 +- src/Jamesnet.Core/YamlConverter.cs | 4 + src/Jamesnet.Core/YamlData.cs | 4 +- src/Jamesnet.Core/YamlExtensions.cs | 5 +- src/Jamesnet.Core/YamlItem.cs | 3 + src/Jamesnet.Core2/AppBootstrapper.cs | 37 +++++++ src/Jamesnet.Core2/BaseResourceLoader.cs | 43 ++++++++ src/Jamesnet.Core2/Container.cs | 100 ++++++++++++++++++ src/Jamesnet.Core2/ContainerProvider.cs | 20 ++++ .../DefaultViewModelInitializer.cs | 46 ++++++++ src/Jamesnet.Core2/IContainer.cs | 18 ++++ src/Jamesnet.Core2/ILayer.cs | 6 ++ src/Jamesnet.Core2/ILayerManager.cs | 10 ++ src/Jamesnet.Core2/IView.cs | 6 ++ src/Jamesnet.Core2/IViewLoadable.cs | 6 ++ src/Jamesnet.Core2/IViewModelInitializer.cs | 6 ++ src/Jamesnet.Core2/IViewModelMapper.cs | 7 ++ src/Jamesnet.Core2/InjectAttribute.cs | 4 + src/Jamesnet.Core2/Jamesnet.Core.csproj | 7 ++ src/Jamesnet.Core2/LayerManager.cs | 75 +++++++++++++ src/Jamesnet.Core2/RelayCommand.cs | 61 +++++++++++ src/Jamesnet.Core2/StringExtensions.cs | 15 +++ src/Jamesnet.Core2/ViewModelBase.cs | 25 +++++ src/Jamesnet.Core2/ViewModelMapper.cs | 16 +++ src/Jamesnet.Core2/YamlConverter.cs | 60 +++++++++++ src/Jamesnet.Core2/YamlData.cs | 7 ++ src/Jamesnet.Core2/YamlExtensions.cs | 20 ++++ src/Jamesnet.Core2/YamlItem.cs | 18 ++++ src/Leagueoflegends.WinUI3.sln | 38 +++---- 40 files changed, 679 insertions(+), 28 deletions(-) create mode 100644 src/Jamesnet.Core2/AppBootstrapper.cs create mode 100644 src/Jamesnet.Core2/BaseResourceLoader.cs create mode 100644 src/Jamesnet.Core2/Container.cs create mode 100644 src/Jamesnet.Core2/ContainerProvider.cs create mode 100644 src/Jamesnet.Core2/DefaultViewModelInitializer.cs create mode 100644 src/Jamesnet.Core2/IContainer.cs create mode 100644 src/Jamesnet.Core2/ILayer.cs create mode 100644 src/Jamesnet.Core2/ILayerManager.cs create mode 100644 src/Jamesnet.Core2/IView.cs create mode 100644 src/Jamesnet.Core2/IViewLoadable.cs create mode 100644 src/Jamesnet.Core2/IViewModelInitializer.cs create mode 100644 src/Jamesnet.Core2/IViewModelMapper.cs create mode 100644 src/Jamesnet.Core2/InjectAttribute.cs create mode 100644 src/Jamesnet.Core2/Jamesnet.Core.csproj create mode 100644 src/Jamesnet.Core2/LayerManager.cs create mode 100644 src/Jamesnet.Core2/RelayCommand.cs create mode 100644 src/Jamesnet.Core2/StringExtensions.cs create mode 100644 src/Jamesnet.Core2/ViewModelBase.cs create mode 100644 src/Jamesnet.Core2/ViewModelMapper.cs create mode 100644 src/Jamesnet.Core2/YamlConverter.cs create mode 100644 src/Jamesnet.Core2/YamlData.cs create mode 100644 src/Jamesnet.Core2/YamlExtensions.cs create mode 100644 src/Jamesnet.Core2/YamlItem.cs diff --git a/src/Jamesnet.Core/BaseResourceLoader.cs b/src/Jamesnet.Core/BaseResourceLoader.cs index 0f446f2..0bd109b 100644 --- a/src/Jamesnet.Core/BaseResourceLoader.cs +++ b/src/Jamesnet.Core/BaseResourceLoader.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using System.Reflection; namespace Jamesnet.Core; diff --git a/src/Jamesnet.Core/Container.cs b/src/Jamesnet.Core/Container.cs index fe44dd2..930b4b2 100644 --- a/src/Jamesnet.Core/Container.cs +++ b/src/Jamesnet.Core/Container.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.Linq; + namespace Jamesnet.Core; public class Container : IContainer diff --git a/src/Jamesnet.Core/ContainerProvider.cs b/src/Jamesnet.Core/ContainerProvider.cs index 64e3399..1c71234 100644 --- a/src/Jamesnet.Core/ContainerProvider.cs +++ b/src/Jamesnet.Core/ContainerProvider.cs @@ -1,4 +1,6 @@ -namespace Jamesnet.Core; +using System; + +namespace Jamesnet.Core; public static class ContainerProvider { diff --git a/src/Jamesnet.Core/DefaultViewModelInitializer.cs b/src/Jamesnet.Core/DefaultViewModelInitializer.cs index 2bf8886..c34e720 100644 --- a/src/Jamesnet.Core/DefaultViewModelInitializer.cs +++ b/src/Jamesnet.Core/DefaultViewModelInitializer.cs @@ -1,3 +1,6 @@ +using System; +using System.Linq; + namespace Jamesnet.Core; public class DefaultViewModelInitializer : IViewModelInitializer diff --git a/src/Jamesnet.Core/IContainer.cs b/src/Jamesnet.Core/IContainer.cs index c027cc9..2215afd 100644 --- a/src/Jamesnet.Core/IContainer.cs +++ b/src/Jamesnet.Core/IContainer.cs @@ -1,3 +1,5 @@ +using System; + namespace Jamesnet.Core; public interface IContainer diff --git a/src/Jamesnet.Core/IViewModelMapper.cs b/src/Jamesnet.Core/IViewModelMapper.cs index 221fb51..4bd8347 100644 --- a/src/Jamesnet.Core/IViewModelMapper.cs +++ b/src/Jamesnet.Core/IViewModelMapper.cs @@ -1,4 +1,6 @@ -namespace Jamesnet.Core; +using System; + +namespace Jamesnet.Core; public interface IViewModelMapper { diff --git a/src/Jamesnet.Core/InjectAttribute.cs b/src/Jamesnet.Core/InjectAttribute.cs index 6870137..12c23c6 100644 --- a/src/Jamesnet.Core/InjectAttribute.cs +++ b/src/Jamesnet.Core/InjectAttribute.cs @@ -1,4 +1,6 @@ -[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] +using System; + +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] public class InjectAttribute : Attribute { } diff --git a/src/Jamesnet.Core/Jamesnet.Core.csproj b/src/Jamesnet.Core/Jamesnet.Core.csproj index fa71b7a..dbb7150 100644 --- a/src/Jamesnet.Core/Jamesnet.Core.csproj +++ b/src/Jamesnet.Core/Jamesnet.Core.csproj @@ -1,9 +1,9 @@  - net8.0 - enable - enable + netstandard2.0 + 10 + disable diff --git a/src/Jamesnet.Core/LayerManager.cs b/src/Jamesnet.Core/LayerManager.cs index 404865e..de78166 100644 --- a/src/Jamesnet.Core/LayerManager.cs +++ b/src/Jamesnet.Core/LayerManager.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + namespace Jamesnet.Core; public class LayerManager : ILayerManager diff --git a/src/Jamesnet.Core/RelayCommand.cs b/src/Jamesnet.Core/RelayCommand.cs index 1c458cf..ecbf6e5 100644 --- a/src/Jamesnet.Core/RelayCommand.cs +++ b/src/Jamesnet.Core/RelayCommand.cs @@ -1,3 +1,4 @@ +using System; using System.Windows.Input; namespace Jamesnet.Core; diff --git a/src/Jamesnet.Core/ViewModelBase.cs b/src/Jamesnet.Core/ViewModelBase.cs index cc0091e..7795e9c 100644 --- a/src/Jamesnet.Core/ViewModelBase.cs +++ b/src/Jamesnet.Core/ViewModelBase.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; diff --git a/src/Jamesnet.Core/ViewModelMapper.cs b/src/Jamesnet.Core/ViewModelMapper.cs index a9cae44..75e3eb0 100644 --- a/src/Jamesnet.Core/ViewModelMapper.cs +++ b/src/Jamesnet.Core/ViewModelMapper.cs @@ -1,4 +1,7 @@ -namespace Jamesnet.Core; +using System; +using System.Collections.Generic; + +namespace Jamesnet.Core; public class ViewModelMapper : IViewModelMapper { diff --git a/src/Jamesnet.Core/YamlConverter.cs b/src/Jamesnet.Core/YamlConverter.cs index 3f3e33b..aa78560 100644 --- a/src/Jamesnet.Core/YamlConverter.cs +++ b/src/Jamesnet.Core/YamlConverter.cs @@ -1,3 +1,7 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Reflection; namespace Jamesnet.Core diff --git a/src/Jamesnet.Core/YamlData.cs b/src/Jamesnet.Core/YamlData.cs index 7bc0b31..f20f612 100644 --- a/src/Jamesnet.Core/YamlData.cs +++ b/src/Jamesnet.Core/YamlData.cs @@ -1,4 +1,6 @@ -namespace Jamesnet.Core; +using System.Collections.Generic; + +namespace Jamesnet.Core; public class YamlData : List { diff --git a/src/Jamesnet.Core/YamlExtensions.cs b/src/Jamesnet.Core/YamlExtensions.cs index 85412a8..30ce1e4 100644 --- a/src/Jamesnet.Core/YamlExtensions.cs +++ b/src/Jamesnet.Core/YamlExtensions.cs @@ -1,4 +1,7 @@ -namespace Jamesnet.Core; +using System; +using System.Collections.Generic; + +namespace Jamesnet.Core; public static class YamlExtensions { diff --git a/src/Jamesnet.Core/YamlItem.cs b/src/Jamesnet.Core/YamlItem.cs index f78e80e..ac342a7 100644 --- a/src/Jamesnet.Core/YamlItem.cs +++ b/src/Jamesnet.Core/YamlItem.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; + namespace Jamesnet.Core; public class YamlItem : Dictionary diff --git a/src/Jamesnet.Core2/AppBootstrapper.cs b/src/Jamesnet.Core2/AppBootstrapper.cs new file mode 100644 index 0000000..e0fa4d8 --- /dev/null +++ b/src/Jamesnet.Core2/AppBootstrapper.cs @@ -0,0 +1,37 @@ +namespace Jamesnet.Core; + +public abstract class AppBootstrapper +{ + protected readonly IContainer Container; + protected readonly ILayerManager Layer; + protected readonly IViewModelMapper ViewModelMapper; + + protected AppBootstrapper() + { + Container = new Container(); + Layer = new LayerManager(); + ViewModelMapper = new ViewModelMapper(); + ContainerProvider.SetContainer(Container); + ConfigureContainer(); + } + + protected virtual void ConfigureContainer() + { + Container.RegisterInstance(Container); + Container.RegisterInstance(Layer); + Container.RegisterInstance(ViewModelMapper); + Container.RegisterSingleton(); + } + + protected abstract void RegisterViewModels(); + protected abstract void RegisterDependencies(); + + public void Run() + { + RegisterViewModels(); + RegisterDependencies(); + OnStartup(); + } + + protected abstract void OnStartup(); +} diff --git a/src/Jamesnet.Core2/BaseResourceLoader.cs b/src/Jamesnet.Core2/BaseResourceLoader.cs new file mode 100644 index 0000000..0f446f2 --- /dev/null +++ b/src/Jamesnet.Core2/BaseResourceLoader.cs @@ -0,0 +1,43 @@ +using System.Reflection; + +namespace Jamesnet.Core; + +public abstract class BaseResourceLoader +{ + protected abstract string AssemblyName { get; } + protected abstract string ResourcePath { get; } + protected abstract IEnumerable ConvertToItems(YamlData rawData); + protected abstract TResult OrganizeItems(IEnumerable items); + + public TResult LoadAndOrganize() + { + Assembly assembly = Assembly.Load(AssemblyName); + YamlData rawData = LoadYamlData(assembly, ResourcePath); + IEnumerable items = ConvertToItems(rawData); + return OrganizeItems(items); + } + + private YamlData LoadYamlData(Assembly assembly, string resourcePath) + { + YamlData yamlData = new YamlData(); + + object result = YamlConverter.ParseResource(assembly, resourcePath); + IEnumerable data = result as IEnumerable; + + if (data == null) + { + throw new InvalidOperationException("YamlConverter.ParseResource did not return an IEnumerable"); + } + + foreach (object item in data) + { + IDictionary dict = item as IDictionary; + if (dict != null) + { + yamlData.Add(new YamlItem(dict)); + } + } + + return yamlData; + } +} diff --git a/src/Jamesnet.Core2/Container.cs b/src/Jamesnet.Core2/Container.cs new file mode 100644 index 0000000..fe44dd2 --- /dev/null +++ b/src/Jamesnet.Core2/Container.cs @@ -0,0 +1,100 @@ +namespace Jamesnet.Core; + +public class Container : IContainer +{ + private readonly Dictionary<(Type, string), Func> _registrations = new Dictionary<(Type, string), Func>(); + + public void Register() where TImplementation : TInterface + { + Register(null); + } + + public void Register(string name) where TImplementation : TInterface + { + _registrations[(typeof(TInterface), name)] = () => CreateInstance(typeof(TImplementation)); + } + + public void RegisterSingleton() where TImplementation : TInterface + { + RegisterSingleton(null); + } + + public void RegisterSingleton(string name) where TImplementation : TInterface + { + var lazy = new Lazy(() => CreateInstance(typeof(TImplementation))); + _registrations[(typeof(TInterface), name)] = () => lazy.Value; + } + + public void RegisterSingleton(string name) + { + var lazy = new Lazy(() => CreateInstance(typeof(TImplementation))); + _registrations[(typeof(TImplementation), name)] = () => lazy.Value; + } + + public void RegisterInstance(TInterface instance) + { + RegisterInstance(instance, null); + } + + public void RegisterInstance(TInterface instance, string name) + { + _registrations[(typeof(TInterface), name)] = () => instance; + } + + public T Resolve() + { + return Resolve(null); + } + + public T Resolve(string name) + { + return (T)Resolve(typeof(T), name); + } + + public object Resolve(Type type) + { + return Resolve(type, null); + } + + public object Resolve(Type type, string name) + { + if (_registrations.TryGetValue((type, name), out var creator)) + { + return creator(); + } + if (!type.IsAbstract && !type.IsInterface) + { + return CreateInstance(type); + } + throw new InvalidOperationException($"Type {type} has not been registered."); + } + + public bool TryResolve(out T result) + { + return TryResolve(null, out result); + } + + public bool TryResolve(string name, out T result) + { + if (_registrations.TryGetValue((typeof(T), name), out var creator)) + { + result = (T)creator(); + return true; + } + if (!typeof(T).IsAbstract && !typeof(T).IsInterface) + { + result = (T)CreateInstance(typeof(T)); + return true; + } + result = default; + return false; + } + + private object CreateInstance(Type type) + { + var constructors = type.GetConstructors(); + var constructor = constructors.FirstOrDefault(c => c.GetParameters().Length > 0) ?? constructors.First(); + var parameters = constructor.GetParameters().Select(p => Resolve(p.ParameterType)).ToArray(); + return constructor.Invoke(parameters); + } +} diff --git a/src/Jamesnet.Core2/ContainerProvider.cs b/src/Jamesnet.Core2/ContainerProvider.cs new file mode 100644 index 0000000..64e3399 --- /dev/null +++ b/src/Jamesnet.Core2/ContainerProvider.cs @@ -0,0 +1,20 @@ +namespace Jamesnet.Core; + +public static class ContainerProvider +{ + private static IContainer _container; + + public static void SetContainer(IContainer container) + { + _container = container; + } + + public static IContainer GetContainer() + { + if (_container == null) + { + throw new InvalidOperationException("IContainer has not been set. Make sure to call ContainerProvider.SetContainer in your App class."); + } + return _container; + } +} diff --git a/src/Jamesnet.Core2/DefaultViewModelInitializer.cs b/src/Jamesnet.Core2/DefaultViewModelInitializer.cs new file mode 100644 index 0000000..2bf8886 --- /dev/null +++ b/src/Jamesnet.Core2/DefaultViewModelInitializer.cs @@ -0,0 +1,46 @@ +namespace Jamesnet.Core; + +public class DefaultViewModelInitializer : IViewModelInitializer +{ + private readonly IContainer _container; + private readonly IViewModelMapper _viewModelMapper; + + public DefaultViewModelInitializer(IContainer container, IViewModelMapper viewModelMapper) + { + _container = container; + _viewModelMapper = viewModelMapper; + } + + public void InitializeViewModel(IView view) + { + var viewType = view.GetType(); + var viewModelType = _viewModelMapper.GetViewModelType(viewType); + + if (viewModelType != null) + { + var viewModel = CreateViewModel(viewModelType); + view.DataContext = viewModel; + } + } + + private object CreateViewModel(Type viewModelType) + { + try + { + var constructor = viewModelType.GetConstructors() + .OrderByDescending(c => c.GetParameters().Length) + .First(); + + var parameters = constructor.GetParameters() + .Select(p => _container.Resolve(p.ParameterType)) + .ToArray(); + + return constructor.Invoke(parameters); + } + catch (Exception ex) + { + throw new InvalidOperationException($"Failed to create ViewModel of type {viewModelType.Name}.", ex); + } + } + +} diff --git a/src/Jamesnet.Core2/IContainer.cs b/src/Jamesnet.Core2/IContainer.cs new file mode 100644 index 0000000..c027cc9 --- /dev/null +++ b/src/Jamesnet.Core2/IContainer.cs @@ -0,0 +1,18 @@ +namespace Jamesnet.Core; + +public interface IContainer +{ + void Register() where TImplementation : TInterface; + void Register(string name) where TImplementation : TInterface; + void RegisterSingleton() where TImplementation : TInterface; + void RegisterSingleton(string name) where TImplementation : TInterface; + void RegisterSingleton(string name); + void RegisterInstance(TInterface instance); + void RegisterInstance(TInterface instance, string name); + T Resolve(); + T Resolve(string name); + object Resolve(Type type); + object Resolve(Type type, string name); + bool TryResolve(out T result); + bool TryResolve(string name, out T result); +} diff --git a/src/Jamesnet.Core2/ILayer.cs b/src/Jamesnet.Core2/ILayer.cs new file mode 100644 index 0000000..e576ca9 --- /dev/null +++ b/src/Jamesnet.Core2/ILayer.cs @@ -0,0 +1,6 @@ +namespace Jamesnet.Core; + +public interface ILayer +{ + object Content { get; set; } +} diff --git a/src/Jamesnet.Core2/ILayerManager.cs b/src/Jamesnet.Core2/ILayerManager.cs new file mode 100644 index 0000000..341d7a4 --- /dev/null +++ b/src/Jamesnet.Core2/ILayerManager.cs @@ -0,0 +1,10 @@ +namespace Jamesnet.Core; + +public interface ILayerManager +{ + void Register(string layerName, ILayer layer); + void Add(string layerName, IView view); + void Show(string layerName, IView view); + void Hide(string layerName); + void Mapping(string layerName, IView view); +} diff --git a/src/Jamesnet.Core2/IView.cs b/src/Jamesnet.Core2/IView.cs new file mode 100644 index 0000000..3bb5b29 --- /dev/null +++ b/src/Jamesnet.Core2/IView.cs @@ -0,0 +1,6 @@ +namespace Jamesnet.Core; + +public interface IView +{ + object DataContext { get; set; } +} diff --git a/src/Jamesnet.Core2/IViewLoadable.cs b/src/Jamesnet.Core2/IViewLoadable.cs new file mode 100644 index 0000000..b3d6635 --- /dev/null +++ b/src/Jamesnet.Core2/IViewLoadable.cs @@ -0,0 +1,6 @@ +namespace Jamesnet.Core; + +public interface IViewLoadable +{ + void Loaded(); +} diff --git a/src/Jamesnet.Core2/IViewModelInitializer.cs b/src/Jamesnet.Core2/IViewModelInitializer.cs new file mode 100644 index 0000000..04280a4 --- /dev/null +++ b/src/Jamesnet.Core2/IViewModelInitializer.cs @@ -0,0 +1,6 @@ +namespace Jamesnet.Core; + +public interface IViewModelInitializer +{ + void InitializeViewModel(IView view); +} diff --git a/src/Jamesnet.Core2/IViewModelMapper.cs b/src/Jamesnet.Core2/IViewModelMapper.cs new file mode 100644 index 0000000..221fb51 --- /dev/null +++ b/src/Jamesnet.Core2/IViewModelMapper.cs @@ -0,0 +1,7 @@ +namespace Jamesnet.Core; + +public interface IViewModelMapper +{ + void Register() where TView : IView where TViewModel : class; + Type GetViewModelType(Type viewType); +} diff --git a/src/Jamesnet.Core2/InjectAttribute.cs b/src/Jamesnet.Core2/InjectAttribute.cs new file mode 100644 index 0000000..6870137 --- /dev/null +++ b/src/Jamesnet.Core2/InjectAttribute.cs @@ -0,0 +1,4 @@ +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] +public class InjectAttribute : Attribute +{ +} diff --git a/src/Jamesnet.Core2/Jamesnet.Core.csproj b/src/Jamesnet.Core2/Jamesnet.Core.csproj new file mode 100644 index 0000000..dbdcea4 --- /dev/null +++ b/src/Jamesnet.Core2/Jamesnet.Core.csproj @@ -0,0 +1,7 @@ + + + + netstandard2.0 + + + diff --git a/src/Jamesnet.Core2/LayerManager.cs b/src/Jamesnet.Core2/LayerManager.cs new file mode 100644 index 0000000..404865e --- /dev/null +++ b/src/Jamesnet.Core2/LayerManager.cs @@ -0,0 +1,75 @@ +namespace Jamesnet.Core; + +public class LayerManager : ILayerManager +{ + private readonly Dictionary _layers = new Dictionary(); + private readonly Dictionary> _layerViews = new Dictionary>(); + private readonly Dictionary _layerViewMappings = new Dictionary(); + + public void Register(string layerName, ILayer layer) + { + Console.WriteLine($"LayerManager.Register called with layerName: {layerName}"); + + if (!_layers.ContainsKey(layerName)) + { + _layers[layerName] = layer; + _layerViews[layerName] = new List(); + if (_layerViewMappings.TryGetValue(layerName, out var view)) + { + Show(layerName, view); + } + } + } + + public void Show(string layerName, IView view) + { + if (!_layers.TryGetValue(layerName, out var layer)) + { + throw new InvalidOperationException($"Layer not registered: {layerName}"); + } + + if (view == null) + { + layer.Content = null; + return; + } + + if (!_layerViews[layerName].Contains(view)) + { + Add(layerName, view); + } + + layer.Content = view; + } + + public void Add(string layerName, IView view) + { + if (!_layers.ContainsKey(layerName)) + { + throw new InvalidOperationException($"Layer not registered: {layerName}"); + } + + if (!_layerViews.ContainsKey(layerName)) + { + _layerViews[layerName] = new List(); + } + + if (!_layerViews[layerName].Contains(view)) + { + _layerViews[layerName].Add(view); + } + } + + public void Hide(string layerName) + { + if (_layers.TryGetValue(layerName, out var layer)) + { + layer.Content = null; + } + } + + public void Mapping(string layerName, IView view) + { + _layerViewMappings[layerName] = view; + } +} diff --git a/src/Jamesnet.Core2/RelayCommand.cs b/src/Jamesnet.Core2/RelayCommand.cs new file mode 100644 index 0000000..1c458cf --- /dev/null +++ b/src/Jamesnet.Core2/RelayCommand.cs @@ -0,0 +1,61 @@ +using System.Windows.Input; + +namespace Jamesnet.Core; + +public class RelayCommand : ICommand +{ + private readonly Action _execute; + private readonly Func _canExecute; + + public RelayCommand(Action execute, Func canExecute = null) + { + _execute = execute ?? throw new ArgumentNullException(nameof(execute)); + _canExecute = canExecute; + } + + public event EventHandler CanExecuteChanged; + + public bool CanExecute(object parameter) + { + return _canExecute == null || _canExecute((T)parameter); + } + + public void Execute(object parameter) + { + _execute((T)parameter); + } + + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } +} + +public class RelayCommand : ICommand +{ + private readonly Action _execute; + private readonly Func _canExecute; + + public RelayCommand(Action execute, Func canExecute = null) + { + _execute = execute ?? throw new ArgumentNullException(nameof(execute)); + _canExecute = canExecute; + } + + public event EventHandler CanExecuteChanged; + + public bool CanExecute(object parameter) + { + return _canExecute == null || _canExecute(); + } + + public void Execute(object parameter) + { + _execute(); + } + + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } +} diff --git a/src/Jamesnet.Core2/StringExtensions.cs b/src/Jamesnet.Core2/StringExtensions.cs new file mode 100644 index 0000000..173d01e --- /dev/null +++ b/src/Jamesnet.Core2/StringExtensions.cs @@ -0,0 +1,15 @@ +using System.Globalization; + +namespace Jamesnet.Core; + +public static class StringExtensions +{ + public static string ToPascal(this string input) + { + if (string.IsNullOrEmpty(input)) + return input; + + TextInfo textInfo = new CultureInfo("en-US", false).TextInfo; + return textInfo.ToTitleCase(input.ToLower()).Replace(" ", ""); + } +} diff --git a/src/Jamesnet.Core2/ViewModelBase.cs b/src/Jamesnet.Core2/ViewModelBase.cs new file mode 100644 index 0000000..cc0091e --- /dev/null +++ b/src/Jamesnet.Core2/ViewModelBase.cs @@ -0,0 +1,25 @@ +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Jamesnet.Core; + +public class ViewModelBase : INotifyPropertyChanged +{ + public event PropertyChangedEventHandler? PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + protected bool SetProperty(ref T storage, T value, Action? callback = null, [CallerMemberName] string propertyName = null) + { + if (EqualityComparer.Default.Equals(storage, value)) + return false; + + storage = value; + OnPropertyChanged(propertyName); + callback?.Invoke(); + return true; + } +} diff --git a/src/Jamesnet.Core2/ViewModelMapper.cs b/src/Jamesnet.Core2/ViewModelMapper.cs new file mode 100644 index 0000000..a9cae44 --- /dev/null +++ b/src/Jamesnet.Core2/ViewModelMapper.cs @@ -0,0 +1,16 @@ +namespace Jamesnet.Core; + +public class ViewModelMapper : IViewModelMapper +{ + private readonly Dictionary _mappings = new Dictionary(); + + public void Register() where TView : IView where TViewModel : class + { + _mappings[typeof(TView)] = typeof(TViewModel); + } + + public Type GetViewModelType(Type viewType) + { + return _mappings.TryGetValue(viewType, out var viewModelType) ? viewModelType : null; + } +} diff --git a/src/Jamesnet.Core2/YamlConverter.cs b/src/Jamesnet.Core2/YamlConverter.cs new file mode 100644 index 0000000..3f3e33b --- /dev/null +++ b/src/Jamesnet.Core2/YamlConverter.cs @@ -0,0 +1,60 @@ +using System.Reflection; + +namespace Jamesnet.Core +{ + public static class YamlConverter + { + public static IEnumerable> Parse(string content) + { + return ParseYamlContent(content); + } + + public static IEnumerable> ParseFile(string filePath) + { + string content = File.ReadAllText(filePath); + return Parse(content); + } + + public static IEnumerable> ParseResource(Assembly assembly, string resourcePath) + { + using (Stream stream = assembly.GetManifestResourceStream(resourcePath)) + using (StreamReader reader = new StreamReader(stream)) + { + string content = reader.ReadToEnd(); + return Parse(content); + } + } + + private static IEnumerable> ParseYamlContent(string content) + { + var lines = content.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None) + .Where(line => !string.IsNullOrWhiteSpace(line) && !line.TrimStart().StartsWith("#")); + + var currentItem = new Dictionary(); + foreach (var line in lines) + { + if (line.TrimStart().StartsWith("-")) + { + if (currentItem.Count > 0) + { + yield return currentItem; + currentItem = new Dictionary(); + } + } + + if (line.Contains(':')) + { + var parts = line.Split(new[] { ':' }, 2); + var key = parts[0].Trim().TrimStart('-', ' '); + var value = parts[1].Trim(); + currentItem[key] = value; + } + } + + if (currentItem.Count > 0) + { + yield return currentItem; + } + } + } +} diff --git a/src/Jamesnet.Core2/YamlData.cs b/src/Jamesnet.Core2/YamlData.cs new file mode 100644 index 0000000..7bc0b31 --- /dev/null +++ b/src/Jamesnet.Core2/YamlData.cs @@ -0,0 +1,7 @@ +namespace Jamesnet.Core; + +public class YamlData : List +{ + public YamlData() : base() { } + public YamlData(IEnumerable collection) : base(collection) { } +} diff --git a/src/Jamesnet.Core2/YamlExtensions.cs b/src/Jamesnet.Core2/YamlExtensions.cs new file mode 100644 index 0000000..85412a8 --- /dev/null +++ b/src/Jamesnet.Core2/YamlExtensions.cs @@ -0,0 +1,20 @@ +namespace Jamesnet.Core; + +public static class YamlExtensions +{ + public static T GetValue(this IReadOnlyDictionary dict, string key, T defaultValue = default) + { + if (dict.TryGetValue(key, out string value)) + { + try + { + return (T)Convert.ChangeType(value, typeof(T)); + } + catch + { + return defaultValue; + } + } + return defaultValue; + } +} diff --git a/src/Jamesnet.Core2/YamlItem.cs b/src/Jamesnet.Core2/YamlItem.cs new file mode 100644 index 0000000..f78e80e --- /dev/null +++ b/src/Jamesnet.Core2/YamlItem.cs @@ -0,0 +1,18 @@ +namespace Jamesnet.Core; + +public class YamlItem : Dictionary +{ + public YamlItem() : base() { } + + public YamlItem(IDictionary dictionary) : base(dictionary) { } + + public T GetValue(string key) + { + string value; + if (TryGetValue(key, out value)) + { + return (T)Convert.ChangeType(value, typeof(T)); + } + return default(T); + } +} diff --git a/src/Leagueoflegends.WinUI3.sln b/src/Leagueoflegends.WinUI3.sln index 7371091..cdfbc13 100644 --- a/src/Leagueoflegends.WinUI3.sln +++ b/src/Leagueoflegends.WinUI3.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 17.11.35303.130 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leagueoflegends", "Leagueoflegends\Leagueoflegends.csproj", "{E2C762EC-6430-45BE-8274-0B72EF545857}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jamesnet.Core", "Jamesnet.Core\Jamesnet.Core.csproj", "{8EEF56C6-5B62-4C1E-8B4F-1A773144F101}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jamesnet.WinUI3", "Jamesnet.WinUI3\Jamesnet.WinUI3.csproj", "{BCAB0F11-1D0E-409F-BFF7-5180EECC3EDA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Leagueoflegends.Main", "Leagueoflegends.Main\Leagueoflegends.Main.csproj", "{502F2EBB-F5F2-4E65-9C2E-E213C45F909F}" @@ -41,6 +39,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Foundation", "Foundation", EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Partial", "Partial", "{21F3F9AA-0CA6-428A-883C-47AEEABA91B8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jamesnet.Core", "Jamesnet.Core\Jamesnet.Core.csproj", "{EB09F503-3FBC-40CF-B04E-A59D6AEB595D}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -77,22 +77,6 @@ Global {E2C762EC-6430-45BE-8274-0B72EF545857}.Release|x86.ActiveCfg = Release|x86 {E2C762EC-6430-45BE-8274-0B72EF545857}.Release|x86.Build.0 = Release|x86 {E2C762EC-6430-45BE-8274-0B72EF545857}.Release|x86.Deploy.0 = Release|x86 - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|ARM64.Build.0 = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|x64.ActiveCfg = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|x64.Build.0 = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|x86.ActiveCfg = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Debug|x86.Build.0 = Debug|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|Any CPU.Build.0 = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|ARM64.ActiveCfg = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|ARM64.Build.0 = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|x64.ActiveCfg = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|x64.Build.0 = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|x86.ActiveCfg = Release|Any CPU - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101}.Release|x86.Build.0 = Release|Any CPU {BCAB0F11-1D0E-409F-BFF7-5180EECC3EDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BCAB0F11-1D0E-409F-BFF7-5180EECC3EDA}.Debug|Any CPU.Build.0 = Debug|Any CPU {BCAB0F11-1D0E-409F-BFF7-5180EECC3EDA}.Debug|ARM64.ActiveCfg = Debug|Any CPU @@ -301,13 +285,28 @@ Global {DD4C7FD3-D576-45D2-94A8-6988FA66C607}.Release|x64.Build.0 = Release|Any CPU {DD4C7FD3-D576-45D2-94A8-6988FA66C607}.Release|x86.ActiveCfg = Release|Any CPU {DD4C7FD3-D576-45D2-94A8-6988FA66C607}.Release|x86.Build.0 = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|ARM64.Build.0 = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|x64.ActiveCfg = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|x64.Build.0 = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|x86.ActiveCfg = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Debug|x86.Build.0 = Debug|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|Any CPU.Build.0 = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|ARM64.ActiveCfg = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|ARM64.Build.0 = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|x64.ActiveCfg = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|x64.Build.0 = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|x86.ActiveCfg = Release|Any CPU + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {E2C762EC-6430-45BE-8274-0B72EF545857} = {624700EA-94CE-4783-9D7A-864A6C9E7FCB} - {8EEF56C6-5B62-4C1E-8B4F-1A773144F101} = {BF65155D-09F3-411B-ACBE-12D5D5A4C926} {BCAB0F11-1D0E-409F-BFF7-5180EECC3EDA} = {BF65155D-09F3-411B-ACBE-12D5D5A4C926} {502F2EBB-F5F2-4E65-9C2E-E213C45F909F} = {21F3F9AA-0CA6-428A-883C-47AEEABA91B8} {E2772AB7-51AC-45B2-AE3C-3D2EBB88492F} = {7F754BDB-3CB1-413D-8942-51A3C10CE64D} @@ -321,6 +320,7 @@ Global {1299D853-8DA4-431C-B194-34E44363FAF4} = {21F3F9AA-0CA6-428A-883C-47AEEABA91B8} {3A1CEA4B-DBA9-4188-8B43-84D626FE5F49} = {21F3F9AA-0CA6-428A-883C-47AEEABA91B8} {DD4C7FD3-D576-45D2-94A8-6988FA66C607} = {21F3F9AA-0CA6-428A-883C-47AEEABA91B8} + {EB09F503-3FBC-40CF-B04E-A59D6AEB595D} = {BF65155D-09F3-411B-ACBE-12D5D5A4C926} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7657BEB8-D088-4AA3-BA18-A87FAB8B9144}