Use Constructor class in PointerArray

This commit is contained in:
Deukhoofd 2020-08-24 18:33:04 +02:00
parent f74f29daef
commit 2c5f35c640
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
9 changed files with 103 additions and 34 deletions

View File

@ -64,7 +64,7 @@ namespace PkmnLibSharp.Battling
{
if (_sides != null) return _sides;
var ptr = Creaturelib.Generated.Battle.GetSides(Ptr);
_sides = new ReadOnlyNativePtrArray<BattleSide>(ptr, (int) SidesCount);
_sides = new ReadOnlyNativePtrArray<BattleSide>(ptr, (int) SidesCount, Constructor.GenericType.BattleSide);
return _sides;
}
}
@ -77,7 +77,7 @@ namespace PkmnLibSharp.Battling
{
if (_parties != null) return _parties;
var ptr = Creaturelib.Generated.Battle.GetParties(Ptr);
_parties = new ReadOnlyNativePtrArray<BattleParty>(ptr, (int) PartiesCount);
_parties = new ReadOnlyNativePtrArray<BattleParty>(ptr, (int) PartiesCount, Constructor.GenericType.BattleParty);
return _parties;
}
}

View File

@ -35,7 +35,7 @@ namespace PkmnLibSharp.Battling
/// <summary>
/// Get the first hit for the first target. Honestly just here so I can quickly read hit info from my debugger.
/// </summary>
public HitData FirstHit => GetHitData(Targets[0], 0);
public HitData FirstHit => GetHitData(Targets[0]!, 0);
public byte NumberOfHits => Creaturelib.Generated.ExecutingAttack.GetNumberOfHits(Ptr);
@ -46,7 +46,7 @@ namespace PkmnLibSharp.Battling
if (_targets != null) return _targets;
var size = Creaturelib.Generated.ExecutingAttack.GetTargetCount(Ptr);
var ptr = Creaturelib.Generated.ExecutingAttack.GetTargets(Ptr);
_targets = new ReadOnlyNativePtrArray<Pokemon>(ptr, size);
_targets = new ReadOnlyNativePtrArray<Pokemon>(ptr, size, Constructor.GenericType.Pokemon);
return _targets;
}
}

View File

@ -173,7 +173,7 @@ namespace PkmnLibSharp.Battling
if (_moves != null) return _moves;
var movesLength = Creaturelib.Generated.Creature.GetAttacksCount(Ptr);
var movesPtr = Creaturelib.Generated.Creature.GetAttacks(Ptr);
_moves = new ReadOnlyNativePtrArray<LearnedMove>(movesPtr, (int) movesLength);
_moves = new ReadOnlyNativePtrArray<LearnedMove>(movesPtr, (int) movesLength, Constructor.GenericType.LearnedMove);
return _moves;
}
}

View File

@ -7,7 +7,7 @@ namespace PkmnLibSharp.Battling
{
public class PokemonParty : PointerWrapper, IEnumerable<Pokemon>
{
private ReadOnlyNativePtrArray<Pokemon?>? _party;
private ReadOnlyNativePtrArray<Pokemon>? _party;
internal PokemonParty(IntPtr ptr) : base(ptr){}
@ -46,13 +46,13 @@ namespace PkmnLibSharp.Battling
return Creaturelib.Generated.CreatureParty.HasAvailableCreatures(Ptr) == 1;
}
public ReadOnlyNativePtrArray<Pokemon?> Party
public ReadOnlyNativePtrArray<Pokemon> Party
{
get
{
if (_party != null) return _party;
var ptr = Creaturelib.Generated.CreatureParty.GetParty(Ptr);
_party = new ReadOnlyNativePtrArray<Pokemon?>(ptr, (int) Length);
_party = new ReadOnlyNativePtrArray<Pokemon>(ptr, (int) Length, Constructor.GenericType.Pokemon);
return _party;
}
}

View File

@ -10,7 +10,7 @@ namespace PkmnLibSharp.Library.Evolution
{
public sealed class EvolutionData : PointerWrapper
{
private EvolutionData(IntPtr ptr) : base(ptr)
internal EvolutionData(IntPtr ptr) : base(ptr)
{
}

View File

@ -25,7 +25,8 @@ namespace PkmnLibSharp.Library
if (_distinctLevelMoves != null) return _distinctLevelMoves;
var count = LearnableAttacks.GetDistinctLevelAttacksCount(Ptr);
var ptr = LearnableAttacks.GetDistinctLevelAttacks(Ptr);
_distinctLevelMoves = new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count);
_distinctLevelMoves =
new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.LearnableMoves);
return _distinctLevelMoves;
}
}
@ -37,7 +38,7 @@ namespace PkmnLibSharp.Library
if (_eggMoves != null) return _eggMoves;
var count = Pkmnlib.Generated.LearnableMoves.GetEggMovesCount(Ptr);
var ptr = Pkmnlib.Generated.LearnableMoves.GetEggMoves(Ptr);
_eggMoves = new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count);
_eggMoves = new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.MoveData);
return _eggMoves;
}
}
@ -47,11 +48,11 @@ namespace PkmnLibSharp.Library
{
if (LearnableAttacks.HasAttacksForLevel(Ptr, level) != 1)
{
return new ReadOnlyNativePtrArray<MoveData>();
return new ReadOnlyNativePtrArray<MoveData>(Constructor.GenericType.MoveData);
}
var count = LearnableAttacks.GetAttacksForLevelCount(Ptr, level);
var ptr = LearnableAttacks.GetAttacksForLevel(Ptr, level);
return new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count);
return new ReadOnlyNativePtrArray<MoveData>(ptr, (int) count, Constructor.GenericType.MoveData);
}
public void AddLevelMove(byte level, MoveData move)

View File

@ -55,7 +55,7 @@ namespace PkmnLibSharp.Library
if (_formes != null) return _formes;
var startPtr = CreatureSpecies.GetVariants(Ptr);
var size = CreatureSpecies.GetVariantsCount(Ptr);
_formes = new ReadOnlyNativePtrArray<Forme>(startPtr, (int) size);
_formes = new ReadOnlyNativePtrArray<Forme>(startPtr, (int) size, Constructor.GenericType.Forme);
return _formes;
}
}
@ -68,7 +68,7 @@ namespace PkmnLibSharp.Library
var ptr = IntPtr.Zero;
PokemonSpecies.GetEvolutions(Ptr, ref ptr);
var length = PokemonSpecies.GetEvolutionCount(Ptr);
_evolutions = new ReadOnlyNativePtrArray<EvolutionData>(ptr, (int) length);
_evolutions = new ReadOnlyNativePtrArray<EvolutionData>(ptr, (int) length, Constructor.GenericType.EvolutionData);
return _evolutions;
}
}

View File

@ -2,16 +2,32 @@ using System;
using System.Runtime.Serialization;
using PkmnLibSharp.Battling;
using PkmnLibSharp.Library;
using PkmnLibSharp.Library.Items;
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>();
public static Constructor Active { get; set; } =
new Constructor<
Species, Forme, MoveData, Item, LearnableMoves,
Pokemon, Battle, BattleParty, BattleSide, LearnedMove>();
internal enum GenericType
{
Species, Forme, MoveData, Item, LearnableMoves, EvolutionData,
Pokemon, Battle,
BattleParty,
BattleSide,
LearnedMove
}
internal abstract Species? ConstructSpecies(IntPtr ptr);
internal abstract Forme? ConstructForme(IntPtr ptr);
internal abstract MoveData? ConstructMove(IntPtr ptr);
@ -19,11 +35,39 @@ namespace PkmnLibSharp.Utilities
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>
TPokemon, TBattle, TBattleParty, TBattleSide, TLearnedMove>
: Constructor
where TSpecies : Species
where TForme : Forme
@ -33,6 +77,9 @@ namespace PkmnLibSharp.Utilities
where TPokemon : Pokemon
where TBattle : Battle
where TBattleParty : BattleParty
where TBattleSide : BattleSide
where TLearnedMove : LearnedMove
{
private readonly Type _speciesType = typeof(TSpecies);
private readonly Type _formeType = typeof(TForme);
@ -42,7 +89,10 @@ namespace PkmnLibSharp.Utilities
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;
@ -85,5 +135,20 @@ namespace PkmnLibSharp.Utilities
{
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);
}
}
}

View File

@ -8,24 +8,27 @@ namespace PkmnLibSharp.Utilities
public class ReadOnlyNativePtrArray<T> : IReadOnlyList<T> where T : PointerWrapper
{
private readonly IntPtr _ptr;
private T?[] _cache;
private Type _type = typeof(T);
private readonly T?[] _cache;
private readonly Type _type = typeof(T);
private Constructor.GenericType _constructorType;
internal ReadOnlyNativePtrArray()
internal ReadOnlyNativePtrArray(Constructor.GenericType type)
{
_ptr = IntPtr.Zero;
Count = 0;
_cache = new T[Count];
_constructorType = type;
}
internal ReadOnlyNativePtrArray(IntPtr ptr, int length)
internal ReadOnlyNativePtrArray(IntPtr ptr, int length, Constructor.GenericType type)
{
_ptr = ptr;
Count = length;
_cache = new T[Count];
_constructorType = type;
}
public IEnumerator<T> GetEnumerator()
public IEnumerator<T?> GetEnumerator()
{
for (var i = 0; i < Count; i++)
{
@ -42,14 +45,15 @@ namespace PkmnLibSharp.Utilities
{
foreach (var v in this)
{
if (item == null)
if (item == null && v == null)
{
if (v.Ptr == IntPtr.Zero)
return true;
continue;
}
if (item.Ptr == v.Ptr)
return true;
}
if (v != null && item != null)
{
if (item.Ptr == v.Ptr)
return true;
}
}
return false;
}
@ -69,7 +73,7 @@ namespace PkmnLibSharp.Utilities
return -1;
}
public T this[int index]
public T? this[int index]
{
get
{
@ -84,8 +88,7 @@ namespace PkmnLibSharp.Utilities
return _cache[index]!;
if (PointerWrapper.TryResolvePointer(p, out T? t))
return t!;
t = (T) FormatterServices.GetUninitializedObject(_type);
t.Initialize(p);
t = (T?) Constructor.Active.InstantiateGeneric(_constructorType, p);
_cache[index] = t;
return t;
}