This commit is contained in:
Wiesław Šoltés 2021-11-06 19:23:04 +01:00
Родитель 9fd35ec4c4
Коммит eb3e973ec7
5 изменённых файлов: 56 добавлений и 21 удалений

Просмотреть файл

@ -63,6 +63,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NodeEditorAvalonia.Reactive
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NodeEditorAvalonia.Model", "src\NodeEditorAvalonia.Model\NodeEditorAvalonia.Model.csproj", "{5DECE45D-598C-47F0-9776-2BE77A4572BC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NodeEditorAvalonia.Serializer", "src\NodeEditorAvalonia.Serializer\NodeEditorAvalonia.Serializer.csproj", "{9221D195-FCFF-4D53-B278-925A387ABA87}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -93,6 +95,10 @@ Global
{5DECE45D-598C-47F0-9776-2BE77A4572BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5DECE45D-598C-47F0-9776-2BE77A4572BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5DECE45D-598C-47F0-9776-2BE77A4572BC}.Release|Any CPU.Build.0 = Release|Any CPU
{9221D195-FCFF-4D53-B278-925A387ABA87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9221D195-FCFF-4D53-B278-925A387ABA87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9221D195-FCFF-4D53-B278-925A387ABA87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9221D195-FCFF-4D53-B278-925A387ABA87}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{861D1DD2-FDE9-492E-AEF6-E00F92F61EBD} = {02D6D6DC-21FA-435F-9526-E6F635127483}
@ -104,5 +110,6 @@ Global
{0737F4A8-E674-4518-A362-0A78D03F8165} = {17289397-391E-4F2E-A591-4AA3EEC80586}
{0866A0D7-055F-4FA0-8F9E-CED158F2DEA6} = {02D6D6DC-21FA-435F-9526-E6F635127483}
{5DECE45D-598C-47F0-9776-2BE77A4572BC} = {02D6D6DC-21FA-435F-9526-E6F635127483}
{9221D195-FCFF-4D53-B278-925A387ABA87} = {02D6D6DC-21FA-435F-9526-E6F635127483}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -18,10 +18,10 @@
<Import Project="..\..\build\Avalonia.ReactiveUI.props" />
<Import Project="..\..\build\Avalonia.Xaml.Behaviors.props" />
<Import Project="..\..\build\Avalonia.Controls.PanAndZoom.props" />
<Import Project="..\..\build\Newtonsoft.Json.props" Version="13.0.1" />
<ItemGroup>
<ProjectReference Include="..\..\src\NodeEditorAvalonia.ReactiveUI\NodeEditorAvalonia.ReactiveUI.csproj" />
<ProjectReference Include="..\..\src\NodeEditorAvalonia.Serializer\NodeEditorAvalonia.Serializer.csproj" />
<ProjectReference Include="..\..\src\NodeEditorAvalonia\NodeEditorAvalonia.csproj" />
</ItemGroup>

Просмотреть файл

@ -9,6 +9,7 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using NodeEditor.Model;
using NodeEditor.Serializer;
using NodeEditor.ViewModels;
using ReactiveUI;
@ -16,6 +17,7 @@ namespace NodeEditorDemo.ViewModels
{
public class MainWindowViewModel : ViewModelBase
{
private readonly INodeSerializer _serializer = new NodeSerializer(typeof(ObservableCollection<>));
private readonly NodeFactory _factory = new();
private ObservableCollection<INodeTemplate>? _templates;
private IDrawingNode? _drawing;
@ -69,7 +71,7 @@ namespace NodeEditorDemo.ViewModels
try
{
var json = await Task.Run(() => System.IO.File.ReadAllText(result.First()));
var drawing = NodeSerializer.Deserialize<DrawingNodeViewModel?>(json);
var drawing = _serializer.Deserialize<DrawingNodeViewModel?>(json);
if (drawing is { })
{
Drawing = drawing;
@ -96,7 +98,7 @@ namespace NodeEditorDemo.ViewModels
{
await Task.Run(() =>
{
var json = NodeSerializer.Serialize(_drawing);
var json = _serializer.Serialize(_drawing);
System.IO.File.WriteAllText(result, json);
});
}

Просмотреть файл

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
<IsPackable>True</IsPackable>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
<RootNamespace>NodeEditor.Serializer</RootNamespace>
</PropertyGroup>
<PropertyGroup>
<PackageId>NodeEditorAvalonia.Serializer</PackageId>
<Description>A node editor control for Avalonia.</Description>
<PackageTags>node;editor;nodeeditor;graph;control;xaml;axaml;avalonia;avaloniaui</PackageTags>
</PropertyGroup>
<Import Project="..\..\build\Base.props" />
<Import Project="..\..\build\SignAssembly.props" />
<Import Project="..\..\build\SourceLink.props" />
<Import Project="..\..\build\ReferenceAssemblies.props" />
<Import Project="..\..\build\Newtonsoft.Json.props" />
<ItemGroup>
<ProjectReference Include="..\NodeEditorAvalonia.Model\NodeEditorAvalonia.Model.csproj" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,32 +1,32 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NodeEditor.Model;
namespace NodeEditorDemo.ViewModels
namespace NodeEditor.Serializer
{
public static class NodeSerializer
public class NodeSerializer : INodeSerializer
{
private static readonly JsonSerializerSettings s_settings;
private readonly JsonSerializerSettings _settings;
private class ListContractResolver : DefaultContractResolver
{
private readonly Type _type;
private readonly Type _listType;
public ListContractResolver(Type type)
public ListContractResolver(Type listType)
{
_type = type;
_listType = listType;
}
public override JsonContract ResolveContract(Type type)
{
if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>))
{
return base.ResolveContract(_type.MakeGenericType(type.GenericTypeArguments[0]));
return base.ResolveContract(_listType.MakeGenericType(type.GenericTypeArguments[0]));
}
return base.ResolveContract(type);
}
@ -37,30 +37,30 @@ namespace NodeEditorDemo.ViewModels
}
}
static NodeSerializer()
public NodeSerializer(Type listType)
{
s_settings = new JsonSerializerSettings
_settings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Objects,
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
ContractResolver = new ListContractResolver(typeof(ObservableCollection<>)),
ContractResolver = new ListContractResolver(listType),
NullValueHandling = NullValueHandling.Ignore,
};
}
public static string Serialize<T>(T value)
public string Serialize<T>(T value)
{
return JsonConvert.SerializeObject(value, s_settings);
return JsonConvert.SerializeObject(value, _settings);
}
public static T Deserialize<T>(string text)
public T? Deserialize<T>(string text)
{
return JsonConvert.DeserializeObject<T>(text, s_settings)!;
return JsonConvert.DeserializeObject<T>(text, _settings);
}
public static T Load<T>(string path)
public T? Load<T>(string path)
{
using var stream = System.IO.File.OpenRead(path);
using var streamReader = new System.IO.StreamReader(stream, Encoding.UTF8);
@ -68,9 +68,9 @@ namespace NodeEditorDemo.ViewModels
return Deserialize<T>(text);
}
public static void Save<T>(string path, T value)
public void Save<T>(string path, T value)
{
var text = Serialize<T>(value);
var text = Serialize(value);
if (string.IsNullOrWhiteSpace(text)) return;
using var stream = System.IO.File.Create(path);
using var streamWriter = new System.IO.StreamWriter(stream, Encoding.UTF8);