PkmnLibSharp/PkmnLibSharp/Utilities/Constructor.cs

165 lines
5.9 KiB
C#

using System;
using System.Runtime.Serialization;
using PkmnLibSharp.Battling;
using PkmnLibSharp.Library;
using PkmnLibSharp.Library.Moves;
using Battle = PkmnLibSharp.Battling.Battle;
using EvolutionData = PkmnLibSharp.Library.Evolution.EvolutionData;
using Item = PkmnLibSharp.Library.Items.Item;
using LearnableMoves = PkmnLibSharp.Library.LearnableMoves;
using Pokemon = PkmnLibSharp.Battling.Pokemon;
namespace PkmnLibSharp.Utilities
{
public abstract class Constructor
{
public static Constructor Active { get; set; } =
new Constructor<Species, Forme, MoveData, Item, LearnableMoves, Pokemon, Battle, BattleParty, BattleSide,
LearnedMove, Ability>();
internal enum GenericType
{
Species,
Forme,
MoveData,
Item,
LearnableMoves,
EvolutionData,
Pokemon,
Battle,
BattleParty,
BattleSide,
LearnedMove,
Ability
}
internal abstract Species? ConstructSpecies(IntPtr ptr);
internal abstract Ability? ConstructAbility(IntPtr ptr);
internal abstract Forme? ConstructForme(IntPtr ptr);
internal abstract MoveData? ConstructMove(IntPtr ptr);
internal abstract Item? ConstructItem(IntPtr ptr);
internal abstract LearnableMoves? ConstructLearnableMoves(IntPtr ptr);
internal abstract Pokemon? ConstructPokemon(IntPtr ptr);
internal abstract Battle? ConstructBattle(IntPtr ptr);
internal abstract BattleParty? ConstructBattleParty(IntPtr ptr);
internal abstract BattleSide? ConstructBattleSide(IntPtr ptr);
internal abstract LearnedMove? ConstructLearnedMove(IntPtr ptr);
internal EvolutionData? ConstructEvolutionData(IntPtr ptr)
{
return new EvolutionData(ptr);
}
internal object? InstantiateGeneric(GenericType type, IntPtr ptr)
{
return type switch
{
GenericType.Species => ConstructSpecies(ptr),
GenericType.Forme => ConstructForme(ptr),
GenericType.MoveData => ConstructMove(ptr),
GenericType.Item => ConstructItem(ptr),
GenericType.LearnableMoves => ConstructLearnableMoves(ptr),
GenericType.EvolutionData => ConstructEvolutionData(ptr),
GenericType.Pokemon => ConstructPokemon(ptr),
GenericType.Battle => ConstructBattle(ptr),
GenericType.BattleParty => ConstructBattleParty(ptr),
GenericType.BattleSide => ConstructBattleSide(ptr),
GenericType.LearnedMove => ConstructLearnedMove(ptr),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
}
public class Constructor<
TSpecies, TForme, TMoveData, TItem, TLearnableMoves, TPokemon, TBattle, TBattleParty, TBattleSide, TLearnedMove,
TAbility> : Constructor where TSpecies : Species
where TForme : Forme
where TMoveData : MoveData
where TItem : Item
where TLearnableMoves : LearnableMoves
where TPokemon : Pokemon
where TBattle : Battle
where TBattleParty : BattleParty
where TBattleSide : BattleSide
where TLearnedMove : LearnedMove
where TAbility : Ability
{
private readonly Type _speciesType = typeof(TSpecies);
private readonly Type _formeType = typeof(TForme);
private readonly Type _moveDataType = typeof(TMoveData);
private readonly Type _itemType = typeof(TItem);
private readonly Type _learnableMovesType = typeof(TLearnableMoves);
private readonly Type _abilityType = typeof(TAbility);
private readonly Type _pokemonType = typeof(TPokemon);
private readonly Type _battleType = typeof(TBattle);
private readonly Type _battlePartyType = typeof(TBattleParty);
private readonly Type _battleSideType = typeof(TBattleSide);
private readonly Type _learnedMoveType = typeof(TLearnedMove);
private static T? Create<T>(IntPtr ptr, Type t) where T : PointerWrapper
{
if (ptr == IntPtr.Zero) return null;
var o = (T)FormatterServices.GetUninitializedObject(t);
o.Initialize(ptr);
return o;
}
internal override Species? ConstructSpecies(IntPtr ptr)
{
return Create<TSpecies>(ptr, _speciesType);
}
internal override Ability? ConstructAbility(IntPtr ptr)
{
return Create<TAbility>(ptr, _abilityType);
}
internal override Forme? ConstructForme(IntPtr ptr)
{
return Create<TForme>(ptr, _formeType);
}
internal override MoveData? ConstructMove(IntPtr ptr)
{
return Create<TMoveData>(ptr, _moveDataType);
}
internal override Item? ConstructItem(IntPtr ptr)
{
return Create<TItem>(ptr, _itemType);
}
internal override LearnableMoves? ConstructLearnableMoves(IntPtr ptr)
{
return Create<TLearnableMoves>(ptr, _learnableMovesType);
}
internal override Pokemon? ConstructPokemon(IntPtr ptr)
{
return Create<TPokemon>(ptr, _pokemonType);
}
internal override Battle? ConstructBattle(IntPtr ptr)
{
return Create<TBattle>(ptr, _battleType);
}
internal override BattleParty? ConstructBattleParty(IntPtr ptr)
{
return Create<TBattleParty>(ptr, _battlePartyType);
}
internal override BattleSide? ConstructBattleSide(IntPtr ptr)
{
return Create<TBattleSide>(ptr, _battleSideType);
}
internal override LearnedMove? ConstructLearnedMove(IntPtr ptr)
{
return Create<TLearnedMove>(ptr, _learnedMoveType);
}
}
}