2024-07-27 14:26:45 +00:00
|
|
|
using System.Linq.Expressions;
|
|
|
|
using System.Reflection;
|
2024-07-28 10:52:17 +00:00
|
|
|
using JetBrains.Annotations;
|
2024-07-27 14:26:45 +00:00
|
|
|
using PkmnLib.Dynamic.Libraries;
|
2024-07-28 10:18:12 +00:00
|
|
|
using PkmnLib.Static.Utils;
|
2024-07-27 14:26:45 +00:00
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
namespace PkmnLib.Dynamic.ScriptHandling.Registry;
|
2024-07-27 14:26:45 +00:00
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// A helper data class that's passed through all plugins when initializing a library, so they can
|
|
|
|
/// register their scripts and other data.
|
|
|
|
/// </summary>
|
2024-07-27 14:26:45 +00:00
|
|
|
public class ScriptRegistry
|
|
|
|
{
|
2024-07-28 10:52:17 +00:00
|
|
|
private readonly Dictionary<(ScriptCategory category, StringKey name), Func<Script>> _scriptTypes = new();
|
2024-07-27 14:26:45 +00:00
|
|
|
private IBattleStatCalculator? _battleStatCalculator;
|
|
|
|
private IDamageCalculator? _damageCalculator;
|
|
|
|
private IMiscLibrary? _miscLibrary;
|
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Automatically register all scripts in the given assembly that have the <see cref="ScriptAttribute"/>, and
|
|
|
|
/// inherit from <see cref="Script"/>.
|
|
|
|
/// </summary>
|
2024-07-27 14:26:45 +00:00
|
|
|
public void RegisterAssemblyScripts(Assembly assembly)
|
|
|
|
{
|
|
|
|
var baseType = typeof(Script);
|
|
|
|
foreach (var type in assembly.GetTypes().Where(t => baseType.IsAssignableFrom(t)))
|
|
|
|
{
|
|
|
|
var attribute = type.GetCustomAttribute<ScriptAttribute>();
|
|
|
|
if (attribute == null)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
RegisterScriptType(attribute.Category, attribute.Name, type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Register a script type with the given category and name.
|
|
|
|
/// </summary>
|
|
|
|
[PublicAPI]
|
2024-07-28 10:18:12 +00:00
|
|
|
public void RegisterScriptType(ScriptCategory category, StringKey name, Type type)
|
2024-07-27 14:26:45 +00:00
|
|
|
{
|
|
|
|
if (type == null)
|
|
|
|
throw new ArgumentNullException(nameof(type));
|
|
|
|
|
|
|
|
var constructor = type.GetConstructor(Type.EmptyTypes);
|
|
|
|
if (constructor == null)
|
|
|
|
throw new ArgumentException("The type must have a parameterless constructor.");
|
|
|
|
|
|
|
|
// We create a lambda that creates a new instance of the script type.
|
|
|
|
// This is more performant than using Activator.CreateInstance.
|
|
|
|
_scriptTypes[(category, name)] = Expression.Lambda<Func<Script>>(Expression.New(constructor)).Compile();
|
|
|
|
}
|
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Register a battle stat calculator.
|
|
|
|
/// </summary>
|
2024-07-27 14:26:45 +00:00
|
|
|
public void RegisterBattleStatCalculator<T>(T battleStatCalculator)
|
|
|
|
where T : IBattleStatCalculator => _battleStatCalculator = battleStatCalculator;
|
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Register a damage calculator.
|
|
|
|
/// </summary>
|
2024-07-27 14:26:45 +00:00
|
|
|
public void RegisterDamageCalculator<T>(T damageCalculator)
|
|
|
|
where T : IDamageCalculator => _damageCalculator = damageCalculator;
|
|
|
|
|
2024-07-28 10:52:17 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Register a misc library.
|
|
|
|
/// </summary>
|
2024-07-27 14:26:45 +00:00
|
|
|
public void RegisterMiscLibrary<T>(T miscLibrary) where T : IMiscLibrary
|
|
|
|
=> _miscLibrary = miscLibrary;
|
|
|
|
|
2024-07-28 10:18:12 +00:00
|
|
|
internal Dictionary<(ScriptCategory category, StringKey name), Func<Script>> ScriptTypes => _scriptTypes;
|
2024-07-27 14:26:45 +00:00
|
|
|
internal IBattleStatCalculator? BattleStatCalculator => _battleStatCalculator;
|
|
|
|
internal IDamageCalculator? DamageCalculator => _damageCalculator;
|
|
|
|
internal IMiscLibrary? MiscLibrary => _miscLibrary;
|
|
|
|
}
|