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; using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Library.GrowthRates namespace PkmnLibSharp.Library.GrowthRates
@ -28,7 +29,7 @@ namespace PkmnLibSharp.Library.GrowthRates
{ {
Creatureliblibrary.Generated.GrowthRateLibrary.AddGrowthRate(Ptr, name.ToPtr(), gr.Ptr).Assert(); Creatureliblibrary.Generated.GrowthRateLibrary.AddGrowthRate(Ptr, name.ToPtr(), gr.Ptr).Assert();
} }
protected override void DeletePtr() protected override void DeletePtr()
{ {
Creatureliblibrary.Generated.GrowthRateLibrary.Destruct(Ptr); Creatureliblibrary.Generated.GrowthRateLibrary.Destruct(Ptr);

View File

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

View File

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

View File

@ -1,3 +1,4 @@
using System;
using PkmnLibSharp.Utilities; using PkmnLibSharp.Utilities;
namespace PkmnLibSharp.Library namespace PkmnLibSharp.Library
@ -7,7 +8,15 @@ namespace PkmnLibSharp.Library
public byte MaximalLevel => Creatureliblibrary.Generated.LibrarySettings.GetMaximalLevel(Ptr); public byte MaximalLevel => Creatureliblibrary.Generated.LibrarySettings.GetMaximalLevel(Ptr);
public byte MaximalMoves => Creatureliblibrary.Generated.LibrarySettings.GetMaximalMoves(Ptr); public byte MaximalMoves => Creatureliblibrary.Generated.LibrarySettings.GetMaximalMoves(Ptr);
public ushort ShinyRate => Pkmnlib.Generated.LibrarySettings.GetShinyRate(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( public LibrarySettings(byte maximalLevel, byte maximalMoves, ushort shinyRate) : base(
Pkmnlib.Generated.LibrarySettings.Construct(maximalLevel, maximalMoves, shinyRate)) 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; return species;
} }
internal SpeciesLibrary(IntPtr ptr) : base(ptr)
{
}
public SpeciesLibrary(ulong initialCapacity) : base( public SpeciesLibrary(ulong initialCapacity) : base(
Creatureliblibrary.Generated.SpeciesLibrary.Construct(initialCapacity)) Creatureliblibrary.Generated.SpeciesLibrary.Construct(initialCapacity))
{ {

View File

@ -1,19 +1,24 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Linq;
using System.Reflection;
namespace PkmnLibSharp.Utilities namespace PkmnLibSharp.Utilities
{ {
public abstract class PointerWrapper : IDisposable public abstract class PointerWrapper : IDisposable
{ {
private readonly IntPtr _ptr; private readonly IntPtr _ptr;
internal IntPtr Ptr internal IntPtr Ptr
{ {
get get
{ {
if (_isDeleted) 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; return _ptr;
} }
} }
@ -23,13 +28,17 @@ namespace PkmnLibSharp.Utilities
private static readonly ConcurrentDictionary<IntPtr, WeakReference<object>> Cached = private static readonly ConcurrentDictionary<IntPtr, WeakReference<object>> Cached =
new ConcurrentDictionary<IntPtr, WeakReference<object>>(); new ConcurrentDictionary<IntPtr, WeakReference<object>>();
private protected PointerWrapper()
{
}
protected PointerWrapper(IntPtr ptr) protected PointerWrapper(IntPtr ptr)
{ {
_ptr = ptr; _ptr = ptr;
var weakRef = new WeakReference<object>(this); var weakRef = new WeakReference<object>(this);
Cached.TryAdd(ptr, weakRef); Cached.AddOrUpdate(ptr, weakRef, (intPtr, reference) => weakRef);
} }
~PointerWrapper() ~PointerWrapper()
{ {
if (!_isDeleted) if (!_isDeleted)
@ -42,15 +51,43 @@ namespace PkmnLibSharp.Utilities
{ {
if (val.TryGetTarget(out var target)) if (val.TryGetTarget(out var target))
{ {
result = (T) target; if (target is T r)
return true; {
result = r;
return true;
}
} }
} }
result = null; result = null;
return false; 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(); protected abstract void DeletePtr();
public virtual void Dispose() public virtual void Dispose()
{ {
if (_isDeleted) if (_isDeleted)
@ -59,5 +96,23 @@ namespace PkmnLibSharp.Utilities
DeletePtr(); DeletePtr();
_isDeleted = true; _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();
}
}
}