11 Commits

Author SHA1 Message Date
omegaleo dec8fc7674 Automatically generated changelog for v1.1.1 2025-02-18 21:51:46 +00:00
omegaleo 4540db3a5e added LICENSE.md 2025-02-18 21:50:57 +00:00
omegaleo fd2600863e Added READMEs 2025-02-18 21:48:14 +00:00
omegaleo c0bc8ff760 fixed changelog lib workflow 2025-02-18 21:24:02 +00:00
omegaleo 699bb1d5f5 removed create release from workflow 2025-02-18 21:23:12 +00:00
omegaleo 21e55614ec fixed global usings 2025-02-18 21:20:18 +00:00
omegaleo bcb2d95ed4 fix for tag version 2025-02-18 21:17:57 +00:00
omegaleo 560567dc96 updated workflows 2025-02-18 21:14:55 +00:00
omegaleo 906bfc7781 fixed dotnet versions 2025-02-18 21:12:42 +00:00
omegaleo 7b6115da21 Dev changes (#3)
* Fixed dependency

* Updates to NeoDictionary

* Changes to NeoDictionary

* Started working on a Git implementation to integrate into Game Engines in the future

* Added commit functionality to the git library

* New changes

* Added select for NeoDictionary.cs

* Fixed issue with previous new method

* Added a Benchmarking Tool to be used mostly in game engines

* Added IndexOf to NeoDictionary.cs

* Added new method for BenchmarkUtility.cs

* added an instacedobject class

* Added a new shuffle method for lists

* fixed return type

* Added new Changelog generator
2025-02-18 21:09:25 +00:00
omegaleo 8f249d2567 NeoDictionary changes (#2)
* Fixed dependency

* Updates to NeoDictionary

* Changes to NeoDictionary
2024-07-27 10:52:55 +01:00
27 changed files with 883 additions and 5 deletions
+40
View File
@@ -0,0 +1,40 @@
name: Create Tag
on:
workflow_dispatch:
inputs:
tagName:
description: 'Tag name:'
type: string
required: true
run-name: "Generating changelog for Release v${{github.event.inputs.tagName}}"
jobs:
generate_changelog:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
token: ${{ secrets.TOKEN }}
- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'
- name: Update Project Versions
run: sed -i "s/\(<Version>\)[0-9]\+\.[0-9]\+\.[0-9]\+/\1${{github.event.inputs.tagName}}/" "./OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj"
- name: Update Project Versions
run: sed -i "s/\(<Version>\)[0-9]\+\.[0-9]\+\.[0-9]\+/\1${{github.event.inputs.tagName}}/" "./OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj"
- name: Build and Run Changelog Generator
run: dotnet run --project "./OmegaLeo.HelperLib.ChangelogHandler/OmegaLeo.HelperLib.ChangelogHandler.csproj"
env:
UNITYFLOW_SECRET: ${{ secrets.TOKEN }}
- name: Create Tag
run: |
git config --local user.email "nunodiogo@omegaleo.pt"
git config --local user.name "Nuno Diogo"
git add .
git commit -m "Automatically generated changelog for v${{github.event.inputs.tagName}}"
git tag -a "${{ github.event.inputs.tagName }}" -m "Release ${{ github.event.inputs.tagName }}"
git push origin "${{ github.event.inputs.tagName }}"
+27 -2
View File
@@ -2,6 +2,7 @@ name: Publish Nuget Packages
on:
release:
types: [created]
run-name: "Publish version v${{github.event.release.tag_name}} to nuget"
jobs:
get-release:
name: Get Release
@@ -16,7 +17,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
outputs:
upload_url: ${{ steps.get_release.outputs.upload_url }}
publish_doc_helper:
publish-helper-lib:
runs-on: ubuntu-latest
needs: [get-release]
steps:
@@ -24,7 +25,7 @@ jobs:
- name: Setup .Net Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '7.0.x'
dotnet-version: '8.0.x'
- name: Update Project Version
run: sed -i "s/\(<Version>\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{ github.event.release.tag_name }}/" "./OmegaLeo.HelperLib/OmegaLeo.HelperLib.csproj"
- name: Create Nuget Package
@@ -40,3 +41,27 @@ jobs:
asset_path: ./OmegaLeo.HelperLib/bin/Release/OmegaLeo.HelperLib.${{ github.event.release.tag_name }}.nupkg
asset_name: OmegaLeo.HelperLib.${{ github.event.release.tag_name }}.nupkg
asset_content_type: application/zip
publish-changelog-lib:
runs-on: ubuntu-latest
needs: [ get-release ]
steps:
- uses: actions/checkout@v2
- name: Setup .Net Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '8.0.x'
- name: Update Project Version
run: sed -i "s/\(<Version>\([0-9]\+\.\)\{2\}\)\([0-9]\+\)/\1${{ github.event.release.tag_name }}/" "./OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj"
- name: Create Nuget Package
run: dotnet pack "./OmegaLeo.HelperLib.Changelog/OmegaLeo.HelperLib.Changelog.csproj" -c Release /p:Version=${{ github.event.release.tag_name }} /p:PackageReleaseNotes="See https://github.com/omegaleo/OmegaLeo.HelperLib/releases/tag/${{ github.event.release.tag_name }}"
- name: Publish Nuget Package
run: dotnet nuget push ./OmegaLeo.HelperLib.Changelog/bin/Release/OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg --api-key ${{ secrets.nuget_api_key }} --source https://api.nuget.org/v3/index.json --skip-duplicate
- name: Upload assets to release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
with:
upload_url: ${{ needs.get-release.outputs.upload_url }}
asset_path: ./OmegaLeo.HelperLib/bin/Release/OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg
asset_name: OmegaLeo.HelperLib.Changelog.${{ github.event.release.tag_name }}.nupkg
asset_content_type: application/zip
@@ -0,0 +1,18 @@
using System;
namespace OmegaLeo.HelperLib.Changelog.Attributes
{
[Changelog("v1.0.0", "Created ChangelogAttribute to be used to register changes in the code.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)]
public class ChangelogAttribute : Attribute
{
public string Version { get; }
public string Description { get; }
public ChangelogAttribute(string version, string description)
{
Version = version;
Description = description;
}
}
}
@@ -0,0 +1,7 @@
# Changelog
## Version v1.0.0
- **Class: ChangelogTool**: Created the class ChangelogTool to extract changelogs via attributes
- **Class: ChangelogAttribute**: Created ChangelogAttribute to be used to register changes in the code.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Nuno "Omega Leo" Diogo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,14 @@
namespace OmegaLeo.HelperLib.Changelog.Models
{
public class Changelog
{
public string Target;
public string Description;
public Changelog(string target, string description)
{
Target = target;
Description = description;
}
}
}
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
<Title>Omega Leo's Helper Library - Changelog</Title>
<Authors>Nuno "Omega Leo" Diogo</Authors>
<Description>Package to help with Changelog generation</Description>
<PackageProjectUrl>https://github.com/omegaleo/HelperLib</PackageProjectUrl>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/omegaleo/HelperLib</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\"/>
<None Include="CHANGELOG.md" Pack="true" PackagePath="\"/>
<None Include="LICENSE.md" Pack="true" PackagePath="\"/>
</ItemGroup>
</Project>
+12
View File
@@ -0,0 +1,12 @@
# Omega Leo's Helper Library - Changelog
Package to help with Changelog generation by providing a new Changelog attribute and a tool to extract a dictionary of the changelogs or the markdown for CHANGELOG.md
Example attribute usage:
```cs
[Changelog("v1.0.0", "This is a test")]
[Changelog("v1.0.1", "This is another test")]
public class Test
{
}
```
@@ -0,0 +1,63 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using OmegaLeo.HelperLib.Changelog.Attributes;
namespace OmegaLeo.HelperLib.Changelog.Tools
{
[Changelog("v1.0.0", "Created the class ChangelogTool to extract changelogs via attributes")]
public class ChangelogTool
{
public static Dictionary<string, List<Models.Changelog>> ExtractChangelog(Assembly assembly)
{
var changelogByVersion = new Dictionary<string, List<Models.Changelog>>();
foreach (var type in assembly.GetTypes())
{
foreach (var attr in type.GetCustomAttributes<ChangelogAttribute>())
{
AddChangelogEntry(changelogByVersion, attr.Version, $"Class: {type.Name}", attr.Description);
}
foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
{
foreach (var attr in method.GetCustomAttributes<ChangelogAttribute>())
AddChangelogEntry(changelogByVersion, attr.Version, $"Method: {type.Name}.{method.Name}()", attr.Description);
}
}
changelogByVersion = new Dictionary<string, List<Models.Changelog>>(changelogByVersion.OrderByDescending(x => x.Key));
return changelogByVersion;
}
public static string GetMarkdown(Assembly assembly)
{
var changelog = ExtractChangelog(assembly);
var sb = new StringBuilder();
sb.AppendLine("# Changelog\n");
foreach (var version in changelog)
{
sb.AppendLine($"## Version {version.Key}\n");
foreach (var entry in version.Value)
{
sb.AppendLine($"- **{entry.Target}**: {entry.Description}");
}
sb.AppendLine();
}
return sb.ToString();
}
private static void AddChangelogEntry(Dictionary<string, List<Models.Changelog>> changelog, string version, string target, string description)
{
if (!changelog.ContainsKey(version))
changelog[version] = new List<Models.Changelog>();
changelog[version].Add(new Models.Changelog(target, description));
}
}
}
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\OmegaLeo.HelperLib.Changelog\OmegaLeo.HelperLib.Changelog.csproj" />
<ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,45 @@
// See https://aka.ms/new-console-template for more information
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using GameDevLibrary.Helpers;
using OmegaLeo.HelperLib.Changelog.Models;
using OmegaLeo.HelperLib.Changelog.Tools;
var root = GetSolutionRoot();
var changelogs = new Dictionary<string, Assembly>()
{
{Path.Join(root, "OmegaLeo.HelperLib.Changelog", "CHANGELOG.md"), typeof(Changelog).Assembly},
{Path.Join(root, "OmegaLeo.HelperLib", "CHANGELOG.md"), typeof(BenchmarkUtility).Assembly},
};
foreach (var changelog in changelogs)
{
GenerateChangelog(changelog.Key, changelog.Value);
}
void GenerateChangelog(string path, Assembly libraryAssembly)
{
var changelogMarkdown = ChangelogTool.GetMarkdown(libraryAssembly);
File.WriteAllText(path,changelogMarkdown);
}
static string GetSolutionRoot()
{
string dir = AppContext.BaseDirectory;
while (!string.IsNullOrEmpty(dir))
{
if (Directory.GetFiles(dir, "*.sln").Length > 0)
return dir; // Found the solution root
dir = Directory.GetParent(dir)?.FullName; // Move up a directory
}
throw new Exception("Solution root not found.");
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\OmegaLeo.HelperLib.Changelog\OmegaLeo.HelperLib.Changelog.csproj" />
<ProjectReference Include="..\OmegaLeo.HelperLib.Git\OmegaLeo.HelperLib.Git.csproj" />
<ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" />
</ItemGroup>
</Project>
+102
View File
@@ -0,0 +1,102 @@
// See https://aka.ms/new-console-template for more information
// /media/omegaleo/Development/Library Dev/HelperLib
using System.Reflection;
using GameDevLibrary.Extensions;
using GameDevLibrary.Helpers;
using LibGit2Sharp;
using OmegaLeo.HelperLib.Changelog.Tools;
using OmegaLeo.HelperLib.Git;
using OmegaLeo.HelperLib.Git.Models;
Console.WriteLine("Insert repo path to check changes:");
var repo = Console.ReadLine();
if (repo.IsNullOrEmpty())
{
repo = "/media/omegaleo/Development/Library Dev/HelperLib";
}
var git = new GitClient(repo);
var result = BenchmarkUtility.Record(() =>
{
var changes = git.GetChanges();
if (changes.FolderName.IsNotNullOrEmpty())
{
RecursiveOutput(new List<ChangeFolder>() { changes });
var option = 99;
while (option != 0)
{
ShowOptions();
if (option != 99)
{
switch (option)
{
case 1:
Console.WriteLine("Write the commit message");
var msg = Console.ReadLine();
while (msg.IsNullOrEmpty())
{
Console.WriteLine("Empty message detected, please write a commit message...");
msg = Console.ReadLine();
}
var signature = new Signature("Nuno 'Omega Leo' Diogo", "nunodiogo@omegaleo.pt",
DateTimeOffset.Now);
git.Commit(msg, signature);
break;
case 2:
git.Push();
break;
default:
Console.WriteLine("Invalid Option!");
break;
}
}
int.TryParse(Console.ReadLine(), out option);
}
}
else
{
Console.WriteLine("No changes found in specified repository");
}
});
Console.WriteLine($"Time for checking for changes: {result} ms");
Console.ReadLine();
void RecursiveOutput(List<ChangeFolder> folders, int depth = 0)
{
foreach (var folder in folders)
{
Console.WriteLine($"{new string('\t', depth)}>{folder.FolderName}");
if (folder.SubFolders.Any())
{
RecursiveOutput(folder.SubFolders, depth + 1);
}
foreach (var change in folder.ChangesInFolder)
{
Console.WriteLine($"{new string('\t', depth + 1)}>{Path.GetFileName(change.Path)} ({change.Status})");
}
}
}
void ShowOptions()
{
Console.Clear();
Console.WriteLine(new string('=', 20));
Console.WriteLine("What do you want to do in this repository?");
Console.WriteLine("1. Commit all changes");
Console.WriteLine("2. Push");
}
@@ -0,0 +1,10 @@
using OmegaLeo.HelperLib.Changelog.Attributes;
namespace OmegaLeo.HelperLib.ConsoleApp;
[Changelog("v1.0.0", "Test")]
[Changelog("v1.0.1", "Test 1")]
public class TestClass
{
}
+130
View File
@@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using GameDevLibrary.Extensions;
using LibGit2Sharp;
using OmegaLeo.HelperLib.Git.Models;
namespace OmegaLeo.HelperLib.Git
{
public class GitClient
{
private Repository _repo;
public GitClient(string path)
{
if (path.IsNullOrEmpty())
{
path = AppDomain.CurrentDomain.BaseDirectory;
}
_repo = new Repository(path);
}
public void CheckoutBranch(string branchName)
{
var branch = _repo.Branches[branchName];
if (branch == null)
{
branch = _repo.CreateBranch(branchName);
}
Commands.Checkout(_repo, branch);
}
public bool HasChanges() => _repo.Diff.Compare<TreeChanges>().Count > 0;
public ChangeFolder GetChanges()
{
var folder = new ChangeFolder();
if (HasChanges())
{
var changes = _repo.Diff.Compare<TreeChanges>();
var allChanges = new List<TreeEntryChanges>();
allChanges.AddRange(changes.Added);
allChanges.AddRange(changes.Modified);
allChanges.AddRange(changes.Deleted);
var uniqueFolderPaths = allChanges.Select(x => Path.GetDirectoryName(x.Path)).Distinct();
foreach (var path in uniqueFolderPaths)
{
if (path.IsNullOrEmpty()) continue;
if (path.Contains(Path.DirectorySeparatorChar))
{
var paths = path.Split(Path.DirectorySeparatorChar);
for (var i = 0; i < paths.Length; i++)
{
var p = paths[i];
if (folder.FolderName.Equals(p))
{
if (folder.ChangesInFolder.Any()) continue;
folder.ChangesInFolder =
allChanges.Where(x => Path.GetDirectoryName(x.Path)!.Equals(p, StringComparison.OrdinalIgnoreCase));
}
else
{
var pathList = paths[0..(i+1)].ToList();
var subFolder = folder.RecursiveGet(pathList);
var fullPath = string.Join(Path.DirectorySeparatorChar, pathList);
if (!subFolder.ChangesInFolder.Any())
{
subFolder.ChangesInFolder = allChanges.Where(x =>
Path.GetDirectoryName(x.Path)!.Equals(fullPath, StringComparison.OrdinalIgnoreCase));
}
}
}
}
else
{
folder.FolderName = path;
folder.ChangesInFolder =
allChanges.Where(x => Path.GetDirectoryName(x.Path)!.Equals(path, StringComparison.OrdinalIgnoreCase));
}
}
}
return folder;
}
public void Commit(string message, Signature author)
{
if (HasChanges())
{
var changes = _repo.Diff.Compare<TreeChanges>();
var allChanges = new List<TreeEntryChanges>();
allChanges.AddRange(changes.Added);
allChanges.AddRange(changes.Modified);
allChanges.AddRange(changes.Deleted);
var filePaths = allChanges.Select(x => x.Path).Where(x => x.IsNotNullOrEmpty());
Commands.Stage(_repo, filePaths);
}
_repo.Commit(message, author, author);
}
public void Push()
{
try {
var remote = _repo.Network.Remotes["origin"];
var options = new PushOptions();
var pushRefSpec = @"refs/heads/master";
_repo.Network.Push(remote, new string[] {pushRefSpec}, options);
}
catch (Exception e) {
Console.WriteLine("Exception:RepoActions:PushChanges " + e.Message);
}
}
}
}
@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using LibGit2Sharp;
namespace OmegaLeo.HelperLib.Git.Models
{
public class ChangeFolder
{
public string FolderName { get; set; }
public List<ChangeFolder> SubFolders { get; set; }
public IEnumerable<TreeEntryChanges> ChangesInFolder { get; set; }
public ChangeFolder()
{
FolderName = "";
SubFolders = new List<ChangeFolder>();
ChangesInFolder = new List<TreeEntryChanges>();
}
public ChangeFolder RecursiveGet(List<string> paths)
{
if (!paths.Any()) return null;
var tempPaths = paths;
var pathToCheck = tempPaths.FirstOrDefault();
ChangeFolder folder = new ChangeFolder();
if (FolderName.Equals(pathToCheck, StringComparison.OrdinalIgnoreCase))
{
folder = this;
}
else if (SubFolders.Any(x => x.FolderName.Equals(pathToCheck)))
{
folder = SubFolders.FirstOrDefault(x => x.FolderName.Equals(pathToCheck))!;
}
else
{
folder.FolderName = pathToCheck;
SubFolders.Add(folder);
}
tempPaths.RemoveAt(0);
if (tempPaths.Any())
{
return folder.RecursiveGet(tempPaths);
}
else
{
return folder;
}
}
}
}
@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<RootNamespace>GameDevLibrary.Git</RootNamespace>
<Version>0.0.2</Version>
<Title>Omega Leo's Helper Library - LibGit2Sharp Implementation</Title>
<Authors>Nuno "Omega Leo" Diogo</Authors>
<PackageProjectUrl>https://github.com/omegaleo/HelperLib</PackageProjectUrl>
<RepositoryUrl>https://github.com/omegaleo/HelperLib</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibGit2Sharp" Version="0.30.0"/>
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj" />
</ItemGroup>
</Project>
+24
View File
@@ -2,6 +2,14 @@
Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib", "OmegaLeo.HelperLib\OmegaLeo.HelperLib.csproj", "{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Git", "OmegaLeo.HelperLib.Git\OmegaLeo.HelperLib.Git.csproj", "{A9579FFB-9A05-4EBF-B298-513C48FB0F91}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.ConsoleApp", "OmegaLeo.HelperLib.ConsoleApp\OmegaLeo.HelperLib.ConsoleApp.csproj", "{3B77B177-FD47-470A-B0EF-01EF8B30CE09}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.Changelog", "OmegaLeo.HelperLib.Changelog\OmegaLeo.HelperLib.Changelog.csproj", "{378D8125-66B5-42B8-9881-33F951E5E04A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmegaLeo.HelperLib.ChangelogHandler", "OmegaLeo.HelperLib.ChangelogHandler\OmegaLeo.HelperLib.ChangelogHandler.csproj", "{359536F7-02DE-43E9-A383-D83853227B0F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -12,5 +20,21 @@ Global
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7256931-5D66-46FA-BA50-22B2FA4CD9E9}.Release|Any CPU.Build.0 = Release|Any CPU
{A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9579FFB-9A05-4EBF-B298-513C48FB0F91}.Release|Any CPU.Build.0 = Release|Any CPU
{3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3B77B177-FD47-470A-B0EF-01EF8B30CE09}.Release|Any CPU.Build.0 = Release|Any CPU
{378D8125-66B5-42B8-9881-33F951E5E04A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{378D8125-66B5-42B8-9881-33F951E5E04A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{378D8125-66B5-42B8-9881-33F951E5E04A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{378D8125-66B5-42B8-9881-33F951E5E04A}.Release|Any CPU.Build.0 = Release|Any CPU
{359536F7-02DE-43E9-A383-D83853227B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{359536F7-02DE-43E9-A383-D83853227B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{359536F7-02DE-43E9-A383-D83853227B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{359536F7-02DE-43E9-A383-D83853227B0F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
+5
View File
@@ -0,0 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASafeFileHandle_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fomegaleo_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc21672d0d37542808f219d7d1f059dc1b2e000_003Faf_003Fbed3a9b4_003FSafeFileHandle_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThrowHelper_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fomegaleo_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fc61cc76f205b4535a5b4f40700c07900b2d200_003Fe5_003F6b3ec67e_003FThrowHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATreeChanges_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fomegaleo_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F7478b0ce6362feb345e793626f5c504bd9d7ffeb748226521658c85fc4e29_003FTreeChanges_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATreeEntryChanges_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Fhome_003Fomegaleo_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2b7912eaeadb1d9a91a3f891a244b5cd4a856d9dde42694e941ee6a2994_003FTreeEntryChanges_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
+2
View File
@@ -0,0 +1,2 @@
# Changelog
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
namespace GameDevLibrary.Extensions
{
@@ -98,7 +99,7 @@ namespace GameDevLibrary.Extensions
return values;
}
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
/*public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
@@ -109,7 +110,7 @@ namespace GameDevLibrary.Extensions
yield return element;
}
}
}
}*/
// Idea obtained from TaroDev's video on things to do in Unity - https://youtu.be/Ic5ux-tpkCE?t=302
@@ -117,5 +118,30 @@ namespace GameDevLibrary.Extensions
{
return array[currentIndex++ % array.Count];
}
/// <summary>
/// Shuffle around items in a list.
/// Code obtained from https://stackoverflow.com/a/1262619
/// </summary>
/// <param name="list"></param>
/// <typeparam name="T"></typeparam>
public static IList<T> Shuffle<T>(this IList<T> list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
(list[k], list[n]) = (list[n], list[k]);
}
return list;
}
}
}
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace GameDevLibrary.Helpers
{
public class BenchmarkUtility
{
private static Dictionary<string, List<long>> _benchmarks = new Dictionary<string, List<long>>();
private static Dictionary<string, Stopwatch> _stopwatches = new Dictionary<string, Stopwatch>();
private static Stopwatch GetStopwatch(string key)
{
Stopwatch stopwatch = new Stopwatch();
if (_stopwatches.TryGetValue(key, out stopwatch))
{
}
else
{
stopwatch = new Stopwatch();
_stopwatches.Add(key, stopwatch);
}
return stopwatch;
}
public static long Record(Action actionToRecord)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
actionToRecord.Invoke();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
public static long RecordAndSaveToResults(string key, Action actionToRecord)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
actionToRecord.Invoke();
stopwatch.Stop();
if (!_benchmarks.ContainsKey(key))
{
_benchmarks[key] = new List<long>();
}
_benchmarks[key].Add(stopwatch.ElapsedMilliseconds);
return stopwatch.ElapsedMilliseconds;
}
public static void Start(string key)
{
GetStopwatch(key).Restart();
}
public static void Stop(string key)
{
if (!_benchmarks.ContainsKey(key))
{
_benchmarks[key] = new List<long>();
}
GetStopwatch(key).Stop();
_benchmarks[key].Add(GetStopwatch(key).ElapsedMilliseconds);
}
public static List<long> GetResults(string key)
{
return _benchmarks.ContainsKey(key) ? _benchmarks[key] : new List<long>();
}
public static void ClearResults()
{
_benchmarks.Clear();
}
public static Dictionary<string, List<long>> GetAllResults()
{
return new Dictionary<string, List<long>>(_benchmarks);
}
}
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Nuno "Omega Leo" Diogo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,31 @@
using System;
namespace GameDevLibrary.Models
{
public abstract class InstancedObject<T> where T : class
{
public static T Instance { get; private set; }
protected InstancedObject()
{
if (Instance != null)
{
throw new InvalidOperationException($"An instance of {typeof(T).Name} already exists.");
}
Instance = this as T;
if (Instance == null)
{
throw new InvalidOperationException($"Failed to cast {GetType().Name} to {typeof(T).Name}.");
}
}
~InstancedObject()
{
if (Instance == this)
{
Instance = null;
}
}
}
}
@@ -81,6 +81,12 @@ namespace GameDevLibrary.Models
public NeoDictionaryItem<TKey, TValue>? LastOrDefault(Func<NeoDictionaryItem<TKey, TValue>, bool> predicate) =>
Items.LastOrDefault(predicate);
public IEnumerable<NeoDictionaryItem<TKey, TValue>> Select(Func<NeoDictionaryItem<TKey, TValue>, NeoDictionaryItem<TKey, TValue>> selector) =>
Items.Select(selector);
public int IndexOf(NeoDictionaryItem<TKey, TValue> selector) =>
Items.IndexOf(selector);
public void Remove(TKey key)
{
@@ -90,6 +96,54 @@ namespace GameDevLibrary.Models
}
public void RemoveAt(int index) => Items.RemoveAt(index);
public void Replace(TKey key, TValue value)
{
if (HasKey(key))
{
this[key] = value;
}
}
public bool HasKey(TKey key) => Items.Any(x => x.Key.Equals(key));
public TValue this[TKey key]
{
get
{
if (Items == null)
{
Items = new List<NeoDictionaryItem<TKey, TValue>>();
Items.Add(new NeoDictionaryItem<TKey, TValue>(key, (TValue)Activator.CreateInstance(typeof(TValue))));
}
try
{
var value = Items.FirstOrDefault(x => EqualityComparer<TKey>.Default.Equals(x.Key, key))!.Value;
return value ?? (TValue)Activator.CreateInstance(typeof(TValue));
}
catch (Exception e)
{
return (TValue)Activator.CreateInstance(typeof(TValue));
}
}
set
{
if (HasKey(key))
{
var item = Items.FirstOrDefault(x => EqualityComparer<TKey>.Default.Equals(x.Key, key));
var index = Items.IndexOf(item);
Items[index] = new NeoDictionaryItem<TKey, TValue>(key, value);
}
else
{
Items.Add(new NeoDictionaryItem<TKey, TValue>(key, value));
}
}
}
public void Clear() => Items.Clear();
}
[Serializable]
+8 -1
View File
@@ -4,9 +4,10 @@
<TargetFramework>netstandard2.1</TargetFramework>
<Nullable>enable</Nullable>
<RootNamespace>GameDevLibrary</RootNamespace>
<Version>0.0.2</Version>
<Version>1.1.1</Version>
<Title>Omega Leo's Helper Library</Title>
<Authors>Nuno "Omega Leo" Diogo</Authors>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/omegaleo/HelperLib</PackageProjectUrl>
<RepositoryUrl>https://github.com/omegaleo/HelperLib</RepositoryUrl>
</PropertyGroup>
@@ -15,4 +16,10 @@
<PackageReference Include="NetFlow.DocumentationHelper.Library" Version="1.1.2" />
</ItemGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="\"/>
<None Include="CHANGELOG.md" Pack="true" PackagePath="\"/>
<None Include="LICENSE.md" Pack="true" PackagePath="\"/>
</ItemGroup>
</Project>
+1
View File
@@ -0,0 +1 @@
# Omega Leo's Helper Lib