Skip to content

Commit

Permalink
Code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
0x7c13 committed Oct 23, 2023
1 parent e36ced6 commit de98baa
Show file tree
Hide file tree
Showing 42 changed files with 345 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ public static class LazyThetaStarPathFinder
}

path.Reverse();
return path.ToArray();
return path;
}

private static bool IsPositionInsideGrid(int x, int y, SearchNode[,] nodes)
Expand Down
27 changes: 27 additions & 0 deletions Assets/Scripts/Pal3.Core/Command/ISceCommandParser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2021-2023, Jiaqi Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------

namespace Pal3.Core.Command
{
using DataReader;

/// <summary>
/// Defines the interface for parsing SCE commands from a binary reader.
/// </summary>
public interface ISceCommandParser
{
/// <summary>
/// Parse the next SceCommand from the given reader
/// in the SCE script data block.
/// </summary>
/// <param name="reader">The binary reader to read from.</param>
/// <param name="codepage">The codepage to use for decoding strings.</param>
/// <param name="commandId">The ID of the parsed command.</param>
/// <returns>The parsed command.</returns>
public ICommand ParseNextCommand(IBinaryReader reader,
int codepage,
out ushort commandId);
}
}
3 changes: 3 additions & 0 deletions Assets/Scripts/Pal3.Core/Command/ISceCommandParser.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions Assets/Scripts/Pal3.Core/Command/ISceCommandPreprocessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2021-2023, Jiaqi Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------

namespace Pal3.Core.Command
{
/// <summary>
/// Interface for a command preprocessor that can modify a command before it is executed.
/// </summary>
public interface ISceCommandPreprocessor
{
/// <summary>
/// Processes the given command before it is executed.
/// </summary>
/// <param name="command">The command to process.</param>
/// <param name="currentPlayerActorId">The ID of the current player actor.</param>
public void Process(ICommand command, int currentPlayerActorId);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 23 additions & 0 deletions Assets/Scripts/Pal3.Core/Command/ISceCommandTypeResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// ---------------------------------------------------------------------------------------------
// Copyright (c) 2021-2023, Jiaqi Liu. All rights reserved.
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------

namespace Pal3.Core.Command
{
using System;

/// <summary>
/// Interface for resolving the type of a SceCommand based on its ID and user variable mask.
/// </summary>
public interface ISceCommandTypeResolver
{
/// <summary>
/// Get SceCommand Type for the given command id.
/// </summary>
/// <param name="commandId">SceCommand Id</param>
/// <param name="userVariableMask">User variable mask</param>
/// <returns>Type of the command, null if not found</returns>
public Type GetType(ushort commandId, ushort userVariableMask);
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 11 additions & 3 deletions Assets/Scripts/Pal3.Core/Command/SceCommandParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,21 @@ namespace Pal3.Core.Command
using System.Reflection;
using Contract.Constants;
using DataReader;
using Utilities;

/// <summary>
/// Parser logic for parsing SceCommand in .sce script data block.
/// </summary>
public static class SceCommandParser
public sealed class SceCommandParser : ISceCommandParser
{
public static ICommand ParseSceCommand(IBinaryReader reader,
private readonly ISceCommandTypeResolver _sceCommandTypeResolver;

public SceCommandParser(ISceCommandTypeResolver sceCommandTypeResolver)
{
_sceCommandTypeResolver = Requires.IsNotNull(sceCommandTypeResolver, nameof(sceCommandTypeResolver));
}

public ICommand ParseNextCommand(IBinaryReader reader,
int codepage,
out ushort commandId)
{
Expand All @@ -28,7 +36,7 @@ public static class SceCommandParser
throw new InvalidDataException($"Command Id is invalid: {commandId}");
}

Type commandType = SceCommandTypeResolver.GetType(commandId, userVariableMask);
Type commandType = _sceCommandTypeResolver.GetType(commandId, userVariableMask);

if (commandType == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,24 @@
// See LICENSE file in the project root for license information.
// ---------------------------------------------------------------------------------------------

namespace Pal3.Game.Command
namespace Pal3.Core.Command
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using Core.Command;
using Core.Contract.Constants;
using Core.Utilities;
using GamePlay;
using Contract.Constants;

public sealed class CommandPreprocessor
public sealed class SceCommandPreprocessor : ISceCommandPreprocessor
{
private readonly PlayerActorManager _playerActorManager;

private bool _isInitialized = false;
private readonly Dictionary<Type, PropertyInfo[]> _sceCommandToActorIdPropertiesCache = new();

public CommandPreprocessor(PlayerActorManager playerActorManager)
public void Init()
{
_playerActorManager = Requires.IsNotNull(playerActorManager, nameof(playerActorManager));
BuildTypeCache();
}
if (_isInitialized) return;

private void BuildTypeCache()
{
IEnumerable<Type> commandTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(t => t.IsClass && t.GetInterfaces().Contains(typeof(ICommand)));
Expand Down Expand Up @@ -65,19 +57,29 @@ private void BuildTypeCache()

_sceCommandToActorIdPropertiesCache[commandType] = actorIdProperties;
}

_isInitialized = true;
}

public void Process(ref ICommand command)
public void Process(ICommand command, int currentPlayerActorId)
{
if (!_isInitialized)
{
throw new InvalidOperationException(
$"[{nameof(SceCommandPreprocessor)}] is not initialized. " +
$"Please call [{nameof(Init)}] before using it.");
}

Type commandType = command.GetType();

if (_sceCommandToActorIdPropertiesCache.TryGetValue(commandType, out PropertyInfo[] actorIdProperties))
{
foreach (PropertyInfo actorIdProperty in actorIdProperties)
{
// Set actorIdProperty to current player actor id if it is PlayerActorVirtualID (-1)
if (actorIdProperty.GetValue(command) is ActorConstants.PlayerActorVirtualID)
{
actorIdProperty.SetValue(command, (int)_playerActorManager.GetPlayerActor());
actorIdProperty.SetValue(command, currentPlayerActorId);
}
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions Assets/Scripts/Pal3.Core/Command/SceCommandTypeResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ namespace Pal3.Core.Command
using System.Reflection;
using System.Runtime.Serialization;

public static class SceCommandTypeResolver
public sealed class SceCommandTypeResolver : ISceCommandTypeResolver
{
private static bool _isInitialized;
private static readonly Dictionary<uint, Type> SceCommandTypeCache = new ();

private static void Init()
public void Init()
{
if (_isInitialized) return;

Expand Down Expand Up @@ -78,12 +78,16 @@ private static uint GetHashCode(ushort commandId, ushort userVariableMask)
/// <param name="commandId">SceCommand Id</param>
/// <param name="userVariableMask">User variable mask</param>
/// <returns>Type of the command, null if not found</returns>
public static Type GetType(ushort commandId, ushort userVariableMask)
public Type GetType(ushort commandId, ushort userVariableMask)
{
if (!_isInitialized) Init();
if (!_isInitialized)
{
throw new InvalidOperationException(
$"[{nameof(SceCommandTypeResolver)}] is not initialized, " +
$"call [{nameof(Init)}] first");
}

uint hashCode = GetHashCode(commandId, userVariableMask);

return SceCommandTypeCache.TryGetValue(hashCode, out Type type) ? type : null; // not found
}
}
Expand Down
12 changes: 10 additions & 2 deletions Assets/Scripts/Pal3.Core/DataReader/Cpk/CpkArchive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ public void Init()
/// <returns>True if file exists</returns>
public bool FileExists(string fileVirtualPath, out uint filePathCrcHash)
{
if (!_isInitialized)
{
throw new InvalidOperationException("Initialize the archive before accessing its content");
}
filePathCrcHash = _crcHash.Compute(fileVirtualPath.ToLower(), _codepage);
return _crcToTableEntityMap.ContainsKey(filePathCrcHash);
}
Expand All @@ -177,6 +181,11 @@ public bool FileExists(string fileVirtualPath, out uint filePathCrcHash)
/// <returns>File content in byte array</returns>
public byte[] ReadAllBytes(uint fileVirtualPathCrcHash)
{
if (!_isInitialized)
{
throw new InvalidOperationException("Initialize the archive before accessing its content");
}

if (!_crcToTableEntityMap.ContainsKey(fileVirtualPathCrcHash))
{
throw new FileNotFoundException(
Expand Down Expand Up @@ -247,8 +256,7 @@ public IEnumerable<CpkEntry> GetRootEntries()
{
if (!_isInitialized)
{
throw new InvalidOperationException(
"Initialize the archive before accessing its content");
throw new InvalidOperationException("Initialize the archive before accessing its content");
}

return GetChildren(0); // 0 is the CRC of the root directory
Expand Down
6 changes: 3 additions & 3 deletions Assets/Scripts/Pal3.Core/DataReader/Cpk/Crc32Hash.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public void Init()
{
if (_initialized) return;

// generate the table of CRC remainders for all possible bytes
// Generate the table of CRC remainders for all possible bytes
for (uint i = 0; i <= CRC_TABLE_MAX; i++)
{
var crcAccum = i << 24;
uint crcAccum = i << 24;
for (var j = 0; j < 8; j++)
{
crcAccum = (crcAccum & 0x80000000L) != 0 ?
(crcAccum << 1) ^ POLYNOMIAL :
crcAccum << 1;
(crcAccum << 1);
}
CrcTable[i] = crcAccum;
}
Expand Down
6 changes: 3 additions & 3 deletions Assets/Scripts/Pal3.Core/DataReader/IFileReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ namespace Pal3.Core.DataReader
/// <typeparam name="T">File type</typeparam>
public interface IFileReader<out T>
{
T Read(IBinaryReader reader, int codepage);
public T Read(IBinaryReader reader, int codepage);

T Read(byte[] data, int codepage)
public T Read(byte[] data, int codepage)
{
// Use unsafe binary reader (faster) if IL2CPP is enabled
// otherwise use safe reader
Expand All @@ -29,7 +29,7 @@ T Read(byte[] data, int codepage)
return Read(reader, codepage);
}

T Read(Stream stream, int codepage)
public T Read(Stream stream, int codepage)
{
// Use unsafe binary reader (faster) if IL2CPP is enabled
// otherwise use safe reader
Expand Down
2 changes: 1 addition & 1 deletion Assets/Scripts/Pal3.Core/FileSystem/CpkFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void ExtractTo(string outputFolder)
{
foreach ((string cpkFileName, CpkArchive cpkArchive) in _cpkArchives)
{
var outputDir = outputFolder + cpkFileName + Path.DirectorySeparatorChar;
string outputDir = outputFolder + cpkFileName + Path.DirectorySeparatorChar;

if (!Directory.Exists(outputDir))
{
Expand Down
43 changes: 0 additions & 43 deletions Assets/Scripts/Pal3.Core/Utilities/BinaryReaderMethodResolver.cs

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion Assets/Scripts/Pal3.Core/Utilities/CoreUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static class CoreUtility
{
public static T ReadStruct<T>(Stream stream) where T : struct
{
var structSize = Marshal.SizeOf(typeof(T));
int structSize = Marshal.SizeOf(typeof(T));
byte[] buffer = new byte[structSize];
_ = stream.Read(buffer);
return ReadStructInternal<T>(buffer);
Expand Down
6 changes: 3 additions & 3 deletions Assets/Scripts/Pal3.Core/Utilities/Requires.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public static class Requires
public static T IsNotNull<T>([NotNull] T instance, string paramName)
where T : class
{
if (typeof(T) == typeof(System.Object) ||
typeof(T).IsSubclassOf(typeof(System.Object)))
if (typeof(T) == typeof(Object) ||
typeof(T).IsSubclassOf(typeof(Object)))
{
if (System.Object.ReferenceEquals(null, instance))
if (ReferenceEquals(null, instance))
{
throw new ArgumentNullException(paramName);
}
Expand Down
Loading

0 comments on commit de98baa

Please sign in to comment.