1 Commits

Author SHA1 Message Date
3ae6e827a5 start implementation fo SimpleSorting 2023-08-09 09:25:06 +02:00
523 changed files with 7375 additions and 20190 deletions

View File

@@ -1,10 +0,0 @@
<Project>
<PropertyGroup>
<PackageProjectUrl>https://git.pilzinsel64.de/pilz-framework</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateSerializationAssemblies>False</GenerateSerializationAssemblies>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
</startup>
</configuration>

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>true</MySubMain>
<MainForm>Form1</MainForm>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>0</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,63 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.Collections.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@@ -1,16 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<StartupObject />
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Version>2.1.1</Version>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,89 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<StartupObject />
<MyType>Windows</MyType>
<TargetFramework>netstandard2.0</TargetFramework>
<DocumentationFile>Pilz.Collections.xml</DocumentationFile>
<DefineTrace>true</DefineTrace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,40008</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineDebug>false</DefineDebug>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DefineDebug>true</DefineDebug>
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,40008</NoWarn>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<UseVSHostingProcess>true</UseVSHostingProcess>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
<RemoveIntegerChecks>true</RemoveIntegerChecks>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Drawing" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Update="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Update="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Compile Remove="SimpleHistory\Enums.vb" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pilz.Cryptography\Pilz.Cryptography.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,12 @@
Namespace SimpleHistory
''' <summary>
''' Specify which member types you would include.
''' </summary>
Public Enum ObjectValueType
None = 0
Field = 1
[Property] = 2
End Enum
End Namespace

View File

@@ -1,615 +0,0 @@
using System.Data;
using System.Reflection;
namespace Pilz.Collections.SimpleHistory;
/// <summary>
/// Represent some Object States and Actions.
/// </summary>
public class HistoryPoint
{
/// <summary>
/// Represents the Name of this History Point
/// </summary>
/// <returns></returns>
public string Name { get; set; } = string.Empty;
/// <summary>
/// A List of Object States and Actions.
/// </summary>
/// <returns></returns>
public List<ObjectBase> Entries { get; } = [];
/// <summary>
/// Some data can be refered on this HistoryPoint. Don't know, in some situations this can be helpful.
/// </summary>
public readonly object? Tag = null;
public bool HasEntries<T>() where T : ObjectBase
{
return Entries.Where(n => n is T).Any();
}
internal void Undo()
{
foreach (var s in Entries.OrderBy(n => n.UndoPriority))
{
switch (s)
{
case ObjectState state:
state.Patch();
break;
case ObjectAction action:
action.Undo();
break;
}
}
}
internal void Redo()
{
foreach (var s in Entries.OrderBy(n => n.RedoPriority))
{
switch (s)
{
case ObjectState state:
state.Patch();
break;
case ObjectAction action:
action.Redo();
break;
}
}
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, MemberWhiteList whiteList)
{
return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, MemberBlackList blackList)
{
return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, params string[] memberName)
{
return FromObject(obj, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default);
else
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, params string[] memberName)
{
return FromObject(obj, membersToStore, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default);
else
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, BindingFlags flags, params string[] memberName)
{
return FromObject(obj, flags, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, BindingFlags flags, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags);
else
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName)
{
return FromObject(obj, flags, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags);
else
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, MemberWhiteList whiteList)
{
return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, MemberBlackList blackList)
{
return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, params string[] memberName)
{
return FromObject(obj, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default);
else
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, params string[] memberName)
{
return FromObject(obj, membersToStore, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default);
else
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, BindingFlags flags, params string[] memberName)
{
return FromObject(obj, flags, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, BindingFlags flags, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags);
else
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="memberName">The member names to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName)
{
return FromObject(obj, flags, true, memberName);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
/// <param name="memberName">The member names to include/exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName)
{
if (isWhiteList)
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags);
else
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj)
{
return FromObject([obj], ObjectValueType.None, default(object), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore)
{
return FromObject([obj], membersToStore, default(object), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList)
{
return FromObject([obj], membersToStore, (object)whiteList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList)
{
return FromObject([obj], membersToStore, (object)blackList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, BindingFlags flags)
{
return FromObject([obj], ObjectValueType.None, default(object), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags)
{
return FromObject([obj], membersToStore, default(object), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags)
{
return FromObject([obj], membersToStore, (object)whiteList, flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="obj">The object that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags)
{
return FromObject([obj], membersToStore, (object)blackList, flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs)
{
return FromObject(objs, ObjectValueType.None, default(object), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore)
{
return FromObject(objs, membersToStore, default(object), BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList)
{
return FromObject(objs, membersToStore, (object)whiteList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList)
{
return FromObject(objs, membersToStore, (object)blackList, BindingFlags.Default);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, BindingFlags flags)
{
return FromObject(objs, ObjectValueType.None, default(object), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, BindingFlags flags)
{
return FromObject(objs, membersToStore, default(object), flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="whiteList">Specify which members to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags)
{
return FromObject(objs, membersToStore, (object)whiteList, flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="blackList">Specify which members to exclude.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags)
{
return FromObject(objs, membersToStore, (object)blackList, flags);
}
/// <summary>
/// Creates an History Point with Object States automaticly from input.
/// </summary>
/// <param name="objs">The objects that should be included.</param>
/// <param name="membersToStore">Specify what member types to include.</param>
/// <param name="whiteOrBlackList">Specify which members to include.</param>
/// <param name="flags">The Binding Flags that the members should have.</param>
/// <returns>A History Point with Object States.</returns>
private static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, object? whiteOrBlackList, BindingFlags flags)
{
var hp = new HistoryPoint();
whiteOrBlackList ??= new MemberBlackList();
var isWhiteList = whiteOrBlackList is MemberWhiteList;
if (flags == BindingFlags.Default)
flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
if (membersToStore == ObjectValueType.None)
membersToStore = ObjectValueType.Field | ObjectValueType.Property;
foreach (var obj in objs)
{
if ((membersToStore & ObjectValueType.Field) == ObjectValueType.Field)
{
foreach (var fi in obj.GetType().GetFields(flags))
{
var contains = ((List<string>)whiteOrBlackList).Contains(fi.Name);
if (isWhiteList ? contains : !contains)
{
var os = new ObjectState
{
Object = obj,
MemberName = fi.Name,
MemberType = ObjectValueType.Field,
MemberFlags = flags,
ValueToPatch = fi.GetValue(obj)
};
hp.Entries.Add(os);
}
}
}
if ((membersToStore & ObjectValueType.Property) == ObjectValueType.Property)
{
foreach (var pi in obj.GetType().GetProperties(flags))
{
var contains = ((List<string>)whiteOrBlackList).Contains(pi.Name);
if (isWhiteList ? contains : !contains)
{
var os = new ObjectState
{
Object = obj,
MemberName = pi.Name,
MemberType = ObjectValueType.Property,
MemberFlags = flags,
ValueToPatch = pi.GetValue(obj)
};
hp.Entries.Add(os);
}
}
}
}
return hp;
}
/// <summary>
/// Combines some History Points to one.
/// </summary>
/// <param name="hps">An array of History Points to combine.</param>
/// <returns>One History Point that contains all Data of inputted History Points.</returns>
public static HistoryPoint Concat(params HistoryPoint[] hps)
{
return Concat(null, hps);
}
/// <summary>
/// Combines some History Points to one.
/// </summary>
/// <param name="hps">An array of History Points to combine.</param>
/// <param name="newName">The new name for the History Point after concating.</param>
/// <returns>One History Point that contains all Data of inputted History Points.</returns>
public static HistoryPoint Concat(string? newName, params HistoryPoint[] hps)
{
var hp = new HistoryPoint();
foreach (var _hp in hps)
hp.Entries.AddRange(_hp.Entries);
if (newName != null)
hp.Name = newName;
else
hp.Name = hps.FirstOrDefault()?.Name ?? string.Empty;
return hp;
}
}

View File

@@ -0,0 +1,543 @@
Imports System.Reflection
Namespace SimpleHistory
''' <summary>
''' Represent some Object States and Actions.
''' </summary>
Public Class HistoryPoint
''' <summary>
''' Represents the Name of this History Point
''' </summary>
''' <returns></returns>
Public Property Name As String = ""
''' <summary>
''' A List of Object States and Actions.
''' </summary>
''' <returns></returns>
Public ReadOnly Property Entries As New List(Of ObjectBase)
''' <summary>
''' Some data can be refered on this HistoryPoint. Don't know, in some situations this can be helpful.
''' </summary>
Public ReadOnly Tag As Object = Nothing
Public Function HasEntries(Of T As ObjectBase)() As Boolean
Return Entries.Where(Function(n) TypeOf n Is T).Count > 0
End Function
Friend Sub Undo()
For Each s As ObjectBase In Entries.OrderBy(Function(n) n.UndoPriority)
If TypeOf s Is ObjectState Then
CType(s, ObjectState).Patch()
ElseIf TypeOf s Is ObjectAction Then
CType(s, ObjectAction).Undo()
End If
Next
End Sub
Friend Sub Redo()
For Each s As ObjectBase In Entries.OrderBy(Function(n) n.RedoPriority)
If TypeOf s Is ObjectState Then
CType(s, ObjectState).Patch()
ElseIf TypeOf s Is ObjectAction Then
CType(s, ObjectAction).Redo()
End If
Next
End Sub
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), whiteList As MemberWhiteList) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(whiteList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), blackList As MemberBlackList) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(blackList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
Else
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, membersToStore, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
Else
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, flags, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), flags)
Else
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), flags)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, flags, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), flags)
Else
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), flags)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, whiteList As MemberWhiteList) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(whiteList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, blackList As MemberBlackList) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(blackList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
Else
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, membersToStore, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
Else
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, flags, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), flags)
Else
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), flags)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="memberName">The member names to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
Return FromObject(obj, flags, True, memberName)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
''' <param name="memberName">The member names to include/exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
If isWhiteList Then
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), flags)
Else
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), flags)
End If
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(Nothing), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(Nothing), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, whiteList As MemberWhiteList) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(whiteList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, blackList As MemberBlackList) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(blackList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, flags As BindingFlags) As HistoryPoint
Return FromObject({obj}, ObjectValueType.None, CObj(Nothing), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(Nothing), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, whiteList As MemberWhiteList, flags As BindingFlags) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(whiteList), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="obj">The object that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, blackList As MemberBlackList, flags As BindingFlags) As HistoryPoint
Return FromObject({obj}, membersToStore, CObj(blackList), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object()) As HistoryPoint
Return FromObject(objs, ObjectValueType.None, CObj(Nothing), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(Nothing), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteList As MemberWhiteList) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(whiteList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, blackList As MemberBlackList) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(blackList), BindingFlags.Default)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), flags As BindingFlags) As HistoryPoint
Return FromObject(objs, ObjectValueType.None, CObj(Nothing), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, flags As BindingFlags) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(Nothing), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="whiteList">Specify which members to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteList As MemberWhiteList, flags As BindingFlags) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(whiteList), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="blackList">Specify which members to exclude.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, blackList As MemberBlackList, flags As BindingFlags) As HistoryPoint
Return FromObject(objs, membersToStore, CObj(blackList), flags)
End Function
''' <summary>
''' Creates an History Point with Object States automaticly from input.
''' </summary>
''' <param name="objs">The objects that should be included.</param>
''' <param name="membersToStore">Specify what member types to include.</param>
''' <param name="whiteOrBlackList">Specify which members to include.</param>
''' <param name="flags">The Binding Flags that the members should have.</param>
''' <returns>A History Point with Object States.</returns>
Private Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteOrBlackList As Object, flags As BindingFlags) As HistoryPoint
Dim hp As New HistoryPoint
If whiteOrBlackList Is Nothing Then whiteOrBlackList = New MemberBlackList
Dim isWhiteList As Boolean = TypeOf whiteOrBlackList Is MemberWhiteList
If flags = BindingFlags.Default Then
flags = BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
End If
If membersToStore = ObjectValueType.None Then
membersToStore = ObjectValueType.Field Or ObjectValueType.Property
End If
For Each obj As Object In objs
If (membersToStore And ObjectValueType.Field) = ObjectValueType.Field Then
For Each fi As FieldInfo In obj.GetType.GetFields(flags)
Dim contains As Boolean = CType(whiteOrBlackList, List(Of String)).Contains(fi.Name)
If If(isWhiteList, contains, Not contains) Then
Dim os As New ObjectState
os.Object = obj
os.MemberName = fi.Name
os.MemberType = ObjectValueType.Field
os.MemberFlags = flags
os.ValueToPatch = fi.GetValue(obj)
hp.Entries.Add(os)
End If
Next
End If
If (membersToStore And ObjectValueType.Property) = ObjectValueType.Property Then
For Each pi As PropertyInfo In obj.GetType.GetProperties(flags)
Dim contains As Boolean = CType(whiteOrBlackList, List(Of String)).Contains(pi.Name)
If If(isWhiteList, contains, Not contains) Then
Dim os As New ObjectState
os.Object = obj
os.MemberName = pi.Name
os.MemberType = ObjectValueType.Property
os.MemberFlags = flags
os.ValueToPatch = pi.GetValue(obj)
hp.Entries.Add(os)
End If
Next
End If
Next
Return hp
End Function
''' <summary>
''' Combines some History Points to one.
''' </summary>
''' <param name="hps">An array of History Points to combine.</param>
''' <returns>One History Point that contains all Data of inputted History Points.</returns>
Public Shared Function Concat(ParamArray hps As HistoryPoint()) As HistoryPoint
Return Concat(hps.FirstOrDefault?.Name, hps)
End Function
''' <summary>
''' Combines some History Points to one.
''' </summary>
''' <param name="hps">An array of History Points to combine.</param>
''' <returns>One History Point that contains all Data of inputted History Points.</returns>
Public Shared Function Concat(newName As String, ParamArray hps As HistoryPoint()) As HistoryPoint
Dim hp As New HistoryPoint
For Each _hp As HistoryPoint In hps
hp.Entries.AddRange(_hp.Entries)
Next
Return hp
End Function
End Class
End Namespace

View File

@@ -1,31 +0,0 @@
namespace Pilz.Collections.SimpleHistory;
/// <summary>
/// List contianing member names to include.
/// </summary>
public class MemberWhiteList : List<string>
{
public MemberWhiteList() : base()
{
}
public MemberWhiteList(string[] entries) : base(entries)
{
}
}
/// <summary>
/// List contianing member names to exclude
/// </summary>
public class MemberBlackList : List<string>
{
public MemberBlackList() : base()
{
}
public MemberBlackList(string[] entries) : base(entries)
{
}
}

View File

@@ -0,0 +1,33 @@
Namespace SimpleHistory
''' <summary>
''' List contianing member names to include.
''' </summary>
Public Class MemberWhiteList
Inherits List(Of String)
Public Sub New()
MyBase.New
End Sub
Public Sub New(entries As String())
MyBase.New(entries)
End Sub
End Class
''' <summary>
''' List contianing member names to exclude
''' </summary>
Public Class MemberBlackList
Inherits List(Of String)
Public Sub New()
MyBase.New
End Sub
Public Sub New(entries As String())
MyBase.New(entries)
End Sub
End Class
End Namespace

View File

@@ -1,176 +0,0 @@
using System.Reflection;
namespace Pilz.Collections.SimpleHistory;
public class ObjectAction : ObjectBase
{
public object? Object { get; set; } = null;
public List<object> ParametersUndo { get; } = [];
public List<object> ParametersRedo { get; } = [];
public MethodInfo? MethodUndo { get; set; } = null;
public MethodInfo? MethodRedo { get; set; } = null;
public bool AutogenerateObject { get; set; } = true;
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
public ObjectAction()
{
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], BindingFlags.Default, BindingFlags.Default)
{
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodNameUndo, methodNameRedo, paramsUndo, paramsRedo, BindingFlags.Default, BindingFlags.Default)
{
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
/// <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
/// <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo)
{
Object = obj;
ParametersUndo.AddRange(paramsUndo);
ParametersRedo.AddRange(paramsRedo);
MethodUndo = GetMethodInfo(obj, methodNameUndo, GetFlags(methodFlagsUndo));
MethodRedo = GetMethodInfo(obj, methodNameRedo, GetFlags(methodFlagsRedo));
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
/// <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
/// <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], methodFlagsUndo, methodFlagsRedo)
{
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
/// <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo)
{
Object = obj;
MethodUndo = methodUndo;
MethodRedo = methodRedo;
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
/// <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo)
{
ParametersUndo.AddRange(paramsUndo);
ParametersRedo.AddRange(paramsRedo);
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
/// <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo)
{
Object = obj;
MethodUndo = methodUndo.Method;
MethodRedo = methodRedo.Method;
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
/// <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo)
{
ParametersUndo.AddRange(paramsUndo);
ParametersRedo.AddRange(paramsRedo);
}
/// <summary>
/// Creates a new Instance of Object Action.
/// </summary>
/// <param name="obj">The Objects that contains the methodes to call.</param>
/// <param name="methodUndo">The Action of the methode to call on Undo.</param>
/// <param name="methodRedo">The Action of the methode to call on Redo.</param>
public ObjectAction(object obj, Action methodUndo, Action methodRedo)
{
Object = obj;
MethodUndo = methodUndo.Method;
MethodRedo = methodRedo.Method;
}
private static BindingFlags GetFlags(BindingFlags flags)
{
if (flags == BindingFlags.Default)
flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
return flags;
}
private static MethodInfo? GetMethodInfo(object obj, string name, BindingFlags flags)
{
return obj.GetType().GetMethod(name, flags);
}
internal void Undo()
{
CheckIfObjIsNothing(MethodUndo);
MethodUndo?.Invoke(Object, ParametersUndo.ToArray());
}
internal void Redo()
{
CheckIfObjIsNothing(MethodRedo);
MethodRedo?.Invoke(Object, ParametersRedo.ToArray());
}
private void CheckIfObjIsNothing(MethodInfo? mi)
{
if (mi is not null && !mi.IsStatic && AutogenerateObject)
{
if ((Object is null || Object.GetType() != mi.ReflectedType) && !mi.IsStatic)
{
var constructor = mi.ReflectedType?.GetConstructor(Type.EmptyTypes);
var classObject = constructor?.Invoke([]);
Object = classObject;
}
}
}
}

View File

@@ -0,0 +1,165 @@
Imports System.Reflection
Imports System.Runtime.InteropServices
Namespace SimpleHistory
Public Class ObjectAction
Inherits ObjectBase
Public Property [Object] As Object = Nothing
Public ReadOnly Property ParametersUndo As New List(Of Object)
Public ReadOnly Property ParametersRedo As New List(Of Object)
Public Property MethodUndo As MethodInfo = Nothing
Public Property MethodRedo As MethodInfo = Nothing
Public Property AutogenerateObject As Boolean = True
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
Public Sub New()
End Sub
Private Function GetMethodInfo(obj As Object, name As String, flags As BindingFlags)
Return obj.GetType.GetMethod(name, flags)
End Function
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String)
Me.New(obj, methodNameUndo, methodNameRedo, {}, {}, BindingFlags.Default, BindingFlags.Default)
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, paramsUndo As Object(), paramsRedo As Object())
Me.New(obj, methodNameUndo, methodNameRedo, paramsUndo, paramsRedo, BindingFlags.Default, BindingFlags.Default)
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
''' <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
''' <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, paramsUndo As Object(), paramsRedo As Object(), methodFlagsUndo As BindingFlags, methodFlagsRedo As BindingFlags)
[Object] = obj
ParametersUndo.AddRange(paramsUndo)
ParametersRedo.AddRange(paramsRedo)
MethodUndo = GetMethodInfo(obj, methodNameUndo, GetFlags(methodFlagsUndo))
MethodRedo = GetMethodInfo(obj, methodNameRedo, GetFlags(methodFlagsRedo))
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
''' <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
''' <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, methodFlagsUndo As BindingFlags, methodFlagsRedo As BindingFlags)
Me.New(obj, methodNameUndo, methodNameRedo, {}, {}, methodFlagsUndo, methodFlagsRedo)
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
''' <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
Public Sub New(obj As Object, methodUndo As MethodInfo, methodRedo As MethodInfo)
[Object] = obj
Me.MethodUndo = methodUndo
Me.MethodRedo = methodRedo
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
''' <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
Public Sub New(obj As Object, methodUndo As MethodInfo, methodRedo As MethodInfo, paramsUndo As Object(), paramsRedo As Object())
Me.New(obj, methodUndo, methodRedo)
ParametersUndo.AddRange(paramsUndo)
ParametersRedo.AddRange(paramsRedo)
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
''' <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
Public Sub New(obj As Object, methodUndo As [Delegate], methodRedo As [Delegate])
[Object] = obj
Me.MethodUndo = methodUndo.Method
Me.MethodRedo = methodRedo.Method
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
''' <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
Public Sub New(obj As Object, methodUndo As [Delegate], methodRedo As [Delegate], paramsUndo As Object(), paramsRedo As Object())
Me.New(obj, methodUndo, methodRedo)
ParametersUndo.AddRange(paramsUndo)
ParametersRedo.AddRange(paramsRedo)
End Sub
''' <summary>
''' Creates a new Instance of Object Action.
''' </summary>
''' <param name="obj">The Objects that contains the methodes to call.</param>
''' <param name="methodUndo">The Action of the methode to call on Undo.</param>
''' <param name="methodRedo">The Action of the methode to call on Redo.</param>
Public Sub New(obj As Object, methodUndo As Action, methodRedo As Action)
[Object] = obj
Me.MethodUndo = methodUndo.Method
Me.MethodRedo = methodRedo.Method
End Sub
Private Function GetFlags(flags As BindingFlags) As BindingFlags
If flags = BindingFlags.Default Then
flags = BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
End If
Return flags
End Function
Friend Sub Undo()
CheckIfObjIsNothing(MethodUndo)
MethodUndo?.Invoke([Object], ParametersUndo.ToArray)
End Sub
Friend Sub Redo()
CheckIfObjIsNothing(MethodRedo)
MethodRedo?.Invoke([Object], ParametersRedo.ToArray)
End Sub
Private Sub CheckIfObjIsNothing(mi As MethodInfo)
If mi IsNot Nothing AndAlso Not mi.IsStatic AndAlso AutogenerateObject Then
If (Me.Object Is Nothing OrElse Me.Object.GetType <> mi.ReflectedType) AndAlso Not mi.IsStatic Then
Dim constructor As ConstructorInfo = mi.ReflectedType.GetConstructor(Type.EmptyTypes)
Dim classObject As Object = constructor.Invoke({})
Me.Object = classObject
End If
End If
End Sub
End Class
End Namespace

View File

@@ -1,10 +0,0 @@
namespace Pilz.Collections.SimpleHistory;
public class ObjectBase
{
public static int DefaultPriorityValue { get; set; } = 1000;
public int UndoPriority { get; set; } = DefaultPriorityValue;
public int RedoPriority { get; set; } = DefaultPriorityValue;
}

View File

@@ -0,0 +1,13 @@
Namespace SimpleHistory
Public Class ObjectBase
Public Shared Property DefaultPriorityValue As Integer = 1000
Public Property UndoPriority As Integer = DefaultPriorityValue
Public Property RedoPriority As Integer = DefaultPriorityValue
End Class
End Namespace

View File

@@ -1,88 +0,0 @@
using System.Reflection;
namespace Pilz.Collections.SimpleHistory;
public class ObjectState : ObjectBase
{
/// <summary>
/// The Object including the members to patch.
/// </summary>
/// <returns></returns>
public object? Object { get; set; } = null;
/// <summary>
/// The name of the Member to patch.
/// </summary>
/// <returns></returns>
public string MemberName { get; set; } = "";
/// <summary>
/// The Value that should be patched.
/// </summary>
/// <returns></returns>
public object? ValueToPatch { get; set; } = null;
/// <summary>
/// The member types to include at searching for the member.
/// </summary>
/// <returns></returns>
public ObjectValueType MemberType { get; set; } = ObjectValueType.Field;
/// <summary>
/// The Binding Flags that are used at searching for the member.
/// </summary>
/// <returns></returns>
public BindingFlags MemberFlags { get; set; } = BindingFlags.Default;
/// <summary>
/// Creates a new Instance of ObjectState from input.
/// </summary>
/// <param name="obj">The Object including the members to patch.</param>
/// <param name="valname">The name of the Member to patch.</param>
/// <param name="valToPatch">The member types to include at searching for the member.</param>
/// <param name="valtype">The Binding Flags that are used at searching for the member.</param>
public ObjectState(object obj, string valname, object valToPatch, ObjectValueType valtype)
{
Object = obj;
MemberName = valname;
ValueToPatch = valToPatch;
MemberType = valtype;
}
/// <summary>
/// Creates a new Instance of ObjectState.
/// </summary>
public ObjectState()
{
}
internal void Patch()
{
if (Object is null)
return;
var t = Object.GetType();
switch (MemberType)
{
case ObjectValueType.Field:
if (t.GetField(MemberName, MemberFlags) is FieldInfo f)
{
var temp = f.GetValue(Object);
f.SetValue(Object, ValueToPatch);
ValueToPatch = temp;
}
break;
case ObjectValueType.Property:
if (t.GetProperty(MemberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) is PropertyInfo p)
{
var temp = p.GetValue(Object);
p.SetValue(Object, ValueToPatch);
ValueToPatch = temp;
}
break;
default:
throw new Exception("ValueType is invalid!");
}
}
}

View File

@@ -0,0 +1,84 @@
Imports System.Reflection
Namespace SimpleHistory
Public Class ObjectState
Inherits ObjectBase
''' <summary>
''' The Object including the members to patch.
''' </summary>
''' <returns></returns>
Public Property [Object] As Object = Nothing
''' <summary>
''' The name of the Member to patch.
''' </summary>
''' <returns></returns>
Public Property MemberName As String = ""
''' <summary>
''' The Value that should be patched.
''' </summary>
''' <returns></returns>
Public Property ValueToPatch As Object = Nothing
''' <summary>
''' The member types to include at searching for the member.
''' </summary>
''' <returns></returns>
Public Property MemberType As ObjectValueType = ObjectValueType.Field
''' <summary>
''' The Binding Flags that are used at searching for the member.
''' </summary>
''' <returns></returns>
Public Property MemberFlags As BindingFlags = BindingFlags.Default
''' <summary>
''' Creates a new Instance of ObjectState from input.
''' </summary>
''' <param name="obj">The Object including the members to patch.</param>
''' <param name="valname">The name of the Member to patch.</param>
''' <param name="valToPatch">The member types to include at searching for the member.</param>
''' <param name="valtype">The Binding Flags that are used at searching for the member.</param>
Public Sub New(obj As Object, valname As String, valToPatch As Object, valtype As ObjectValueType)
[Object] = obj
MemberName = valname
ValueToPatch = valToPatch
MemberType = valtype
End Sub
''' <summary>
''' Creates a new Instance of ObjectState.
''' </summary>
Public Sub New()
End Sub
Friend Sub Patch()
Dim t As Type = [Object].GetType
Select Case MemberType
Case ObjectValueType.Field
Dim f As FieldInfo = t.GetField(MemberName, MemberFlags)
Dim temp As Object = Nothing
If f IsNot Nothing Then
temp = f.GetValue([Object])
f.SetValue([Object], ValueToPatch)
ValueToPatch = temp
End If
Case ObjectValueType.Property
Dim p As PropertyInfo = t.GetProperty(MemberName, BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static)
Dim temp As Object = Nothing
If p IsNot Nothing Then
temp = p.GetValue([Object])
p.SetValue([Object], ValueToPatch)
ValueToPatch = temp
End If
Case Else
Throw New Exception("ValueType is invalid!")
End Select
End Sub
End Class
End Namespace

View File

@@ -1,11 +0,0 @@
namespace Pilz.Collections.SimpleHistory;
/// <summary>
/// Specify which member types you would include.
/// </summary>
public enum ObjectValueType
{
None = 0,
Field = 1,
Property = 2,
}

View File

@@ -0,0 +1,12 @@
Namespace SimpleHistory
''' <summary>
''' Specify which member types you would include.
''' </summary>
Public Enum ObjectValueType
None = 0
Field = 1
[Property] = 2
End Enum
End Namespace

View File

@@ -1,101 +0,0 @@
namespace Pilz.Collections.SimpleHistory;
public class HistoryStack
{
private readonly Stack<HistoryPoint> stackPast = new();
private readonly Stack<HistoryPoint> stackFuture = new();
/// <summary>
/// Gets the count of history points.
/// </summary>
/// <returns></returns>
public int ChangesCount => stackPast.Count;
/// <summary>
/// Gets the current stack of all past HistoryPoints that are used for the Undo function.
/// </summary>
/// <returns></returns>
public HistoryPoint[] PastHistoryPoints => [.. stackPast];
/// <summary>
/// Gets the current stack of all future HistoryPoints that are used for the Redo function.
/// </summary>
/// <returns></returns>
public HistoryPoint[] FutureHistoryPoints => [.. stackFuture];
/// <summary>
/// Checks if the History has past changes.
/// </summary>
/// <returns></returns>
public bool HasChanges() => stackPast.Count > 0;
/// <summary>
/// Patch Object States and call Undo Actions.
/// </summary>
public HistoryPoint? Undo()
{
HistoryPoint? ret;
if (stackPast.Count > 0)
{
var hp = stackPast.Pop();
hp.Undo();
stackFuture.Push(hp);
ret = hp;
}
else
ret = null;
return ret;
}
/// <summary>
/// Patch Object States and call Redo Actions.
/// </summary>
public HistoryPoint? Redo()
{
HistoryPoint? ret;
if (stackFuture.Count > 0)
{
var hp = stackFuture.Pop();
hp.Redo();
stackPast.Push(hp);
ret = hp;
}
else
ret = null;
return ret;
}
/// <summary>
/// Clear the History.
/// </summary>
public void Clear()
{
stackPast.Clear();
stackFuture.Clear();
}
/// <summary>
/// Store a History Point.
/// </summary>
/// <param name="point">The History Point to add to the past changes.</param>
/// <param name="newName">The name to set for the History Point.</param>
public void Store(HistoryPoint point, string newName)
{
point.Name = newName;
Store(point);
}
/// <summary>
/// Store a History Point.
/// </summary>
/// <param name="point">The History Point to add to the past changes.</param>
public void Store(HistoryPoint point)
{
stackPast.Push(point);
stackFuture.Clear();
}
}

View File

@@ -0,0 +1,113 @@
Imports System.Reflection
Namespace SimpleHistory
Public Class HistoryStack
Private stackPast As New Stack(Of HistoryPoint)
Private stackFuture As New Stack(Of HistoryPoint)
''' <summary>
''' Gets the count of history points.
''' </summary>
''' <returns></returns>
Public ReadOnly Property ChangesCount As Boolean
Get
Return stackPast.Count
End Get
End Property
''' <summary>
''' Gets the current stack of all past HistoryPoints that are used for the Undo function.
''' </summary>
''' <returns></returns>
Public ReadOnly Property PastHistoryPoints As HistoryPoint()
Get
Return stackPast.ToArray
End Get
End Property
''' <summary>
''' Gets the current stack of all future HistoryPoints that are used for the Redo function.
''' </summary>
''' <returns></returns>
Public ReadOnly Property FutureHistoryPoints As HistoryPoint()
Get
Return stackFuture.ToArray
End Get
End Property
''' <summary>
''' Checks if the History has past changes.
''' </summary>
''' <returns></returns>
Public Function HasChanges() As Boolean
Return stackPast.Count > 0
End Function
''' <summary>
''' Patch Object States and call Undo Actions.
''' </summary>
Public Function Undo() As HistoryPoint
Dim ret As HistoryPoint
If stackPast.Count > 0 Then
Dim hp As HistoryPoint = stackPast.Pop
hp.Undo()
stackFuture.Push(hp)
ret = hp
Else
ret = Nothing
End If
Return ret
End Function
''' <summary>
''' Patch Object States and call Redo Actions.
''' </summary>
Public Function Redo() As HistoryPoint
Dim ret As HistoryPoint
If stackFuture.Count > 0 Then
Dim hp As HistoryPoint = stackFuture.Pop
hp.Redo()
stackPast.Push(hp)
ret = hp
Else
ret = Nothing
End If
Return ret
End Function
''' <summary>
''' Clear the History.
''' </summary>
Public Sub Clear()
stackPast.Clear()
stackFuture.Clear()
End Sub
''' <summary>
''' Store a History Point.
''' </summary>
''' <param name="point">The History Point to add to the past changes.</param>
''' <param name="newName">The name to set for the History Point.</param>
Public Sub Store(point As HistoryPoint, newName As String)
point.Name = newName
Store(point)
End Sub
''' <summary>
''' Store a History Point.
''' </summary>
''' <param name="point">The History Point to add to the past changes.</param>
Public Sub Store(point As HistoryPoint)
stackPast.Push(point)
stackFuture.Clear()
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,8 @@
Namespace SimpleSorting
Public Enum ElementSortingPosition
Before
After
End Enum
End Namespace

View File

@@ -0,0 +1,10 @@
Namespace SimpleSorting
Public Interface ISimpleSortingHost
Inherits IList
Event OnInsert(sender As Object, e As SimpleSortingHostEventArgs)
Event OnRemove(sender As Object, e As SimpleSortingHostEventArgs)
End Interface
End Namespace

View File

@@ -0,0 +1,13 @@
Imports Pilz.Cryptography
Namespace SimpleSorting
Friend Class SimpleSortingEntry
Public Property Element As UniquieID
Public Property Position As ElementSortingPosition
Public Property ReferenceElement As UniquieID
End Class
End Namespace

View File

@@ -0,0 +1,18 @@
Imports Pilz.Cryptography
Namespace SimpleSorting
Public Class SimpleSortingHostEventArgs
Inherits EventArgs
Public ReadOnly Property ElementID As UniquieID
Public ReadOnly Property ElementIndex As Integer
Public Sub New(elementID As UniquieID, elementIndex As Integer)
Me.ElementID = elementID
Me.ElementIndex = elementIndex
End Sub
End Class
End Namespace

View File

@@ -0,0 +1,121 @@
Imports System.Runtime.InteropServices.ComTypes
Imports Newtonsoft.Json
Imports Pilz.Cryptography
Namespace SimpleSorting
''' <summary>
''' Provides some management methods for sorting a list without changing the list itself.
''' Useful if the host list can not be changed or the sorting is indipendent from the required sorting.
''' </summary>
''' <typeparam name="T">The content of the host list to sort.</typeparam>
Public Class SimpleSortingList(Of T As IUniquieIDHost)
Private ReadOnly host As ISimpleSortingHost
<JsonProperty("SortingInfo")>
Private ReadOnly sortingList As New List(Of SimpleSortingEntry)
Public Sub New(parentList As ISimpleSortingHost)
host = parentList
AddHandler host.OnInsert, AddressOf Host_OnInsert
AddHandler host.OnRemove, AddressOf Host_OnRemove
End Sub
Protected Overrides Sub Finalize()
RemoveHandler host.OnInsert, AddressOf Host_OnInsert
RemoveHandler host.OnRemove, AddressOf Host_OnRemove
End Sub
Private Sub Host_OnInsert(sender As Object, e As SimpleSortingHostEventArgs)
'...
End Sub
Private Sub Host_OnRemove(sender As Object, e As SimpleSortingHostEventArgs)
'...
End Sub
''' <summary>
''' Stores positioning infos for the given element.
''' </summary>
''' <param name="elementID"></param>
''' <param name="position"></param>
''' <param name="referenceElementID"></param>
Public Sub SetElementPosition(elementID As UniquieID, position As ElementSortingPosition, referenceElementID As UniquieID)
'...
End Sub
''' <summary>
''' Removes the positioning infos for the given element if available.
''' </summary>
''' <param name="elementID"></param>
Public Sub RemoveElementPosition(elementID As UniquieID)
Dim infoToRemove = FindSortInfoByID(elementID)
If infoToRemove IsNot Nothing Then
sortingList.Remove(infoToRemove)
For Each info In sortingList
If info.ReferenceElement = elementID Then
info.ReferenceElement = infoToRemove.ReferenceElement
End If
Next
End If
End Sub
''' <summary>
''' Completely removes an element from all positioning infos. If possible, elements will be assigned to nearby reference or removed completely.
''' </summary>
''' <param name="elementID"></param>
Public Sub InvalidateElement(elementID As UniquieID)
'...
End Sub
''' <summary>
''' Creates a sorted list with all elements from the host list.
''' </summary>
''' <returns></returns>
Public Function GetSortedList() As List(Of T)
Dim list As New List(Of T)
list.AddRange(host)
For Each info In sortingList
Dim element As T = list.FirstOrDefault(Function(n) n.ID = info.Element)
Dim referenceElement As T = list.FirstOrDefault(Function(n) n.ID = info.ReferenceElement)
If element IsNot Nothing AndAlso referenceElement IsNot Nothing Then
list.Remove(element)
Dim referenceElementIndex As Integer = list.IndexOf(referenceElement)
If info.Position = ElementSortingPosition.After Then
referenceElementIndex += 1
End If
list.Insert(referenceElementIndex, element)
End If
Next
Return list
End Function
''' <summary>
''' Creates a sorted list with all elements from the host list.
''' </summary>
''' <returns></returns>
Public Function GetSortedArray() As T()
Return GetSortedList.ToArray
End Function
Private Function FindSortInfoByID(id As UniquieID) As SimpleSortingEntry
Return sortingList.FirstOrDefault(Function(n) n.Element = id)
End Function
Private Function FindSortInfoByReferenceID(id As UniquieID) As SimpleSortingEntry
Return sortingList.FirstOrDefault(Function(n) n.ReferenceElement = id)
End Function
End Class
End Namespace

View File

@@ -1,86 +0,0 @@
using System;
namespace Pilz.Configuration;
public class AutoSaveConfigurationManager : ConfigurationManager
{
private bool addedHandler = false;
private bool enableAutoSave = false;
private string _ConfigFilePath = string.Empty;
private bool _AutoLoadConfigOnAccess = false;
public string ConfigFilePath
{
get => _ConfigFilePath;
set
{
_ConfigFilePath = value;
if (AutoLoadConfigOnAccess)
Load();
}
}
public bool AutoLoadConfigOnAccess
{
get => _AutoLoadConfigOnAccess;
set
{
_AutoLoadConfigOnAccess = value;
if (value)
Load();
}
}
public bool AutoSaveConfigOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
AddAutoSaveHandler();
else
RemoveAutoSaveHandler();
}
}
}
private void AddAutoSaveHandler()
{
if (!addedHandler)
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
}
private void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
Save();
}
private void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
Configuration.WriteToFile(ConfigFilePath);
}
private void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath))
Configuration.ReadFromFile(ConfigFilePath);
}
~AutoSaveConfigurationManager()
{
RemoveAutoSaveHandler();
}
}

View File

@@ -0,0 +1,78 @@
Public Class AutoSaveConfigurationManager
Inherits ConfigurationManager
Private addedHandler As Boolean = False
Private enableAutoSave As Boolean = False
Private _ConfigFilePath As String = String.Empty
Private _AutoLoadConfigOnAccess As Boolean = False
Public Property ConfigFilePath As String
Get
Return _ConfigFilePath
End Get
Set
_ConfigFilePath = Value
If AutoLoadConfigOnAccess Then Load()
End Set
End Property
Public Property AutoLoadConfigOnAccess As Boolean
Get
Return _AutoLoadConfigOnAccess
End Get
Set
_AutoLoadConfigOnAccess = Value
If Value Then Load()
End Set
End Property
Public Property AutoSaveConfigOnExit As Boolean
Get
Return enableAutoSave
End Get
Set
If enableAutoSave <> Value Then
enableAutoSave = Value
Select Case enableAutoSave
Case True
AddAutoSaveHandler()
Case False
RemoveAutoSaveHandler()
End Select
End If
End Set
End Property
Private Sub AddAutoSaveHandler()
If Not addedHandler Then
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = True
End If
End Sub
Private Sub RemoveAutoSaveHandler()
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = False
End Sub
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
Save()
End Sub
Private Sub Save()
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso Configuration IsNot Nothing Then
Configuration.WriteToFile(ConfigFilePath)
End If
End Sub
Private Sub Load()
If Not String.IsNullOrEmpty(ConfigFilePath) Then
Configuration.ReadFromFile(ConfigFilePath)
End If
End Sub
Protected Overrides Sub Finalize()
RemoveAutoSaveHandler()
End Sub
End Class

View File

@@ -1,11 +0,0 @@
namespace Pilz.Configuration;
public abstract class ConfigurationManager
{
public SimpleConfiguration Configuration { get; private set; }
internal void SetConfiguration(SimpleConfiguration configuration)
{
Configuration = configuration;
}
}

View File

@@ -0,0 +1,9 @@
Public MustInherit Class ConfigurationManager
Public ReadOnly Property Configuration As SimpleConfiguration
Friend Sub SetConfiguration(configuration As SimpleConfiguration)
_Configuration = configuration
End Sub
End Class

View File

@@ -1,87 +0,0 @@
using Pilz.GeneralEventArgs;
using System.Collections;
using System.Collections.Generic;
namespace Pilz.Configuration;
public class ConfigurationManagerList : IList<ConfigurationManager>
{
public event GettingParentManagerEventHandler GettingParentManager;
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
private readonly List<ConfigurationManager> myList = [];
private object GetParentManager()
{
var args = new GetValueEventArgs<SimpleConfiguration>();
GettingParentManager?.Invoke(this, args);
return args.Value;
}
public ConfigurationManager this[int index]
{
get => myList[index];
set => myList[index] = value;
}
public int Count => myList.Count;
public bool IsReadOnly => false;
public void Insert(int index, ConfigurationManager item)
{
myList.Insert(index, item);
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void RemoveAt(int index)
{
}
public void Add(ConfigurationManager item)
{
item.SetConfiguration((SimpleConfiguration)GetParentManager());
}
public void Clear()
{
foreach (ConfigurationManager item in myList)
item.SetConfiguration(null);
myList.Clear();
}
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
{
myList.CopyTo(array, arrayIndex);
}
public int IndexOf(ConfigurationManager item)
{
return myList.IndexOf(item);
}
public bool Contains(ConfigurationManager item)
{
return myList.Contains(item);
}
public bool Remove(ConfigurationManager item)
{
item.SetConfiguration(null);
return myList.Remove(item);
}
public IEnumerator<ConfigurationManager> GetEnumerator()
{
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
}
private IEnumerator IEnumerable_GetEnumerator()
{
return myList.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
}

View File

@@ -0,0 +1,83 @@
Imports Pilz.Configuration
Imports Pilz.GeneralEventArgs
Public Class ConfigurationManagerList
Implements IList(Of ConfigurationManager)
Public Event GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
Private ReadOnly myList As New List(Of ConfigurationManager)
Private Function GetParentManager()
Dim args As New GetValueEventArgs(Of SimpleConfiguration)
RaiseEvent GettingParentManager(Me, args)
Return args.Value
End Function
Default Public Property Item(index As Integer) As ConfigurationManager Implements IList(Of ConfigurationManager).Item
Get
Return myList(index)
End Get
Set(value As ConfigurationManager)
myList(index) = value
End Set
End Property
Public ReadOnly Property Count As Integer Implements ICollection(Of ConfigurationManager).Count
Get
Return myList.Count
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of ConfigurationManager).IsReadOnly
Get
Return False
End Get
End Property
Public Sub Insert(index As Integer, item As ConfigurationManager) Implements IList(Of ConfigurationManager).Insert
myList.Insert(index, item)
item.SetConfiguration(GetParentManager)
End Sub
Public Sub RemoveAt(index As Integer) Implements IList(Of ConfigurationManager).RemoveAt
End Sub
Public Sub Add(item As ConfigurationManager) Implements ICollection(Of ConfigurationManager).Add
item.SetConfiguration(GetParentManager)
End Sub
Public Sub Clear() Implements ICollection(Of ConfigurationManager).Clear
For Each item As ConfigurationManager In myList
item.SetConfiguration(Nothing)
Next
myList.Clear()
End Sub
Public Sub CopyTo(array() As ConfigurationManager, arrayIndex As Integer) Implements ICollection(Of ConfigurationManager).CopyTo
myList.CopyTo(array, arrayIndex)
End Sub
Public Function IndexOf(item As ConfigurationManager) As Integer Implements IList(Of ConfigurationManager).IndexOf
Return myList.IndexOf(item)
End Function
Public Function Contains(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Contains
Return myList.Contains(item)
End Function
Public Function Remove(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Remove
item.SetConfiguration(Nothing)
Return myList.Remove(item)
End Function
Public Function GetEnumerator() As IEnumerator(Of ConfigurationManager) Implements IEnumerable(Of ConfigurationManager).GetEnumerator
Return IEnumerable_GetEnumerator()
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return myList.GetEnumerator
End Function
End Class

View File

@@ -1,138 +0,0 @@
using Newtonsoft.Json;
using Pilz.GeneralEventArgs;
using System.IO;
namespace Pilz.Configuration;
public static class ConfigurationSerializer
{
public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
{
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
GettingJsonSerializer?.Invoke(instance, args);
return args.Value;
}
/// <summary>
/// Writes the given instance to a string and return it.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <returns>The content of the configuration instance as string.</returns>
public static string WriteToString(SimpleConfiguration instance)
{
var tw = new StringWriter();
GetJsonSerializer(instance).Serialize(tw, instance);
string txt = tw.ToString();
tw.Close();
return txt;
}
/// <summary>
/// Write the given instance to a given stream.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <param name="stream">The stream where the content should be written to.</param>
public static void WriteToStream(SimpleConfiguration instance, Stream stream)
{
var sr = new StreamWriter(stream);
sr.Write(WriteToString(instance));
}
/// <summary>
/// Writes the given instance to the given filePath as text file.
/// </summary>
/// <param name="instance">The configuration instance that should be serialized.</param>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public static void WriteToFile(SimpleConfiguration instance, string filePath)
{
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
WriteToStream(instance, fs);
fs.Close();
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="content">The content of the configuration as string.</param>
/// <returns></returns>
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
{
var sr = new StringReader(content);
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
sr.Close();
return instance;
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="content">The content of the configuration as string.</param>
public static void ReadFromString(SimpleConfiguration instance, string content)
{
var sr = new StringReader(content);
GetJsonSerializer(null).Populate(sr, content);
sr.Close();
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
{
return ReadFromString<T>(GetContentOfStream(stream));
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="stream">The stream with the content of the configuration.</param>
public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
{
ReadFromString(instance, GetContentOfStream(stream));
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{
return ReadFromString<T>(GetContentOfFile(filePath));
}
/// <summary>
/// Read a configuration from the given string and put them to the given instance.
/// </summary>
/// <param name="instance">The instance to populate with the configuration.</param>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
public static void ReadFromFile(SimpleConfiguration instance, string filePath)
{
ReadFromString(instance, GetContentOfFile(filePath));
}
private static string GetContentOfStream(Stream stream)
{
var sr = new StreamReader(stream);
return sr.ReadToEnd();
}
private static string GetContentOfFile(string filePath)
{
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
string content = GetContentOfStream(fs);
fs.Close();
return content;
}
}

View File

@@ -0,0 +1,123 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Pilz.GeneralEventArgs
Public Module ConfigurationSerializer
Public Event GettingJsonSerializer(instance As Object, e As GetValueEventArgs(Of JsonSerializer))
Private Function GetJsonSerializer(instance As SimpleConfiguration) As JsonSerializer
Dim args As New GetValueEventArgs(Of JsonSerializer)(JsonSerializer.CreateDefault)
RaiseEvent GettingJsonSerializer(instance, args)
Return args.Value
End Function
''' <summary>
''' Writes the given instance to a string and return it.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <returns>The content of the configuration instance as string.</returns>
Public Function WriteToString(instance As SimpleConfiguration) As String
Dim tw As New StringWriter
GetJsonSerializer(instance).Serialize(tw, instance)
Dim txt = tw.ToString
tw.Close()
Return txt
End Function
''' <summary>
''' Write the given instance to a given stream.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <param name="stream">The stream where the content should be written to.</param>
Public Sub WriteToStream(instance As SimpleConfiguration, stream As Stream)
Dim sr As New StreamWriter(stream)
sr.Write(WriteToString(instance))
End Sub
''' <summary>
''' Writes the given instance to the given filePath as text file.
''' </summary>
''' <param name="instance">The configuration instance that should be serialized.</param>
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
Public Sub WriteToFile(instance As SimpleConfiguration, filePath As String)
Dim fs As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
WriteToStream(instance, fs)
fs.Close()
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="content">The content of the configuration as string.</param>
''' <returns></returns>
Public Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
Dim sr As New StringReader(content)
Dim instance As T = GetJsonSerializer(Nothing).Deserialize(sr, GetType(T))
sr.Close()
Return instance
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="content">The content of the configuration as string.</param>
Public Sub ReadFromString(instance As SimpleConfiguration, content As String)
Dim sr As New StringReader(content)
GetJsonSerializer(Nothing).Populate(sr, content)
sr.Close()
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="stream">The stream with the content of the configuration.</param>
''' <returns></returns>
Public Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
Return ReadFromString(Of T)(GetContentOfStream(stream))
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="stream">The stream with the content of the configuration.</param>
Public Sub ReadFromStream(instance As SimpleConfiguration, stream As Stream)
ReadFromString(instance, GetContentOfStream(stream))
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
''' <returns></returns>
Public Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
Return ReadFromString(Of T)(GetContentOfFile(filePath))
End Function
''' <summary>
''' Read a configuration from the given string and put them to the given instance.
''' </summary>
''' <param name="instance">The instance to populate with the configuration.</param>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
Public Sub ReadFromFile(instance As SimpleConfiguration, filePath As String)
ReadFromString(instance, GetContentOfFile(filePath))
End Sub
Private Function GetContentOfStream(stream As Stream) As String
Dim sr As New StreamReader(stream)
Return sr.ReadToEnd
End Function
Private Function GetContentOfFile(filePath As String) As String
Dim fs As New FileStream(filePath, FileMode.Open, FileAccess.Read)
Dim content = GetContentOfStream(fs)
fs.Close()
Return content
End Function
End Module

View File

@@ -1,16 +0,0 @@
using Castle.Core.Logging;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Pilz.Configuration;
public interface ISettings
{
IReadOnlyCollection<ISettingsNode> Childs { get; }
ILogger Logger { get; set; }
T Get<T>() where T : ISettingsNode, ISettingsIdentifier;
void Reset();
string Save(JsonSerializerSettings serializer);
bool Load(JsonSerializerSettings serializer, string raw);
}

View File

@@ -1,8 +0,0 @@
namespace Pilz.Configuration;
public interface ISettingsIdentifier
{
#if NET8_0_OR_GREATER
static abstract string Identifier { get; }
#endif
}

View File

@@ -1,10 +0,0 @@
namespace Pilz.Configuration;
public interface ISettingsManager
{
ISettings Instance { get; }
void Save();
void Load();
void Reset();
}

View File

@@ -0,0 +1,6 @@
Public Interface ISettingsManager
Property ConfigFilePath As String
Sub Save()
Sub Load()
Sub Reset()
End Interface

View File

@@ -1,11 +0,0 @@
using System;
namespace Pilz.Configuration;
public interface ISettingsNode
{
void Reset();
}
[Obsolete("Use ISettingsNode instead!")]
public interface IChildSettings : ISettingsNode;

View File

@@ -1,6 +0,0 @@
namespace Pilz.Configuration;
internal interface ISettingsValueOptionValueAccessor
{
public object ValueRaw { get; set; }
}

View File

@@ -0,0 +1,13 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<MySubMain>false</MySubMain>
<SingleInstance>false</SingleInstance>
<ShutdownMode>0</ShutdownMode>
<EnableVisualStyles>true</EnableVisualStyles>
<AuthenticationMode>0</AuthenticationMode>
<ApplicationType>1</ApplicationType>
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
</MyApplicationData>

View File

@@ -0,0 +1,63 @@
'------------------------------------------------------------------------------
' <auto-generated>
' Dieser Code wurde von einem Tool generiert.
' Laufzeitversion:4.0.30319.42000
'
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
' der Code erneut generiert wird.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Imports System
Namespace My.Resources
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
Friend Module Resources
Private resourceMan As Global.System.Resources.ResourceManager
Private resourceCulture As Global.System.Globalization.CultureInfo
'''<summary>
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
Get
If Object.ReferenceEquals(resourceMan, Nothing) Then
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.Configuration.Resources", GetType(Resources).Assembly)
resourceMan = temp
End If
Return resourceMan
End Get
End Property
'''<summary>
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
'''</summary>
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Friend Property Culture() As Global.System.Globalization.CultureInfo
Get
Return resourceCulture
End Get
Set
resourceCulture = value
End Set
End Property
End Module
End Namespace

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,22 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>disable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Version>3.2.8</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Castle.Core" Version="5.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pilz\Pilz.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,73 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MyType>Windows</MyType>
<TargetFramework>netstandard2.0</TargetFramework>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DocumentationFile>Pilz.Configuration.xml</DocumentationFile>
<DefineTrace>true</DefineTrace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DefineDebug>false</DefineDebug>
</PropertyGroup>
<PropertyGroup>
<OptionExplicit>On</OptionExplicit>
</PropertyGroup>
<PropertyGroup>
<OptionCompare>Binary</OptionCompare>
</PropertyGroup>
<PropertyGroup>
<OptionStrict>Off</OptionStrict>
</PropertyGroup>
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />
<Import Include="System.Collections" />
<Import Include="System.Collections.Generic" />
<Import Include="System.Data" />
<Import Include="System.Diagnostics" />
<Import Include="System.Linq" />
<Import Include="System.Xml.Linq" />
<Import Include="System.Threading.Tasks" />
</ItemGroup>
<ItemGroup>
<Compile Update="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
</Compile>
<Compile Update="My Project\Resources.Designer.vb">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="My Project\Resources.resx">
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
<CustomToolNamespace>My.Resources</CustomToolNamespace>
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>
<LastGenOutput>Application.Designer.vb</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pilz\Pilz.vbproj" />
</ItemGroup>
</Project>

View File

@@ -1,143 +0,0 @@
using Castle.Core.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace Pilz.Configuration;
public class Settings : ISettings
{
protected readonly Dictionary<string, JObject> settingsJson = [];
protected readonly Dictionary<string, ISettingsNode> settings = [];
protected JsonSerializerSettings serializerSettings;
public virtual IReadOnlyCollection<ISettingsNode> Childs => settings.Values;
public virtual ILogger Logger { get; set; } = NullLogger.Instance;
public virtual T Get<T>() where T : ISettingsNode, ISettingsIdentifier
{
// Find existing one
if (settings.TryGetValue(GetIdentifier<T>(), out var valueExisting) && valueExisting is T settingsExisting)
return settingsExisting;
// Create new & reset
if (Activator.CreateInstance<T>() is T settingsNew)
settingsNew.Reset();
else
{
settingsNew = default;
Logger.WarnFormat("Not able to create new settings node instance {0}.", GetIdentifier<T>());
}
// Try deserialize
if (settingsJson.TryGetValue(GetIdentifier<T>(), out var valueRaw))
{
var serializer = JsonSerializer.CreateDefault(serializerSettings);
// Populate
if (settingsNew != null)
{
try
{
serializer.Populate(valueRaw.CreateReader(), settingsNew);
Logger.InfoFormat("Populated settings node {0}.", GetIdentifier<T>());
}
catch (Exception ex)
{
Logger.Error("Error populating settings node instance.", ex);
}
}
// Deserialize (fallback)
else if (valueRaw.ToObject<T>() is T settingsDeserialized)
{
try
{
settingsNew = settingsDeserialized;
Logger.WarnFormat("Deserialied settings node {0} via fallback variant.", GetIdentifier<T>());
}
catch (Exception ex)
{
Logger.Error("Error deserializing settings node instance.", ex);
}
}
}
// Remember
if (settingsNew != null)
settings[GetIdentifier<T>()] = settingsNew;
// Return
return settingsNew;
}
public void Reset()
{
foreach (var s in settings.Values)
s.Reset();
}
public virtual string Save(JsonSerializerSettings serializerSettings)
{
this.serializerSettings = serializerSettings;
var serializer = JsonSerializer.CreateDefault(serializerSettings);
foreach (var kvp in settings)
{
var raw = JObject.FromObject(kvp.Value, serializer);
settingsJson[kvp.Key] = raw;
}
var objList = new JObject();
foreach (var kvp in settingsJson)
objList.Add(kvp.Key, kvp.Value);
var objSettings = new JObject
{
{ "Settings", objList }
};
return objSettings.ToString(serializer.Formatting);
}
public virtual bool Load(JsonSerializerSettings serializerSettings, string raw)
{
this.serializerSettings = serializerSettings;
var objSettings = JObject.Parse(raw);
if (!objSettings.TryGetValue("Settings", out var tokenList) || tokenList is not JObject objList)
return false;
settingsJson.Clear();
settings.Clear();
foreach (var child in objList)
{
if (child.Value is not JObject value)
continue;
settingsJson.Add(child.Key, value);
}
return true;
}
protected virtual JToken Serialize(object o, JsonSerializer jsonSerializer)
{
using JTokenWriter jTokenWriter = new JTokenWriter();
jsonSerializer.Serialize(jTokenWriter, o, o.GetType());
return jTokenWriter.Token;
}
protected static string GetIdentifier<T>() where T : ISettingsIdentifier
{
#if NET8_0_OR_GREATER
return T.Identifier;
#else
return typeof(T).GetProperty("Identifier", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).GetValue(null) as string;
#endif
}
}

View File

@@ -0,0 +1,20 @@
Imports Newtonsoft.Json
Public MustInherit Class SettingsBase
Public Sub New()
ResetValues()
End Sub
<JsonIgnore>
Friend _settingsManager As ISettingsManager
<JsonIgnore>
Public ReadOnly Property SettingsManager As ISettingsManager
Get
Return _settingsManager
End Get
End Property
Public MustOverride Sub ResetValues()
End Class

View File

@@ -1,145 +0,0 @@
using Newtonsoft.Json;
using System;
using System.IO;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
namespace Pilz.Configuration;
public class SettingsManager : ISettingsManager
{
public event EventHandler AutoSavingSettings;
public event EventHandler SavingSettings;
public event EventHandler SavedSettings;
public event EventHandler<ErrorEventArgs> OnSerializationError;
protected ISettings defaultInstance = null;
protected bool enableAutoSave = false;
protected bool addedHandler = false;
public string ConfigFilePath { get; set; }
public ISettings Instance
{
get
{
if (defaultInstance is null)
Load();
return defaultInstance;
}
}
public bool AutoSaveOnExit
{
get => enableAutoSave;
set
{
if (enableAutoSave != value)
{
enableAutoSave = value;
if (enableAutoSave)
{
if (!addedHandler)
AddAutoSaveHandler();
}
else
{
if (addedHandler)
RemoveAutoSaveHandler();
}
}
}
}
public SettingsManager()
{
}
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
{
ConfigFilePath = fileName;
AutoSaveOnExit = autoSaveOnExit;
}
protected void AddAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
addedHandler = true;
}
protected void RemoveAutoSaveHandler()
{
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
addedHandler = false;
}
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
{
AutoSavingSettings?.Invoke(this, new EventArgs());
Save();
}
public void Save()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
SaveInternal();
}
public void Load()
{
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
LoadInternal();
else
CreateNewInstance();
}
public void Reset()
{
Instance.Reset();
}
protected virtual ISettings CreateInstance()
{
return new Settings();
}
protected virtual void CreateNewInstance()
{
defaultInstance = CreateInstance();
defaultInstance.Reset();
}
protected virtual void LoadInternal()
{
defaultInstance = CreateInstance();
defaultInstance.Load(CreateJsonSerializerSettings(), File.ReadAllText(ConfigFilePath));
}
protected virtual void SaveInternal()
{
SavingSettings?.Invoke(this, EventArgs.Empty);
File.WriteAllText(ConfigFilePath, defaultInstance.Save(CreateJsonSerializerSettings()));
SavedSettings?.Invoke(this, EventArgs.Empty);
}
public virtual JsonSerializerSettings CreateJsonSerializerSettings()
{
return new JsonSerializerSettings
{
Formatting = Formatting.Indented,
TypeNameHandling = TypeNameHandling.Auto,
Error = JsonSerializer_OnError,
};
}
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
{
const string errorResolvingType = "Error resolving type specified in JSON";
// Invoke event
OnSerializationError?.Invoke(sender, e);
// Handle ourself
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
e.ErrorContext.Handled = true;
}
}

View File

@@ -0,0 +1,119 @@
Imports System.IO
Imports System.Reflection
Imports Newtonsoft.Json.Linq
Public NotInheritable Class SettingsManager(Of T As SettingsBase)
Implements ISettingsManager
Public Event AutoSavingSettings As EventHandler
Public Event SavingSettings As EventHandler
Public Event SavedSettings As EventHandler
Private defaultInstance As T = Nothing
Private enableAutoSave As Boolean = False
Private addedHandler As Boolean = False
Public Property ConfigFilePath As String Implements ISettingsManager.ConfigFilePath
Public Property AutoSaveOnExit As Boolean
Get
Return enableAutoSave
End Get
Set
If enableAutoSave <> Value Then
enableAutoSave = Value
Select Case enableAutoSave
Case True
If Not addedHandler Then
AddAutoSaveHandler()
End If
Case False
If addedHandler Then
RemoveAutoSaveHandler()
End If
End Select
End If
End Set
End Property
Private Sub AddAutoSaveHandler()
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = True
End Sub
Private Sub RemoveAutoSaveHandler()
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
addedHandler = False
End Sub
Public ReadOnly Property Instance As T
Get
If defaultInstance Is Nothing Then
Load()
End If
Return defaultInstance
End Get
End Property
Public Sub New()
ConfigFilePath = ""
AutoSaveOnExit = False
End Sub
Public Sub New(fileName As String, autoSaveOnExit As Boolean)
ConfigFilePath = fileName
Me.AutoSaveOnExit = autoSaveOnExit
End Sub
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
RaiseEvent AutoSavingSettings(Me, New EventArgs)
Save()
End Sub
Public Sub Save() Implements ISettingsManager.Save
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso defaultInstance IsNot Nothing Then
SavePrivate()
End If
End Sub
Public Sub Load() Implements ISettingsManager.Load
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso File.Exists(ConfigFilePath) Then
LoadPrivate()
Else
CreateNewInstance()
End If
If defaultInstance IsNot Nothing Then
defaultInstance._settingsManager = Me
End If
End Sub
Public Sub Reset() Implements ISettingsManager.Reset
Instance.ResetValues()
End Sub
Private Sub CreateNewInstance()
Dim ctor As ConstructorInfo = GetType(T).GetConstructor({})
If ctor IsNot Nothing Then
defaultInstance = ctor.Invoke({})
defaultInstance.ResetValues()
Else
Throw New Exception("The base type has no constructor with no parameters.")
End If
End Sub
Private Sub LoadPrivate()
defaultInstance = JObject.Parse(File.ReadAllText(ConfigFilePath)).ToObject(Of T)
End Sub
Private Sub SavePrivate()
RaiseEvent SavingSettings(Me, New EventArgs)
Dim obj As JObject = JObject.FromObject(defaultInstance)
If obj IsNot Nothing Then
File.WriteAllText(ConfigFilePath, obj.ToString)
End If
RaiseEvent SavedSettings(Me, New EventArgs)
End Sub
End Class

View File

@@ -1,56 +0,0 @@
using Newtonsoft.Json;
using System;
namespace Pilz.Configuration;
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(SettingsValueOptionJsonConverter))]
public class SettingsValueOption<T> : ISettingsValueOptionValueAccessor where T : struct
{
protected T? value;
public T DefaultValue { get; }
public virtual bool IsDefault => value == null;
public SettingsValueOption()
{
}
public SettingsValueOption(T value)
{
DefaultValue = value;
}
public virtual T Value
{
get => value ?? DefaultValue;
set => this.value = value;
}
public static implicit operator T(SettingsValueOption<T> option)
{
return option.Value;
}
object ISettingsValueOptionValueAccessor.ValueRaw
{
get => value;
set
{
if (value is not null)
this.value = Convert.ChangeType(value, typeof(T)) as T?;
else
this.value = null;
}
}
public virtual void Reset()
{
value = null;
}
public override string ToString()
{
return Value.ToString();
}
}

View File

@@ -1,27 +0,0 @@
using Newtonsoft.Json;
using System;
namespace Pilz.Configuration;
public class SettingsValueOptionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (existingValue is ISettingsValueOptionValueAccessor option)
option.ValueRaw = reader.Value;
return existingValue;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is ISettingsValueOptionValueAccessor option)
writer.WriteValue(option.ValueRaw);
else
writer.WriteNull();
}
}

View File

@@ -1,109 +0,0 @@
using Newtonsoft.Json;
using Pilz.GeneralEventArgs;
using System.IO;
namespace Pilz.Configuration;
public class SimpleConfiguration
{
[JsonIgnore]
public readonly ConfigurationManagerList Managers = [];
public SimpleConfiguration()
{
Managers.GettingParentManager += Managers_GettingParentManager;
}
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
{
if (ReferenceEquals(sender, Managers))
e.Value = this;
}
/// <summary>
/// Writes this instance to a string and return it.
/// </summary>
/// <returns>The content of the configuration instance as string.</returns>
public string WriteToString()
{
return ConfigurationSerializer.WriteToString(this);
}
/// <summary>
/// Write this instance to a given stream.
/// </summary>
/// <param name="stream">The stream where the content should be written to.</param>
public void WriteToStream(Stream stream)
{
ConfigurationSerializer.WriteToStream(this, stream);
}
/// <summary>
/// Writes this instance to the given filePath as text file.
/// </summary>
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
public void WriteToFile(string filePath)
{
ConfigurationSerializer.WriteToFile(this, filePath);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="content">The content of the configuration as string.</param>
/// <returns></returns>
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromString<T>(content);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="content">The content of the configuration as string.</param>
public void ReadFromString(string content)
{
ConfigurationSerializer.ReadFromString(this, content);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="stream">The stream with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromStream<T>(stream);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="stream">The stream with the content of the configuration.</param>
public void ReadFromStream(Stream stream)
{
ConfigurationSerializer.ReadFromStream(this, stream);
}
/// <summary>
/// Reads a configuratin from the given string and returns an instance of it.
/// </summary>
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
/// <returns></returns>
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
{
return ConfigurationSerializer.ReadFromFile<T>(filePath);
}
/// <summary>
/// Read a configuration from the given string and put them to this instance.
/// </summary>
/// <param name="filePath">The path to the file with the content of the configuration.</param>
public void ReadFromFile(string filePath)
{
ConfigurationSerializer.ReadFromFile(this, filePath);
}
}

View File

@@ -0,0 +1,99 @@
Imports System.IO
Imports Newtonsoft.Json
Imports Pilz.Configuration
Imports Pilz.GeneralEventArgs
Public Class SimpleConfiguration
<JsonIgnore>
Public ReadOnly Managers As New ConfigurationManagerList
Public Sub New()
AddHandler Managers.GettingParentManager, AddressOf Managers_GettingParentManager
End Sub
Private Sub Managers_GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
If sender Is Managers Then
e.Value = Me
End If
End Sub
''' <summary>
''' Writes this instance to a string and return it.
''' </summary>
''' <returns>The content of the configuration instance as string.</returns>
Public Function WriteToString() As String
Return ConfigurationSerializer.WriteToString(Me)
End Function
''' <summary>
''' Write this instance to a given stream.
''' </summary>
''' <param name="stream">The stream where the content should be written to.</param>
Public Sub WriteToStream(stream As Stream)
ConfigurationSerializer.WriteToStream(Me, stream)
End Sub
''' <summary>
''' Writes this instance to the given filePath as text file.
''' </summary>
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
Public Sub WriteToFile(filePath As String)
ConfigurationSerializer.WriteToFile(Me, filePath)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="content">The content of the configuration as string.</param>
''' <returns></returns>
Public Shared Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
Return ConfigurationSerializer.ReadFromString(Of T)(content)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="content">The content of the configuration as string.</param>
Public Sub ReadFromString(content As String)
ConfigurationSerializer.ReadFromString(Me, content)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="stream">The stream with the content of the configuration.</param>
''' <returns></returns>
Public Shared Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
Return ConfigurationSerializer.ReadFromStream(Of T)(stream)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="stream">The stream with the content of the configuration.</param>
Public Sub ReadFromStream(stream As Stream)
ConfigurationSerializer.ReadFromStream(Me, stream)
End Sub
''' <summary>
''' Reads a configuratin from the given string and returns an instance of it.
''' </summary>
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
''' <returns></returns>
Public Shared Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
Return ConfigurationSerializer.ReadFromFile(Of T)(filePath)
End Function
''' <summary>
''' Read a configuration from the given string and put them to this instance.
''' </summary>
''' <param name="filePath">The path to the file with the content of the configuration.</param>
Public Sub ReadFromFile(filePath As String)
ConfigurationSerializer.ReadFromFile(Me, filePath)
End Sub
End Class

View File

@@ -1,51 +0,0 @@
using System;
using System.ComponentModel;
using System.Management;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class Helpers
{
private static string clientSecret = null;
public static string CalculateClientSecret()
{
// Try getting serial number of C drive
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia");
string sn = null;
foreach (var entry in searcher.Get())
{
if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString()?.Trim();
}
clientSecret = sn;
}
// Fallback to Mashine name
clientSecret ??= Environment.MachineName;
return clientSecret;
}
public static string GenerateUniquieID<T>(string var)
{
var sn = CalculateClientSecret();
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
var type = typeof(T).ToString();
var together = sn + dateTime + type + var;
#if NET5_0_OR_GREATER
var hash = BitConverter.ToString(MD5.HashData(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
#else
var hash = BitConverter.ToString(MD5.Create().ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
#endif
return hash;
}
}

View File

@@ -1,7 +1,14 @@
namespace Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface ICrypter
namespace Pilz.Cryptography
{
string Encrypt(string plainValue);
string Decrypt(string encryptedValue);
public interface ICrypter
{
string Encrypt(string plainValue);
string Decrypt(string encryptedValue);
}
}

View File

@@ -1,14 +1,16 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public interface IUniquieID
namespace Pilz.Cryptography
{
bool HasID { get; }
string ID { get; }
public interface IUniquieID
{
bool HasID { get; }
string ID { get; }
void GenerateIfNull();
void Generate();
bool Equals(object obj);
void GenerateIfNull();
void Generate();
bool Equals(object obj);
}
}

View File

@@ -1,9 +1,14 @@
namespace Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Text;
/// <summary>
/// Can be implemented on objects that provides an UniquieID.
/// </summary>
public interface IUniquieIDHost
namespace Pilz.Cryptography
{
UniquieID ID { get; }
/// <summary>
/// Can be implemented on objects that provides an UniquieID.
/// </summary>
public interface IUniquieIDHost
{
UniquieID ID { get; }
}
}

View File

@@ -1,35 +1,38 @@
using Newtonsoft.Json;
using Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Text;
namespace Pilz.Json.Converters;
public class UniquieIDStringJsonConverter : JsonConverter
namespace Pilz.Json.Converters
{
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
public override bool CanConvert(Type objectType)
public class UniquieIDStringJsonConverter : JsonConverter
{
return typeof(IUniquieID).IsAssignableFrom(objectType);
}
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var idString = serializer.Deserialize<string>(reader);
UniquieID id;
public override bool CanConvert(Type objectType)
{
return typeof(UniquieID).IsAssignableFrom(objectType);
}
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
id = existingID;
else
id = new UniquieID();
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var idString = serializer.Deserialize<string>(reader);
UniquieID id;
id.ID = idString;
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
id = existingID;
else
id = new UniquieID();
return id;
}
id.ID = idString;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((UniquieID)value).ID);
return id;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((UniquieID)value).ID);
}
}
}

View File

@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyTitle>Pilz.Cryptography</AssemblyTitle>
<Product>Pilz.Cryptography</Product>
<Copyright>Copyright © 2020</Copyright>
</PropertyGroup>
<PropertyGroup>
<Version>2.1.3</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="System.Management" Version="9.0.9" />
<PackageReference Include="System.Management" Version="4.7.0" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

View File

@@ -1,4 +1,6 @@
using System.Runtime.InteropServices;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von

View File

@@ -1,72 +1,78 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
public class SecureString
namespace Pilz.Cryptography
{
public static ICrypter DefaultCrypter { get; set; }
public ICrypter Crypter { get; set; }
public string EncryptedValue { get; set; }
public string Value
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
public class SecureString
{
get => GetCrypter()?.Decrypt(EncryptedValue);
set => EncryptedValue = GetCrypter().Encrypt(value);
}
[JsonConstructor]
private SecureString(JsonConstructorAttribute dummyAttribute)
{
}
public SecureString() :
this(string.Empty, true)
{
}
public SecureString(string value, bool isEncrypted) :
this(value, isEncrypted, null)
{
}
public SecureString(string value, bool isEncrypted, ICrypter crypter)
{
Crypter = crypter;
if (isEncrypted)
EncryptedValue = value;
else
Value = value;
}
private ICrypter GetCrypter()
{
if (Crypter == null)
public static ICrypter DefaultCrypter { get; set; }
public ICrypter Crypter { get; set; }
public string EncryptedValue { get; set; }
public string Value
{
DefaultCrypter ??= new SimpleStringCrypter(string.Empty);
Crypter = DefaultCrypter;
get => GetCrypter()?.Decrypt(EncryptedValue);
set => EncryptedValue = GetCrypter().Encrypt(value);
}
return Crypter;
[JsonConstructor]
private SecureString(JsonConstructorAttribute dummyAttribute)
{
}
public SecureString() :
this(string.Empty, true)
{
}
public SecureString(string value, bool isEncrypted) :
this(value, isEncrypted, null)
{
}
public SecureString(string value, bool isEncrypted, ICrypter crypter)
{
Crypter = crypter;
if (isEncrypted)
EncryptedValue = value;
else
Value = value;
}
private ICrypter GetCrypter()
{
if (Crypter == null)
{
if (DefaultCrypter == null)
DefaultCrypter = new SimpleStringCrypter(string.Empty);
Crypter = DefaultCrypter;
}
return Crypter;
}
public override string ToString() => Value;
public override bool Equals(object obj)
{
var @string = obj as SecureString;
return @string != null &&
EncryptedValue == @string.EncryptedValue;
}
public override int GetHashCode()
{
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
}
public static implicit operator string(SecureString value) => value?.Value;
public static implicit operator SecureString(string value) => new SecureString(value, false);
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
}
public override string ToString() => Value;
public override bool Equals(object obj)
{
var @string = obj as SecureString;
return @string != null &&
EncryptedValue == @string.EncryptedValue;
}
public override int GetHashCode()
{
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
}
public static implicit operator string(SecureString value) => value?.Value;
public static implicit operator SecureString(string value) => new(value, false);
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
}

View File

@@ -1,34 +1,41 @@
using Newtonsoft.Json;
using Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pilz.Json.Converters;
public class SecureStringJsonConverter : JsonConverter
namespace Pilz.Json.Converters
{
public override bool CanConvert(Type objectType)
public class SecureStringJsonConverter : JsonConverter
{
return typeof(SecureString).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var idString = serializer.Deserialize<string>(reader);
SecureString id;
if (existingValue is SecureString)
public override bool CanConvert(Type objectType)
{
id = (SecureString)existingValue;
id.EncryptedValue = idString;
return typeof(SecureString).IsAssignableFrom(objectType);
}
else
id = new SecureString(idString, true);
return id;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var idString = serializer.Deserialize<string>(reader);
SecureString id;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
if (existingValue is SecureString)
{
id = (SecureString)existingValue;
id.EncryptedValue = idString;
}
else
id = new SecureString(idString, true);
return id;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
}
}
}

View File

@@ -1,77 +1,80 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography;
public class SimpleStringCrypter : ICrypter
namespace Pilz.Cryptography
{
private readonly TripleDES TripleDes;
public Encoding TextEncoding { get; private set; } = Encoding.Default;
public SimpleStringCrypter() : this(string.Empty)
public class SimpleStringCrypter : ICrypter
{
}
private TripleDESCryptoServiceProvider TripleDes;
public Encoding TextEncoding { get; private set; } = Encoding.Default;
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
{
}
public SimpleStringCrypter() : this(string.Empty)
{
}
public SimpleStringCrypter(string key, Encoding textEncoding)
{
TextEncoding = textEncoding;
TripleDes = TripleDES.Create();
TripleDes.Key = TruncateHash(key, TripleDes.KeySize / 8);
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
}
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
{
}
private byte[] TruncateHash(string key, int length)
{
SHA1 sha1CryptoServiceProvider = SHA1.Create();
var bytes = TextEncoding.GetBytes(key);
var array = sha1CryptoServiceProvider.ComputeHash(bytes);
public SimpleStringCrypter(string key, Encoding textEncoding)
{
TextEncoding = textEncoding;
TripleDes = new TripleDESCryptoServiceProvider();
TripleDes.Key = TruncateHash(key,TripleDes.KeySize / 8);
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
}
var output = new byte[length];
var lowerLength = Math.Min(array.Length, output.Length);
private byte[] TruncateHash(string key, int length)
{
SHA1CryptoServiceProvider sha1CryptoServiceProvider = new SHA1CryptoServiceProvider();
byte[] bytes = TextEncoding.GetBytes(key);
byte[] array = sha1CryptoServiceProvider.ComputeHash(bytes);
for (int i = 0; i < lowerLength; i++)
output[i] = array[i];
var output = new byte[length];
var lowerLength = Math.Min(array.Length, output.Length);
for (int i = 0; i < lowerLength; i++)
output[i] = array[i];
return output;
}
return output;
}
private string EncryptData(string plaintext)
{
var bytes = TextEncoding.GetBytes(plaintext);
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
private string EncryptData(string plaintext)
{
byte[] bytes = TextEncoding.GetBytes(plaintext);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
private string DecryptData(string encryptedtext)
{
var array = Convert.FromBase64String(encryptedtext);
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(array, 0, array.Length);
cryptoStream.FlushFinalBlock();
return TextEncoding.GetString(memoryStream.ToArray());
}
private string DecryptData(string encryptedtext)
{
byte[] array = Convert.FromBase64String(encryptedtext);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write(array, 0, array.Length);
cryptoStream.FlushFinalBlock();
return TextEncoding.GetString(memoryStream.ToArray());
}
public string Encrypt(string plainValue)
{
return EncryptData(plainValue ?? string.Empty);
}
public string Encrypt(string plainValue)
{
return EncryptData(plainValue ?? string.Empty);
}
public string Decrypt(string encryptedValue)
{
if (string.IsNullOrEmpty(encryptedValue))
return string.Empty;
else
return DecryptData(encryptedValue);
public string Decrypt(string encryptedValue)
{
if (string.IsNullOrEmpty(encryptedValue))
return string.Empty;
else
return DecryptData(encryptedValue);
}
}
}

View File

@@ -1,140 +1,172 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Management;
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Cryptography;
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public class UniquieID : IUniquieID
namespace Pilz.Cryptography
{
protected static ulong currentSimpleID = 0;
[JsonProperty(nameof(ID))]
protected string _iD;
[JsonIgnore]
public virtual bool SimpleMode { get; }
[JsonIgnore]
public virtual bool GenerateOnGet { get; }
[JsonIgnore]
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
[JsonIgnore]
public virtual string ID
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
public class UniquieID : IUniquieID
{
get
protected static ulong currentSimpleID = 0;
[JsonProperty(nameof(ID))]
protected string _iD;
[JsonIgnore]
public virtual bool SimpleMode { get; }
[JsonIgnore]
public virtual bool GenerateOnGet { get; }
[JsonIgnore]
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
[JsonIgnore]
public virtual string ID
{
if (GenerateOnGet)
GenerateIfNull();
return _iD;
}
internal set
=> _iD = value;
}
public UniquieID() : this(UniquieIDGenerationMode.None)
{
}
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
{
}
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
{
SimpleMode = simpleMode;
if (mode == UniquieIDGenerationMode.GenerateOnInit)
GenerateIfNull();
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
GenerateOnGet = true;
}
[Obsolete("Use the enum 'UniquieIDGenerationMode' instead of a simple boolean.")]
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
{
}
public virtual void Generate()
{
if (SimpleMode)
ID = GenerateSimple();
else
ID = GenerateDefault();
}
protected virtual string GenerateSimple()
{
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
}
protected virtual string GenerateDefault()
{
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
}
public virtual void GenerateIfNull()
{
if (!HasID) Generate();
}
public override string ToString()
{
return ID;
}
public override int GetHashCode()
{
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
}
public override bool Equals(object obj)
{
if (obj is UniquieID iD)
{
if (ReferenceEquals(obj, iD))
return true;
else
get
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
return _iD.Equals(iD._iD);
if (GenerateOnGet)
GenerateIfNull();
return _iD;
}
internal set
=> _iD = value;
}
return base.Equals(obj);
public UniquieID() : this(UniquieIDGenerationMode.None)
{
}
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
{
}
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
{
SimpleMode = simpleMode;
if (mode == UniquieIDGenerationMode.GenerateOnInit)
GenerateIfNull();
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
GenerateOnGet = true;
}
[Obsolete]
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
{
}
public virtual void Generate()
{
if (SimpleMode)
ID = GenerateSimple();
else
ID = GenerateDefault();
}
protected virtual string GenerateSimple()
{
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
}
protected virtual string GenerateDefault()
{
return GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
}
public virtual void GenerateIfNull()
{
if (!HasID) Generate();
}
public override string ToString()
{
return ID;
}
public override int GetHashCode()
{
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
}
public override bool Equals(object obj)
{
if (obj is UniquieID iD)
{
if (ReferenceEquals(obj, iD))
return true;
else
{
var leftHasID = iD.HasID;
var rightHasID = HasID;
if (!leftHasID && iD.GenerateOnGet)
{
iD.Generate();
leftHasID = iD.HasID;
}
if (!rightHasID && GenerateOnGet)
{
Generate();
rightHasID = HasID;
}
if (leftHasID && rightHasID)
return _iD.Equals(iD._iD);
}
}
return base.Equals(obj);
}
#region Statics for Generation
protected static string GenerateUniquieID<T>(string var)
{
var sn = TryGetSerialNumberOfFirstHardDrive();
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
var type = typeof(T).ToString();
var together = sn + dateTime + type + var;
var md5 = MD5.Create();
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
md5.Dispose();
return hash;
}
private static string Win32_PhysicalMedia_SerialNumber = null;
private static string TryGetSerialNumberOfFirstHardDrive()
{
if (Win32_PhysicalMedia_SerialNumber == null)
{
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
var sn = string.Empty;
foreach (ManagementObject wmi_HD in searcher.Get())
{
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
sn = wmi_HD["SerialNumber"].ToString().Trim();
}
Win32_PhysicalMedia_SerialNumber = sn;
}
return Win32_PhysicalMedia_SerialNumber;
}
#endregion
public static implicit operator string(UniquieID id) => id.ID;
public static implicit operator UniquieID(string id) => new UniquieID() { ID = id };
public static implicit operator UniquieID(int id) => new UniquieID() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
}
public static UniquieID GenerateNew()
{
return new UniquieID(UniquieIDGenerationMode.GenerateOnInit);
}
public static UniquieID GenerateNew(bool simpleMode)
{
return new UniquieID(UniquieIDGenerationMode.GenerateOnInit, simpleMode);
}
public static implicit operator string(UniquieID id) => id.ID;
public static implicit operator UniquieID(string id) => new() { ID = id };
public static implicit operator UniquieID(int id) => new() { ID = Convert.ToString(id) };
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
}

View File

@@ -1,8 +1,13 @@
namespace Pilz.Cryptography;
using System;
using System.Collections.Generic;
using System.Text;
public enum UniquieIDGenerationMode
namespace Pilz.Cryptography
{
None,
GenerateOnGet,
GenerateOnInit
public enum UniquieIDGenerationMode
{
None,
GenerateOnGet,
GenerateOnInit
}
}

View File

@@ -1,6 +1,5 @@
Imports System.Windows.Forms
Imports OpenTK.Mathematics
Imports OpenTK
Namespace CameraN
@@ -120,7 +119,7 @@ Namespace CameraN
Private Sub OrientateCam(ang As Single, ang2 As Single)
Dim CamLX As Single = CSng(Math.Sin(ang)) * CSng(Math.Sin(-ang2))
Dim CamLY As Single = Math.Cos(ang2)
Dim CamLY As Single = CSng(Math.Cos(ang2))
Dim CamLZ As Single = CSng(-Math.Cos(ang)) * CSng(Math.Sin(-ang2))
myLookat.X = pos.X + (-CamLX) * 100.0F
@@ -131,11 +130,11 @@ Namespace CameraN
Private Sub OffsetCam(xAmt As Integer, yAmt As Integer, zAmt As Integer)
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
Dim CamLX As Single = CSng(Math.Sin(CamAngleX)) * CSng(Math.Cos(-pitch_Renamed))
Dim CamLY As Single = Math.Sin(pitch_Renamed)
Dim CamLY As Single = CSng(Math.Sin(pitch_Renamed))
Dim CamLZ As Single = CSng(-Math.Cos(CamAngleX)) * CSng(Math.Cos(-pitch_Renamed))
pos.X += xAmt * (CamLX) * CamSpeedMultiplier
pos.Y += yAmt * (CamLY) * CamSpeedMultiplier
pos.Z += zAmt * (CamLZ) * CamSpeedMultiplier
pos.X = pos.X + xAmt * (CamLX) * CamSpeedMultiplier
pos.Y = pos.Y + yAmt * (CamLY) * CamSpeedMultiplier
pos.Z = pos.Z + zAmt * (CamLZ) * CamSpeedMultiplier
End Sub
Public Sub Move(y As Single, ByRef camMtx As Matrix4)
@@ -154,7 +153,7 @@ Namespace CameraN
Dim x_diff As Single = myLookat.X - pos.X
Dim y_diff As Single = myLookat.Y - pos.Y
Dim z_diff As Single = myLookat.Z - pos.Z
Dim dist As Single = Math.Sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff)
Dim dist As Single = CSng(Math.Sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff))
If z_diff = 0 Then
z_diff = 0.001F
End If
@@ -210,32 +209,32 @@ Namespace CameraN
currentLookDirection = dir
Select Case currentLookDirection
Case LookDirection.Top
pos = lookPositions(LookDirection.Top)
pos = lookPositions(CInt(LookDirection.Top))
myLookat = New Vector3(pos.X, -25000, pos.Z - 1)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
Case LookDirection.Bottom
pos = lookPositions(LookDirection.Bottom)
pos = lookPositions(CInt(LookDirection.Bottom))
myLookat = New Vector3(pos.X, 25000, pos.Z + 1)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
Case LookDirection.Left
pos = lookPositions(LookDirection.Left)
pos = lookPositions(CInt(LookDirection.Left))
myLookat = New Vector3(25000, pos.Y, pos.Z)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
Case LookDirection.Right
pos = lookPositions(LookDirection.Right)
pos = lookPositions(CInt(LookDirection.Right))
myLookat = New Vector3(-25000, pos.Y, pos.Z)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
Case LookDirection.Front
pos = lookPositions(LookDirection.Front)
pos = lookPositions(CInt(LookDirection.Front))
myLookat = New Vector3(pos.X, pos.Y, -25000)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
Case LookDirection.Back
pos = lookPositions(LookDirection.Back)
pos = lookPositions(CInt(LookDirection.Back))
myLookat = New Vector3(pos.X, pos.Y, 25000)
UpdateMatrix(cameraMatrix)
SetRotationFromLookAt()
@@ -313,9 +312,9 @@ Namespace CameraN
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
Dim yaw_Renamed As Double = CamAngleX - (Math.PI / 2)
Dim CamLX As Single = Math.Sin(yaw_Renamed)
Dim CamLY As Single = Math.Cos(pitch_Renamed)
Dim CamLZ As Single = -Math.Cos(yaw_Renamed)
Dim CamLX As Single = CSng(Math.Sin(yaw_Renamed))
Dim CamLY As Single = CSng(Math.Cos(pitch_Renamed))
Dim CamLZ As Single = CSng(-Math.Cos(yaw_Renamed))
Dim m As Single = 8.0F
@@ -324,36 +323,36 @@ Namespace CameraN
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m) - ((MousePosY * CamSpeedMultiplier) * (CamLZ) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m) - ((MousePosY * CamSpeedMultiplier) * (CamLX) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y - 1000, pos.Z - 1, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
Case LookDirection.Bottom
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m) + ((MousePosY * CamSpeedMultiplier) * (CamLZ) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m) + ((MousePosY * CamSpeedMultiplier) * (CamLX) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y + 1000, pos.Z + 1, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
Case LookDirection.Left
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X + 12500, pos.Y, pos.Z, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
Case LookDirection.Right
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X - 12500, pos.Y, pos.Z, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
Case LookDirection.Front
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z - 12500, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
Case LookDirection.Back
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z + 12500, 0, 1, 0)
lookPositions(currentLookDirection) = pos
lookPositions(CInt(currentLookDirection)) = pos
End Select
RaisePerspectiveChanged()
@@ -372,7 +371,7 @@ Namespace CameraN
End If
Dim MousePosX As Integer = mouseX - lastMouseX
Dim MousePosY As Integer = mouseY - lastMouseY
CamAngleX += (0.01F * MousePosX)
CamAngleX = CamAngleX + (0.01F * MousePosX)
' This next part isn't neccessary, but it keeps the Yaw rotation value within [0, 2*pi] which makes debugging simpler.
If CamAngleX > TAU Then
CamAngleX -= TAU
@@ -419,9 +418,9 @@ Namespace CameraN
'Console.WriteLine(MousePosX+","+ MousePosY);
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
Dim yaw_Renamed As Double = CamAngleX - (Math.PI / 2)
Dim CamLX As Single = Math.Sin(yaw_Renamed)
Dim CamLX As Single = CSng(Math.Sin(yaw_Renamed))
' float CamLY = (float)Math.Cos(pitch);
Dim CamLZ As Single = -Math.Cos(yaw_Renamed)
Dim CamLZ As Single = CSng(-Math.Cos(yaw_Renamed))
pos.X += ((horz_amount * CamSpeedMultiplier) * (CamLX))
pos.Y += ((vert_amount * CamSpeedMultiplier) * (-1.0F))
pos.Z += ((horz_amount * CamSpeedMultiplier) * (CamLZ))

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -1,11 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MyType>Windows</MyType>
<TargetFrameworks>net8.0-windows</TargetFrameworks>
<TargetFramework>net48</TargetFramework>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DocumentationFile>Pilz.Drawing.Drawing3D.OpenGLFactory.xml</DocumentationFile>
<DefineTrace>true</DefineTrace>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug>
@@ -25,16 +24,18 @@
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup>
<Version>2.0.4</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenTK.Input" Version="4.9.4" />
<PackageReference Include="OpenTK.GLControl" Version="4.0.2" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="OpenTK" Version="4.9.4" />
<PackageReference Include="System.Numerics.Vectors" Version="4.6.1" />
<PackageReference Include="OpenTK" Version="3.2" />
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
@@ -51,7 +52,9 @@
<Compile Update="Preview\ModelPreview.Designer.vb">
<DependentUpon>ModelPreview.vb</DependentUpon>
</Compile>
<Compile Update="Preview\ModelPreview.vb" />
<Compile Update="Preview\ModelPreview.vb">
<SubType>Form</SubType>
</Compile>
<Compile Update="My Project\Application.Designer.vb">
<AutoGen>True</AutoGen>
<DependentUpon>Application.myapp</DependentUpon>
@@ -91,7 +94,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Pilz.Simple3DFileParser\Pilz.Simple3DFileParser.vbproj" />
<ProjectReference Include="..\Pilz.Win32\Pilz.Win32.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Remove="ModelPreview.Designer.vb" />

View File

@@ -1,30 +1,15 @@
Imports System.Drawing
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
' Vor:
' Imports System.Windows.Forms
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
' Nach:
' Imports System.Windows.Forms
'
' Imports OpenTK
' Imports OpenTK.Graphics.OpenGL
' Imports OpenTK.Mathematics
' Imports OpenTK.WinForms
'
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports System.Windows.Forms
Imports OpenTK.GLControl
Imports OpenTK.Graphics.OpenGL
Imports OpenTK.Mathematics
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports Pilz.S3DFileParser
Imports Pilz.Win32.Mapped
Imports Color = System.Drawing.Color
Imports Point = System.Drawing.Point
Imports KeyboardState = OpenTK.Input.KeyboardState
Imports Keyboard = OpenTK.Input.Keyboard
Imports Key = OpenTK.Input.Key
Imports Color = System.Drawing.Color
Namespace PreviewN
@@ -96,13 +81,15 @@ Namespace PreviewN
Private ReadOnly Property IsStrgPressed As Boolean
Get
Return Keyboard.IsKeyDown(Keys.Control)
Dim state As KeyboardState = Keyboard.GetState()
Return state(Key.ControlLeft) OrElse state(Key.ControlRight)
End Get
End Property
Private ReadOnly Property IsShiftPressed As Boolean
Get
Return Keyboard.IsKeyDown(Keys.Shift)
Dim state As KeyboardState = Keyboard.GetState()
Return state(Key.ShiftLeft) OrElse state(Key.ShiftRight)
End Get
End Property
@@ -135,17 +122,17 @@ Namespace PreviewN
DoubleBuffered = True
'glControl1
Me.glControl1 = New GLControl With {
.BackColor = Color.Black,
.Location = New Point(0, 0),
.MinimumSize = New Size(600, 120),
.Name = "glControl1",
.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
}
Me.glControl1 = New GLControl
Me.glControl1.BackColor = Color.Black
Me.glControl1.Location = New Point(0, 0)
Me.glControl1.MinimumSize = New Size(600, 120)
Me.glControl1.Name = "glControl1"
Me.glControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
Me.glControl1.Location = New Point(0, 0)
Me.glControl1.Size = Me.ClientSize
Me.glControl1.TabIndex = 0
Me.glControl1.TabStop = False
Me.glControl1.VSync = False
Me.Controls.Add(Me.glControl1)
Me.ResumeLayout(False)
@@ -260,7 +247,7 @@ Namespace PreviewN
End Sub
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControl1.Resize
'glControl1.Context.Update(glControl1.WindowInfo)
glControl1.Context.Update(glControl1.WindowInfo)
GL.Viewport(0, 0, glControl1.Width, glControl1.Height)
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
glControl1.Invalidate()
@@ -268,7 +255,7 @@ Namespace PreviewN
Private Sub glControl1_Wheel(sender As Object, e As MouseEventArgs)
MyCamera.ResetMouseStuff()
MyCamera.UpdateCameraMatrixWithScrollWheel(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F))), camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
savedCamPos = MyCamera.Position
glControl1.Invalidate()
End Sub
@@ -299,24 +286,32 @@ Namespace PreviewN
Dim allowCamMove As Boolean = Not (IsMouseDown AndAlso IsShiftPressed)
If allowCamMove Then
If Keyboard.IsKeyDown(Keys.W) Then
Dim state As KeyboardState = Keyboard.GetState
If state(Key.W) Then
'camera.Move(moveSpeed, moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If Keyboard.IsKeyDown(Keys.S) Then
If state(Key.S) Then
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
savedCamPos = MyCamera.Position
End If
If Keyboard.IsKeyDown(Keys.A) Then
If state(Key.A) Then
'camera.Move(-moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
End If
If Keyboard.IsKeyDown(Keys.D) Then
If state(Key.D) Then
'camera.Move(moveSpeed, 0, camMtx)
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
End If
If Keyboard.IsKeyDown(Keys.E) Then
If state(Key.E) Then
'camera.Move(0, -moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
End If
If Keyboard.IsKeyDown(Keys.Q) Then
If state(Key.Q) Then
'camera.Move(0, moveSpeed, camMtx)
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
End If
End If

View File

@@ -1,14 +1,5 @@
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
' Vor:
' Imports System.Drawing
' Imports OpenTK
' Nach:
' Imports System.Drawing
'
' Imports OpenTK
Imports System.Drawing
Imports System.Drawing
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Namespace RenderingN

View File

@@ -1,8 +1,8 @@
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports System.Drawing
Imports System.Drawing.Imaging
Imports Bitmap = System.Drawing.Bitmap
Namespace RenderingN

View File

@@ -1,8 +1,9 @@
Imports OpenTK.Graphics.OpenGL
Imports OpenTK.Mathematics
Imports System.Drawing
Imports System.Threading
Imports System.Windows.Forms
Imports OpenTK
Imports OpenTK.Graphics.OpenGL
Imports Pilz.S3DFileParser
Imports Bitmap = System.Drawing.Bitmap
Imports Color = System.Drawing.Color
Imports Image = System.Drawing.Image
@@ -136,14 +137,6 @@ Namespace RenderingN
''' Creates the Buffers and store the requied Data.
''' </summary>
Public Sub RenderModel()
RenderModel(BufferUsageHint.StaticDraw)
End Sub
''' <summary>
''' Creates the Buffers and store the requied Data.
''' </summary>
''' <param name="bufferUsage">The hint how the graphics card should handle the data.</param>
Public Sub RenderModel(bufferUsage As BufferUsageHint)
ReleaseBuffers()
For Each mesh As Mesh In obj3d.Meshes

View File

@@ -1,14 +1,15 @@
Imports System.Drawing
Imports System.Drawing.Drawing2D
Public Module HelpfulDrawingFunctions
Public Function IsPointInRectangle(p As PointF, rect As RectangleF) As Boolean
Dim bList As New List(Of Boolean) From {
p.X > rect.Left,
p.X < rect.Right,
p.Y > rect.Top,
p.Y < rect.Bottom
}
Dim bList As New List(Of Boolean)
bList.Add(p.X > rect.Left)
bList.Add(p.X < rect.Right)
bList.Add(p.Y > rect.Top)
bList.Add(p.Y < rect.Bottom)
Return Not bList.Contains(False)
End Function

View File

@@ -22,7 +22,7 @@ Namespace My.Resources
'''<summary>
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
'''</summary>
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _

View File

@@ -1,12 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<MyType>Windows</MyType>
<TargetFrameworks>net8.0-windows</TargetFrameworks>
<LangVersion>latest</LangVersion>
<TargetFramework>net48</TargetFramework>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<DocumentationFile>Pilz.Drawing.xml</DocumentationFile>
<DefineTrace>true</DefineTrace>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DefineDebug>true</DefineDebug>
@@ -26,9 +24,10 @@
<PropertyGroup>
<OptionInfer>On</OptionInfer>
</PropertyGroup>
<PropertyGroup>
<Version>2.0.2</Version>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
<ItemGroup>
<Import Include="Microsoft.VisualBasic" />
<Import Include="System" />

View File

@@ -1,18 +0,0 @@
namespace Pilz.Extensions.Collections;
public static class IEnumerableExtensions
{
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> @this, Action<T> action)
{
foreach (var t in @this)
action(t);
return @this;
}
public static IQueryable<T> ForEach<T>(this IQueryable<T> @this, Action<T> action)
{
foreach (var t in @this)
action(t);
return @this;
}
}

View File

@@ -1,30 +0,0 @@
namespace Pilz.Extensions.Collections;
public static class IListExtensions
{
public static bool Move<T>(this IList<T> @this, T item, int amount)
{
var oldIndex = @this.IndexOf(item);
if (oldIndex == -1)
return false;
var newIndex = oldIndex + amount;
if (newIndex < 0)
newIndex = 0;
else if (newIndex >= @this.Count)
newIndex = @this.Count;
if (newIndex == oldIndex)
return false;
if (newIndex > 0 && newIndex > oldIndex)
newIndex -= 1;
@this.RemoveAt(oldIndex);
@this.Insert(newIndex, item);
return true;
}
}

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Version>2.1.2</Version>
</PropertyGroup>
</Project>

View File

@@ -1,24 +0,0 @@
using System.Linq.Expressions;
using System.Reflection;
namespace Pilz.Extensions.Reflection;
public static class MethodInfoExtensions
{
/// <summary>
/// Source: https://stackoverflow.com/questions/940675/getting-a-delegate-from-methodinfo
/// </summary>
/// <param name="methodInfo"></param>
/// <param name="target"></param>
/// <returns></returns>
public static Delegate CreateDelegate(this MethodInfo methodInfo, object? target)
{
var parmTypes = methodInfo.GetParameters().Select(parm => parm.ParameterType);
var parmAndReturnTypes = parmTypes.Append(methodInfo.ReturnType).ToArray();
var delegateType = Expression.GetDelegateType(parmAndReturnTypes);
if (methodInfo.IsStatic)
return methodInfo.CreateDelegate(delegateType);
return methodInfo.CreateDelegate(delegateType, target);
}
}

View File

@@ -1,3 +0,0 @@
namespace Pilz.Features;
public delegate void PluginFeatureExecuteEventHandler(object sender, PluginFeatureExecuteEventArgs e);

View File

@@ -1,5 +0,0 @@
namespace Pilz.Features.Exceptions;
public class PluginFeatureException : Exception;
public class PluginFeatureNotFoundException : PluginFeatureException;

View File

@@ -1,34 +0,0 @@
namespace Pilz.Features;
public static class Extensions
{
public static T? ExecuteIfEnabled<T>(this PluginFunction @this, params object?[]? @params)
{
return @this.Enabled ? @this.Execute<T>(@params) : default;
}
public static object? ExecuteIfEnabled(this PluginFunction @this, params object?[]? @params)
{
return @this.Enabled ? @this.Execute(@params) : default;
}
public static T? ExecuteIfEnabled<T>(this PluginFunction @this, PluginFunctionSimpleParamter? @params)
{
return @this.Enabled ? @this.Execute<T>(@params) : default;
}
public static object? ExecuteIfEnabled(this PluginFunction @this, PluginFunctionParameter? @params)
{
return @this.Enabled ? @this.Execute(@params) : default;
}
public static IEnumerable<T> Enabled<T>(this IEnumerable<T> @this) where T : PluginFeature
{
return @this.Where(n => n.Enabled);
}
public static IEnumerable<T> Ordered<T>(this IEnumerable<T> @this) where T : PluginFeature
{
return @this.OrderByDescending(n => n.Prioritization);
}
}

View File

@@ -1,8 +0,0 @@
namespace Pilz.Features;
public enum FeaturePrioritization
{
Low = -1,
Default = 0,
High = 1,
}

View File

@@ -1,5 +0,0 @@
namespace Pilz.Features;
public interface IPluginFeatureConstructor
{
}

View File

@@ -1,12 +0,0 @@
namespace Pilz.Features;
public interface IPluginFeatureProvider
{
static abstract PluginFeature Instance { get; }
}
public interface IPluginFeatureProvider<T> : IPluginFeatureProvider where T : PluginFeature, IPluginFeatureProvider<T>
{
static new abstract T Instance { get; }
static PluginFeature IPluginFeatureProvider.Instance => T.Instance;
}

View File

@@ -1,6 +0,0 @@
namespace Pilz.Features;
public interface IPluginFeaturesProvider
{
static abstract PluginFeature[] GetFeatures();
}

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Version>2.13.1</Version>
</PropertyGroup>
</Project>

View File

@@ -1,110 +0,0 @@
namespace Pilz.Features;
public abstract class PluginFeature
{
/// <summary>
/// Fires when the plugin feature gets used.
/// <br/>- For <see cref="PluginFunction"/> this fires on <see cref="PluginFunction.ExecuteFunction(PluginFunctionParameter?)"/>.
/// <br/>- For <see cref="T:PluginModule"/> this fires on <see cref="T:PluginModule.CreateNewUI(PluginFunctionParameter?)"/>.
/// <br/>- For any other custom feature implementation this may variate.
/// </summary>
public static event PluginFeatureExecuteEventHandler? OnExecute;
/// <summary>
/// The type of the feature defines where the feature get integrated.
/// </summary>
public string Type { get; init; }
/// <summary>
/// The identifier of the feature should be uniquie for the current <see cref="Type"/>.
/// It defines a feature within a type.
/// </summary>
public string Identifier { get; init; }
/// <summary>
/// The full identifier of the feature should be uniquie and is the combination of <see cref="Type"/> and <see cref="Identifier"/>.
/// It defines a feature across all types.
/// </summary>
public string FullIdentifier => GetFullIdentifier(Type, Identifier);
/// <summary>
/// The (display) name of the feature.
/// </summary>
public virtual string? Name { get; init; }
/// <summary>
/// The (display) description of the feature.
/// </summary>
public virtual string? Description { get; init; }
/// <summary>
/// The symbol for the feature.
/// </summary>
public virtual object? Icon { get; set; }
/// <summary>
/// Sets the prioritization of the feature.
/// This will be respected on abfragen features and on inserting as items using the extension methods"/>.
/// Some applications might implement a way to regonize feature prioritization via its own way.
/// </summary>
public virtual FeaturePrioritization Prioritization { get; set; }
/// <summary>
/// Defines if the feature is enabled/visible.
/// </summary>
public virtual bool Enabled { get; set; } = true;
protected PluginFeature(string type, string identifier)
{
Identifier = identifier;
Type = type;
}
protected PluginFeature(string type, string identifier, string? name) : this(type, identifier)
{
Name = name;
}
public static string GetFullIdentifier(string featureType, string identifier)
{
return $"{featureType}:{identifier}";
}
/// <summary>
/// Fires the <see cref="OnExecute"/> event with the status <see cref="PluginFeatureExecuteEventType.PostEvent"/>.
/// </summary>
/// <param name="params">The present <see cref="PluginFunctionParameter"/>.</param>
/// <param name="result">The resulting object that will be returned.</param>
/// <returns>Returns true if the original function should be executed.</returns>
protected bool OnPreExecute(PluginFunctionParameter? @params, ref object? result)
{
if (OnExecute != null)
{
var args = new PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType.PreEvent, @params);
OnExecute.Invoke(this, args);
if (args.Handled)
{
result = args.Result;
return false;
}
}
return true;
}
/// <summary>
/// Fires the <see cref="OnExecute"/> event with the status <see cref="PluginFeatureExecuteEventType.PostEvent"/>.
/// </summary>
/// <param name="params">The present <see cref="PluginFunctionParameter"/>.</param>
/// <param name="result">The resulting object that will be returned.</param>
protected void OnPostExecute(PluginFunctionParameter? @params, ref object? result)
{
if (OnExecute != null)
{
var args = new PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType.PostEvent, @params)
{
Result = result
};
OnExecute.Invoke(this, args);
if (args.Handled)
result = args.Result;
}
}
}

View File

@@ -1,302 +0,0 @@
using Pilz.Features.Exceptions;
using System.Reflection;
namespace Pilz.Features;
public class PluginFeatureController
{
// D e l e g a t e s
public delegate void PluginFeatureEventHandler(PluginFeatureController controller, PluginFeature feature);
// S t a t i c E v e n t s
/// <summary>
/// Fires when a new <see cref="PluginFeature"/> has been registred.
/// </summary>
public static event PluginFeatureEventHandler? OnPluginFeatureReistred;
/// <summary>
/// Fires when a <see cref="PluginFeature"/> has been unregistred.
/// </summary>
public static event PluginFeatureEventHandler? OnPluginFeatureUnregistred;
// S t a t i c M e m b e r s
protected static readonly string nameGetFeatures = $"{nameof(IPluginFeaturesProvider.GetFeatures)}";
protected static readonly string nameGetFeaturesExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.{nameof(IPluginFeaturesProvider.GetFeatures)}";
protected static readonly string nameInstance = $"get_{nameof(IPluginFeatureProvider.Instance)}";
protected static readonly string nameInstnaceExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.get_{nameof(IPluginFeatureProvider.Instance)}";
/// <summary>
/// The default public instance that can be used by plugins and the interface providing software.
/// </summary>
public static PluginFeatureController Instance { get; private set; } = new();
// I n s t a n c e M e m e b e r s
private readonly HashSet<PluginFeature> features = [];
/// <summary>
/// A wrapper of all registred <see cref="PluginFeature"/> instances.
/// </summary>
public FeatureController Features { get; init; }
/// <summary>
/// A wrapper for all registred <see cref="PluginModule"/> instances.
/// </summary>
public ModuleController Modules { get; init; }
/// <summary>
/// A wrapper for all registred <see cref="PluginFunction"/> instances.
/// </summary>
public FunctionController Functions { get; init; }
public PluginFeatureController()
{
Features = new(this);
Functions = new(this);
Modules = new(this);
}
/// <summary>
/// Registers all features found in the currently executing Assembly via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
/// </summary>
public void RegisterAllOwn(string? @namespace = null)
{
RegisterAll(Assembly.GetCallingAssembly());
}
/// <summary>
/// Registers all features found in the given <see cref="Assembly[]"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
/// </summary>
/// <param name="assemblies">The assemblies to query for types.</param>
/// <param name="namespace">If not null, only types within the given namespace will be registered.</param>
public void RegisterAll(Assembly[] assemblies, string? @namespace = null)
{
foreach (var assembly in assemblies)
RegisterAll(assembly);
}
/// <summary>
/// Registers all features found in the given <see cref="Assembly"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
/// </summary>
/// <param name="assembly">The assembly to query for types.</param>
/// <param name="namespace">If not null, only types within the given namespace will be registered.</param>
public void RegisterAll(Assembly assembly, string? @namespace = null)
{
RegisterAll(assembly.GetTypes());
}
/// <summary>
/// Registers all features found from the given <see cref="Type[]"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
/// </summary>
/// <param name="types">The types to query for providers.</param>
/// <param name="namespace">If not null, the types will only be processed if they're within the given namespace.</param>
public void RegisterAll(Type[] types, string? @namespace = null)
{
foreach (var type in types)
RegisterAll(type);
}
/// <summary>
/// Registers all features found from the given <see cref="Type"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
/// </summary>
/// <param name="type">The type to query for providers.</param>
/// <param name="namespace">If not null, the type will only be processed if it's within the given namespace.</param>
public void RegisterAll(Type type, string? @namespace = null)
{
if (@namespace != null && type.Namespace != null && type.Namespace != @namespace && !type.Namespace.StartsWith(@namespace + ".") || type.IsAbstract)
return;
if (type.IsAssignableTo(typeof(IPluginFeaturesProvider)))
{
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var method = methods.FirstOrDefault(n => n.Name == nameGetFeaturesExplicit || n.Name == nameGetFeatures);
if (method != null && method.Invoke(null, null) is PluginFeature[] features)
{
foreach (var feature in features)
Register(feature);
}
}
else if (type.IsAssignableTo(typeof(IPluginFeatureProvider)))
{
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
var method = methods.FirstOrDefault(n => n.Name == nameInstnaceExplicit || n.Name == nameInstance);
if (method != null && method.Invoke(null, null) is PluginFeature feature)
Register(feature);
}
else if (type.IsAssignableTo(typeof(IPluginFeatureConstructor)))
{
if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, [typeof(PluginFeatureController)]) is ConstructorInfo ctor1)
{
if (ctor1.Invoke([this]) is PluginFeature feature)
Register(feature);
}
else if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, []) is ConstructorInfo ctor)
{
if (ctor.Invoke([]) is PluginFeature feature)
Register(feature);
}
}
}
/// <summary>
/// Registers a feature via the given <see cref="IPluginFeatureProvider"/> or <see cref="IPluginFeatureProvider{T}"/>.
/// </summary>
public void Register<TProvider>() where TProvider : IPluginFeatureProvider
{
Register(TProvider.Instance);
}
/// <summary>
/// Registers all features via the given <see cref="IPluginFeaturesProvider"/>.
/// </summary>
public void RegisterAll<TProvider>() where TProvider : IPluginFeaturesProvider
{
foreach (var feature in TProvider.GetFeatures())
Register(feature);
}
/// <summary>
/// Registers the given feature.
/// </summary>
/// <param name="module"></param>
public void Register(PluginFeature module)
{
if (features.Add(module))
OnPluginFeatureReistred?.Invoke(this, module);
}
/// <summary>
/// Unregisters the given feature.
/// </summary>
/// <param name="module"></param>
public void Unregister(PluginFeature module)
{
features.Remove(module);
OnPluginFeatureUnregistred?.Invoke(this, module);
}
public class FeatureController(PluginFeatureController controller)
{
protected readonly PluginFeatureController controller = controller;
public virtual IEnumerable<PluginFeature> GetAll()
{
return [.. controller.features];
}
public virtual IEnumerable<T> GetAll<T>() where T : PluginFeature
{
return controller.features.OfType<T>();
}
public virtual T? Get<T>() where T : PluginFeature
{
return GetAll<T>().FirstOrDefault();
}
public virtual T EnsureGet<T>() where T : PluginFeature
{
if (Get<T>() is T feature)
return feature;
throw new PluginFeatureNotFoundException();
}
public virtual IEnumerable<PluginFeature> Get(string featureType)
{
return controller.features.Where(n => n.Type == featureType);
}
public virtual PluginFeature? GetFirst(string featureType)
{
return controller.features.FirstOrDefault(n => n.Type == featureType);
}
public virtual PluginFeature? GetByIdentifier(string fullIdentifier)
{
return controller.features.FirstOrDefault(n => n.FullIdentifier == fullIdentifier);
}
public virtual PluginFeature? GetByIdentifier(string featureType, string identifier)
{
return controller.features.FirstOrDefault(n => n.Type == featureType && n.Identifier == identifier);
}
}
public class FeatureController<T>(PluginFeatureController controller) : FeatureController(controller) where T : PluginFeature
{
public override IEnumerable<T> GetAll()
{
return GetAll<T>();
}
public override IEnumerable<T> Get(string moduleType)
{
return GetAll().Where(n => n.Type == moduleType);
}
public override T? GetFirst(string moduleType)
{
return base.GetFirst(moduleType) as T;
}
public override T? GetByIdentifier(string fullIdentifier)
{
return base.GetByIdentifier(fullIdentifier) as T;
}
public override T? GetByIdentifier(string featureType, string identifier)
{
return base.GetByIdentifier(featureType, identifier) as T;
}
}
public class ModuleController(PluginFeatureController controller) : FeatureController<PluginModuleBase>(controller)
{
}
public class FunctionController(PluginFeatureController controller) : FeatureController<PluginFunction>(controller)
{
public void ExecuteAll(string functionType)
{
foreach (var function in Get(functionType))
function.Execute();
}
public void ExecuteAll(string functionType, params object?[]? @params)
{
foreach (var function in Get(functionType))
function.Execute(@params);
}
public void ExecuteAll(string functionType, PluginFunctionParameter @params)
{
foreach (var function in Get(functionType))
function.Execute(@params);
}
public IEnumerable<object?> ExcuteAndGetResults(string functionType)
{
return Get(functionType).Select(n => n.Execute());
}
public IEnumerable<object?> ExcuteAndGetResults(string functionType, params object?[]? @params)
{
return Get(functionType).Select(n => n.Execute(@params));
}
public IEnumerable<object?> ExcuteAndGetResults(string functionType, PluginFunctionParameter @params)
{
return Get(functionType).Select(n => n.Execute(@params));
}
}
}

View File

@@ -1,9 +0,0 @@
namespace Pilz.Features;
public class PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType eventType, PluginFunctionParameter? parameters) : EventArgs
{
public PluginFeatureExecuteEventType EventType { get; } = eventType;
public PluginFunctionParameter? Parameters { get; } = parameters;
public bool Handled { get; set; }
public object? Result { get; set; }
}

View File

@@ -1,7 +0,0 @@
namespace Pilz.Features;
public enum PluginFeatureExecuteEventType
{
PreEvent,
PostEvent,
}

View File

@@ -1,90 +0,0 @@
namespace Pilz.Features;
public abstract class PluginFunction : PluginFeature
{
protected PluginFunction(string type, string identifier) : base(type, identifier)
{
}
protected PluginFunction(string type, string identifier, string? name) : base(type, identifier, name)
{
}
public virtual object? Execute()
{
return Execute((PluginFunctionParameter?)null);
}
public virtual T? Execute<T>(params object?[]? @params)
{
return Execute<T>(new PluginFunctionSimpleParamter(@params));
}
public virtual object? Execute(params object?[]? @params)
{
return Execute(new PluginFunctionSimpleParamter(@params));
}
public virtual T? Execute<T>(PluginFunctionSimpleParamter? @params)
{
if (Execute(@params) is T result)
return result;
return default;
}
public virtual object? Execute(PluginFunctionParameter? @params)
{
object? result = null;
if (OnPreExecute(@params, ref result))
result = ExecuteFunction(@params);
OnPostExecute(@params, ref result);
return result;
}
public virtual Task<object?> ExecuteAsync()
{
return ExecuteAsync((PluginFunctionParameter?)null);
}
public virtual Task<T?> ExecuteAsync<T>(params object?[]? @params)
{
return ExecuteAsync<T>(new PluginFunctionSimpleParamter(@params));
}
public virtual Task<object?> ExecuteAsync(params object?[]? @params)
{
return ExecuteAsync(new PluginFunctionSimpleParamter(@params));
}
public virtual async Task<T?> ExecuteAsync<T>(PluginFunctionSimpleParamter? @params)
{
if (await ExecuteAsync(@params) is T result)
return result;
return default;
}
public virtual async Task<object?> ExecuteAsync(PluginFunctionParameter? @params)
{
object? result = null;
if (OnPreExecute(@params, ref result))
result = await ExecuteFunctionAsync(@params);
OnPostExecute(@params, ref result);
return result;
}
protected virtual object? ExecuteFunction(PluginFunctionParameter? @params)
{
return ExecuteFunctionAsync(@params).GetAwaiter().GetResult();
}
protected virtual Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{
return Task.FromResult(ExecuteFunction(@params));
}
}

View File

@@ -1,5 +0,0 @@
namespace Pilz.Features;
public class PluginFunctionParameter
{
}

View File

@@ -1,11 +0,0 @@
namespace Pilz.Features;
public sealed class PluginFunctionSimpleParamter : PluginFunctionParameter
{
public object?[]? Params { get; init; }
public PluginFunctionSimpleParamter(params object?[]? @params)
{
Params = @params;
}
}

View File

@@ -1,15 +0,0 @@
using System.ComponentModel;
namespace Pilz.Features;
[EditorBrowsable(EditorBrowsableState.Never)]
public abstract class PluginModuleBase : PluginFeature
{
protected PluginModuleBase(string type, string identifier) : base(type, identifier)
{
}
protected PluginModuleBase(string type, string identifier, string? name) : base(type, identifier, name)
{
}
}

View File

@@ -1,14 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<Version>2.0.1</Version>
</PropertyGroup>
</Project>

View File

@@ -1,40 +0,0 @@
using System.Security.Cryptography;
using System.Text;
namespace Pilz.Gaming.Minecraft;
public static class Utils
{
public static string GetUUID(string value)
{
//extracted from the java code:
//new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
var data = MD5.HashData(Encoding.ASCII.GetBytes(value));
//set the version to 3 -> Name based md5 hash
data[6] = Convert.ToByte(data[6] & 0x0f | 0x30);
//IETF variant
data[8] = Convert.ToByte(data[8] & 0x3f | 0x80);
//example: 069a79f4-44e9-4726-a5be-fca90e38aaf5
var striped = Convert.ToHexString(data);
var components = new string[] {
striped[..].Remove(8),
striped[8..].Remove(4),
striped[12..].Remove(4),
striped[16..].Remove(4),
striped[20..]
};
return string.Join('-', components).ToLower();
}
public static string GetPlayerUUID(string username, bool offlineMode)
{
using var md5 = MD5.Create();
if (!offlineMode)
throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time.");
return GetUUID("OfflinePlayer:" + username);
}
}

Some files were not shown because too many files have changed in this diff Show More