Implements PokemonLibrary

This commit is contained in:
Deukhoofd 2020-05-19 14:25:21 +02:00
parent 4f249de34e
commit 61b5bd710e
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
8 changed files with 290 additions and 7 deletions

View File

@ -1,3 +1,4 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Library.GrowthRates

View File

@ -1,3 +1,4 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Library.GrowthRates

View File

@ -54,6 +54,10 @@ namespace PkmnLibSharp.Library.Items
return item;
}
internal ItemLibrary(IntPtr ptr) : base(ptr)
{
}
public ItemLibrary(ulong initialCapacity) : base(
Creatureliblibrary.Generated.ItemLibrary.Construct(initialCapacity))
{

View File

@ -1,3 +1,4 @@
using System;
using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Library
@ -8,6 +9,14 @@ namespace PkmnLibSharp.Library
public byte MaximalMoves => Creatureliblibrary.Generated.LibrarySettings.GetMaximalMoves(Ptr);
public ushort ShinyRate => Pkmnlib.Generated.LibrarySettings.GetShinyRate(Ptr);
internal LibrarySettings()
{
}
internal LibrarySettings(IntPtr ptr) : base(ptr)
{
}
public LibrarySettings(byte maximalLevel, byte maximalMoves, ushort shinyRate) : base(
Pkmnlib.Generated.LibrarySettings.Construct(maximalLevel, maximalMoves, shinyRate))
{

View File

@ -0,0 +1,63 @@
using System;
using Creatureliblibrary.Generated;
using PkmnLibSharp.Library.Moves;
using PkmnLibSharp.Utilities;
using GrowthRateLibrary = PkmnLibSharp.Library.GrowthRates.GrowthRateLibrary;
using ItemLibrary = PkmnLibSharp.Library.Items.ItemLibrary;
namespace PkmnLibSharp.Library
{
public class PokemonLibrary : PointerWrapper
{
private LibrarySettings _settings;
public LibrarySettings Settings =>
_settings ??= ResolveOrCreatePtr<LibrarySettings>(DataLibrary.GetSettings(Ptr));
private SpeciesLibrary _species;
public SpeciesLibrary SpeciesLibrary =>
_species ??= ResolveOrCreatePtr<SpeciesLibrary>(DataLibrary.GetSpeciesLibrary(Ptr));
private MoveLibrary _moves;
public MoveLibrary MoveLibrary => _moves ??= ResolveOrCreatePtr<MoveLibrary>(DataLibrary.GetAttackLibrary(Ptr));
private ItemLibrary _items;
public ItemLibrary ItemLibrary => _items ??= ResolveOrCreatePtr<ItemLibrary>(DataLibrary.GetItemLibrary(Ptr));
private GrowthRateLibrary _growthRateLibrary;
public GrowthRateLibrary GrowthRateLibrary => _growthRateLibrary ??=
ResolveOrCreatePtr<GrowthRateLibrary>(DataLibrary.GetGrowthRates(Ptr));
private TypeLibrary _typeLibrary;
public TypeLibrary TypeLibrary =>
_typeLibrary ??= ResolveOrCreatePtr<TypeLibrary>(DataLibrary.GetTypeLibrary(Ptr));
private NatureLibrary _natureLibrary;
public NatureLibrary NatureLibrary => _natureLibrary ??=
ResolveOrCreatePtr<NatureLibrary>(Pkmnlib.Generated.PokemonLibrary.GetNatureLibrary(Ptr));
internal PokemonLibrary(IntPtr ptr) : base(ptr)
{
}
public static PokemonLibrary Create(LibrarySettings settings, SpeciesLibrary species, MoveLibrary moves,
ItemLibrary items,
GrowthRateLibrary growthRates, TypeLibrary types, NatureLibrary natures)
{
var ptr = IntPtr.Zero;
Pkmnlib.Generated.PokemonLibrary.Construct(ref ptr, settings.Ptr, species.Ptr, moves.Ptr, items.Ptr,
growthRates.Ptr, types.Ptr, natures.Ptr).Assert();
return new PokemonLibrary(ptr);
}
protected override void DeletePtr()
{
Pkmnlib.Generated.PokemonLibrary.Destruct(Ptr);
}
}
}

View File

@ -54,6 +54,10 @@ namespace PkmnLibSharp.Library
return species;
}
internal SpeciesLibrary(IntPtr ptr) : base(ptr)
{
}
public SpeciesLibrary(ulong initialCapacity) : base(
Creatureliblibrary.Generated.SpeciesLibrary.Construct(initialCapacity))
{

View File

@ -1,19 +1,24 @@
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
namespace PkmnLibSharp.Utilities
{
public abstract class PointerWrapper : IDisposable
{
private readonly IntPtr _ptr;
internal IntPtr Ptr
{
get
{
if (_isDeleted)
{
throw new Exception("Pointer access after dispose detected. This is not legal, and will cause native exceptions.");
throw new Exception(
"Pointer access after dispose detected. This is not legal, and will cause native exceptions.");
}
return _ptr;
}
}
@ -23,11 +28,15 @@ namespace PkmnLibSharp.Utilities
private static readonly ConcurrentDictionary<IntPtr, WeakReference<object>> Cached =
new ConcurrentDictionary<IntPtr, WeakReference<object>>();
private protected PointerWrapper()
{
}
protected PointerWrapper(IntPtr ptr)
{
_ptr = ptr;
var weakRef = new WeakReference<object>(this);
Cached.TryAdd(ptr, weakRef);
Cached.AddOrUpdate(ptr, weakRef, (intPtr, reference) => weakRef);
}
~PointerWrapper()
@ -42,15 +51,43 @@ namespace PkmnLibSharp.Utilities
{
if (val.TryGetTarget(out var target))
{
result = (T) target;
return true;
if (target is T r)
{
result = r;
return true;
}
}
}
result = null;
return false;
}
public static T ResolveOrCreatePtr<T>(IntPtr p) where T : PointerWrapper
{
if (TryResolvePointer<T>(p, out var result))
return result;
var ctor = typeof(T)
.GetConstructors(
BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance
)
.FirstOrDefault(x =>
{
var pars = x.GetParameters();
return pars.Length == 1 && pars[0].ParameterType == typeof(IntPtr);
});
if (ctor == null)
{
throw new Exception($"Unable to find constructor of type {typeof(T).FullName} with a single parameter of IntPtr.");
}
var instance = ctor.Invoke(new object[] {p}) as T;
return instance;
}
protected abstract void DeletePtr();
public virtual void Dispose()
{
if (_isDeleted)
@ -59,5 +96,23 @@ namespace PkmnLibSharp.Utilities
DeletePtr();
_isDeleted = true;
}
protected bool Equals(PointerWrapper other)
{
return _ptr.Equals(other._ptr);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((PointerWrapper) obj);
}
public override int GetHashCode()
{
return _ptr.GetHashCode();
}
}
}

View File

@ -0,0 +1,146 @@
using NUnit.Framework;
using PkmnLibSharp.Library;
using PkmnLibSharp.Library.GrowthRates;
using PkmnLibSharp.Library.Items;
using PkmnLibSharp.Library.Moves;
namespace PkmnLibSharpTests.Library
{
public class PokemonLibraryTests
{
[Test]
public void ConstructDestruct()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
lib.Dispose();
}
[Test]
public void GetSpeciesLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var s = lib.SpeciesLibrary;
Assert.AreEqual(species, s);
lib.Dispose();
}
[Test]
public void GetLibrarySettings()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var s = lib.Settings;
Assert.AreEqual(settings, s);
lib.Dispose();
}
[Test]
public void GetMoveLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var m = lib.MoveLibrary;
Assert.AreEqual(moves, m);
lib.Dispose();
}
[Test]
public void GetItemLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var i = lib.ItemLibrary;
Assert.AreEqual(items, i);
lib.Dispose();
}
[Test]
public void GetGrowthRateLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var g = lib.GrowthRateLibrary;
Assert.AreEqual(gr, g);
lib.Dispose();
}
[Test]
public void GetTypeLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var t = lib.TypeLibrary;
Assert.AreEqual(types, t);
lib.Dispose();
}
[Test]
public void GetNatureLibrary()
{
var settings = new LibrarySettings(100, 4, 4096);
var species = new SpeciesLibrary(10);
var moves = MoveLibrary.Create(10);
var items = new ItemLibrary(10);
var gr = new GrowthRateLibrary(10);
var types = new TypeLibrary(10);
var natures = new NatureLibrary(10);
var lib = PokemonLibrary.Create(settings, species, moves, items, gr, types, natures);
var n = lib.NatureLibrary;
Assert.AreEqual(natures, n);
lib.Dispose();
}
}
}