Skip to content

Commit

Permalink
Improved logging, improved GameLoader, better split of DLL Games and …
Browse files Browse the repository at this point in the history
…Plugins.
  • Loading branch information
12Acorns committed Jul 30, 2024
1 parent 2faa9c5 commit 8fc2087
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 156 deletions.
78 changes: 38 additions & 40 deletions CardGameConsoleApp/App.csproj
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>False</PublishAot>
<PublishTrimmed>False</PublishTrimmed>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FastEnum" Version="1.8.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GameLoader\GameLoader.csproj" />
</ItemGroup>

<Target Name="Copy Files" AfterTargets="CoreCompile">
<MSBuild Projects="$(SolutionDir)GameOne\GameOne.csproj"
Targets="Build"
Properties="Configuration=$(Configuration);Platform=$(Platform)" />
<Copy
SourceFiles="$(SolutionDir)GameOne\$(OutDir)GameOne.dll"
DestinationFolder="$(TargetDir)Games"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
<Copy
SourceFiles="$(SolutionDir)GameOne\$(OutDir)Deck.dll"
DestinationFolder="$(TargetDir)Games"
OverwriteReadOnlyFiles="true"
SkipUnchangedFiles="false" />
</Target>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PublishAot>False</PublishAot>
<PublishTrimmed>False</PublishTrimmed>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FastEnum" Version="1.8.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GameLoader\GameLoader.csproj" />
</ItemGroup>

<Target Name="Build Unreferenced" AfterTargets="Build">
<MSBuild Projects="$(SolutionDir)GameOne\GameOne.csproj" Targets="Build" Properties="Configuration=$(Configuration);Platform=$(Platform)" />
</Target>

<Target Name="Create Dir" AfterTargets="CoreCompile">
<MakeDir Directories="$(TargetDir)Games" />
<MakeDir Directories="$(TargetDir)Lib" />
</Target>

<Target Name="Copy Files" AfterTargets="Build">
<Copy SourceFiles="$(SolutionDir)GameOne\$(OutDir)GameOne.dll" DestinationFolder="$(TargetDir)Games" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" />
<Copy SourceFiles="$(SolutionDir)GameOne\$(OutDir)Deck.dll" DestinationFolder="$(TargetDir)Lib" OverwriteReadOnlyFiles="true" SkipUnchangedFiles="false" />
</Target>

</Project>
155 changes: 95 additions & 60 deletions GameLoader/GameLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,78 +6,32 @@ namespace GameLoader;

public sealed class GameLoader
{
private static readonly string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
private static readonly string libDirectory = Path.Combine(baseDirectory, "Lib");
private static readonly string gamesDirectory = Path.Combine(baseDirectory, "Games");

public GameLoader()
{
using var _logger = new Logger("GameLoaderLog", 4096);

try
{
Directory.CreateDirectory(gamesDirectory);
}
catch(Exception _ex)
{
_logger.AppendOrLog("\n\nERROR: Could not create directory ->\n Target Path: " +
$"{gamesDirectory}\n Exception: {_ex.Message}");

Console.WriteLine("ERROR");
Console.WriteLine($"Log details: {_logger.filePath}");

throw;
}


IEnumerable<Assembly> _gameAssemblies = [];

try
{
_gameAssemblies = Directory.GetFiles(gamesDirectory, "*.dll")
.Select(Assembly.LoadFrom);
}
catch(Exception _ex)
{
_logger.AppendOrLog("\n\nERROR: Could not get files ->\n " + _ex.Message);

Console.WriteLine("ERROR");
Console.WriteLine($"Log details: {_logger.filePath}");

throw;
}

_logger.AppendOrLog($"Assemblies found:\n" +
string.Join('\n', _gameAssemblies.Select(x => " " + x.GetName().FullName)));

_logger.AppendOrLog($"\n\nAssembly locations:\n" +
string.Join('\n', _gameAssemblies.Select(x => " " + x.Location)));
var _logger = new Logger("GameLoaderLog", 4096);

var _types = _gameAssemblies.SelectMany(assembly => assembly.GetTypes());
var _libAssemblies = LoadAssemblies(libDirectory, _logger);
var _gameAssemblies = LoadAssemblies(gamesDirectory, _logger);

_logger.AppendOrLog($"\n\nTypes found:\n" +
string.Join('\n', _types.Select(x => $" {x.FullName}")));
LogAssemblies(_libAssemblies, _logger);
LogAssemblies(_gameAssemblies, _logger);

var _types = GetTypes(_gameAssemblies, _logger);
var _iGameTypes = _types.Where(type => typeof(IGame).IsAssignableFrom(type));

_logger.AppendOrLog($"\n\nTypes that match {typeof(IGame).Name} found:\n" +
string.Join('\n', _iGameTypes.Select(x => $" {x.FullName}")));
LogTypes(_types, _iGameTypes, _logger);

_logger.Flush();

games = _iGameTypes.Select(type => (IGame)Activator.CreateInstance(type)!);
gameNames = games.ToDictionary(x => x.Name, x => x);

var _builder = new StringBuilder("Enter desired game (Case-Sensitive): \n");
var _format = CompositeFormat.Parse(" -{0}\n");
var _culture = CultureInfo.InvariantCulture;

foreach(var _game in games)
{
_builder.AppendFormat(_culture, _format, _game.Name);
}

gameList = _builder.ToString();
gameList = BuildGameList();
}

private static readonly string gamesDirectory =
Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"Games");

private readonly Dictionary<string, IGame> gameNames;
private readonly IEnumerable<IGame> games;
Expand All @@ -92,7 +46,19 @@ public void Run()
var _runGame = AskGame();
_runGame.Run();
}
private string BuildGameList()
{
var _builder = new StringBuilder("Enter desired game (Case-Sensitive): \n");
var _format = CompositeFormat.Parse(" -{0}\n");
var _culture = CultureInfo.InvariantCulture;

foreach(var _game in games)
{
_builder.AppendFormat(_culture, _format, _game.Name);
}

return _builder.ToString();
}
private IGame AskGame()
{
var _desiredGame = Console.ReadLine() ?? "";
Expand All @@ -106,4 +72,73 @@ private IGame AskGame()
}
return _game;
}
private static IEnumerable<Assembly> LoadAssemblies(string _directory, Logger _logger)
{
var _dir = new DirectoryInfo(_directory);

try
{
var _assemblies = Directory.GetFiles(_directory, "*.dll")
.Select(Assembly.LoadFrom);

_logger.AppendOrLog($"Successfully loaded {_dir.Name} assemblies:\n " +
string.Join("\n ", _assemblies.Select(x => x.GetName().Name)) +
"\n\n");

return _assemblies;
}
catch(Exception _ex)
{
_logger.AppendOrLog("\n\nERROR: Could not get files ->\n " + _ex.Message);

Console.WriteLine("ERROR");
Console.WriteLine($"Log details: {_logger.filePath}");

_logger.Flush();

throw;
}
}
private static IEnumerable<Type> GetTypes(IEnumerable<Assembly> _gameAssemblies, Logger _logger)
{
return _gameAssemblies.SelectMany(assembly =>
{
try
{
return assembly.GetTypes();
}
catch(ReflectionTypeLoadException ex)
{
_logger.AppendOrLog("\n\nReflectionTypeLoadException:\n " + ex.Message);

foreach(var _loaderException in ex.LoaderExceptions)
{
_logger.AppendOrLog($"\n Loader Exception: \n {_loaderException?.Message}");
}

Console.WriteLine("ERROR");
Console.WriteLine($"Log details: {_logger.filePath}");

_logger.Flush();

throw;
}
});
}
private static void LogTypes(IEnumerable<Type> _types, IEnumerable<Type> _gameTypes, Logger _logger)
{
_logger.AppendOrLog($"\n\nTypes found:\n" +
string.Join('\n', _types.Select(type => $" {type.FullName}")));

_logger.AppendOrLog($"\n\nTypes that match {typeof(IGame).Name} found:\n" +
string.Join('\n', _gameTypes.Select(type => $" {type.FullName}")));
}
private static void LogAssemblies(IEnumerable<Assembly> _assemblies, Logger _logger)
{
_logger.AppendOrLog($"Assemblies found:\n" +
string.Join('\n', _assemblies.Select(assembly => " " + assembly.GetName().FullName)));

_logger.AppendOrLog($"\n\nAssembly locations:\n" +
string.Join('\n', _assemblies.Select(assembly => " " + assembly.Location)));
}
}
Loading

0 comments on commit 8fc2087

Please sign in to comment.