Browse Source

Updated Build Status badge on documentation

pull/53/head
Anairkoen Schno 4 years ago
parent
commit
0918190f9c
Signed by: DaNike GPG Key ID: BEFB74D5F3FC4387
4 changed files with 139 additions and 139 deletions
  1. +7
    -7
      IPA.Loader/Config/Stores/Converters.cs
  2. +130
    -130
      IPA.Loader/Config/Stores/GeneratedStoreImpl/GeneratedStoreImpl.cs
  3. +1
    -1
      IPA.Loader/Config/Stores/GeneratedStoreImpl/ObjectStructure.cs
  4. +1
    -1
      docs/index.md

+ 7
- 7
IPA.Loader/Config/Stores/Converters.cs View File

@ -13,7 +13,7 @@ namespace IPA.Config.Stores.Converters
/// <summary> /// <summary>
/// Provides utility functions for custom converters. /// Provides utility functions for custom converters.
/// </summary> /// </summary>
public static class Converter
public static class Converter
{ {
/// <summary> /// <summary>
/// Gets the integral value of a <see cref="Value"/>, coercing a <see cref="FloatingPoint"/> if necessary, /// Gets the integral value of a <see cref="Value"/>, coercing a <see cref="FloatingPoint"/> if necessary,
@ -206,8 +206,8 @@ namespace IPA.Config.Stores.Converters
/// <typeparam name="T">the underlying type of the <see cref="Nullable{T}"/></typeparam> /// <typeparam name="T">the underlying type of the <see cref="Nullable{T}"/></typeparam>
/// <typeparam name="TConverter">the type to use as an underlying converter</typeparam> /// <typeparam name="TConverter">the type to use as an underlying converter</typeparam>
/// <seealso cref="NullableConverter{T}"/> /// <seealso cref="NullableConverter{T}"/>
public sealed class NullableConverter<T, TConverter> : NullableConverter<T>
where T : struct
public sealed class NullableConverter<T, TConverter> : NullableConverter<T>
where T : struct
where TConverter : ValueConverter<T>, new() where TConverter : ValueConverter<T>, new()
{ {
/// <summary> /// <summary>
@ -291,7 +291,7 @@ namespace IPA.Config.Stores.Converters
/// <returns>the deserialized enum value</returns> /// <returns>the deserialized enum value</returns>
/// <exception cref="ArgumentException">if <paramref name="value"/> is not a numeric node</exception> /// <exception cref="ArgumentException">if <paramref name="value"/> is not a numeric node</exception>
public override T FromValue(Value value, object parent) public override T FromValue(Value value, object parent)
=> (T)Enum.ToObject(typeof(T), Converter.IntValue(value)
=> (T)Enum.ToObject(typeof(T), Converter.IntValue(value)
?? throw new ArgumentException("Value not a numeric node", nameof(value))); ?? throw new ArgumentException("Value not a numeric node", nameof(value)));
/// <summary> /// <summary>
@ -494,7 +494,7 @@ namespace IPA.Config.Stores.Converters
internal class CharConverter : ValueConverter<char> internal class CharConverter : ValueConverter<char>
{ {
public override char FromValue(Value value, object parent) public override char FromValue(Value value, object parent)
=> (value as Text)?.Value[0]
=> (value as Text)?.Value[0]
?? throw new ArgumentException("Value not a text node", nameof(value)); // can throw nullptr ?? throw new ArgumentException("Value not a text node", nameof(value)); // can throw nullptr
public override Value ToValue(char obj, object parent) public override Value ToValue(char obj, object parent)
@ -504,7 +504,7 @@ namespace IPA.Config.Stores.Converters
internal class LongConverter : ValueConverter<long> internal class LongConverter : ValueConverter<long>
{ {
public override long FromValue(Value value, object parent) public override long FromValue(Value value, object parent)
=> Converter.IntValue(value)
=> Converter.IntValue(value)
?? throw new ArgumentException("Value not a numeric value", nameof(value)); ?? throw new ArgumentException("Value not a numeric value", nameof(value));
public override Value ToValue(long obj, object parent) public override Value ToValue(long obj, object parent)
@ -514,7 +514,7 @@ namespace IPA.Config.Stores.Converters
internal class ULongConverter : ValueConverter<ulong> internal class ULongConverter : ValueConverter<ulong>
{ {
public override ulong FromValue(Value value, object parent) public override ulong FromValue(Value value, object parent)
=> (ulong)(Converter.FloatValue(value)
=> (ulong)(Converter.FloatValue(value)
?? throw new ArgumentException("Value not a numeric value", nameof(value))); ?? throw new ArgumentException("Value not a numeric value", nameof(value)));
public override Value ToValue(ulong obj, object parent) public override Value ToValue(ulong obj, object parent)


+ 130
- 130
IPA.Loader/Config/Stores/GeneratedStoreImpl/GeneratedStoreImpl.cs View File

@ -1,132 +1,132 @@
using IPA.Config.Data;
using IPA.Config.Stores.Attributes;
using IPA.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.IO;
using Boolean = IPA.Config.Data.Boolean;
using System.Collections;
using IPA.Utilities;
using System.ComponentModel;
using System.Collections.Concurrent;
using IPA.Config.Data;
using IPA.Config.Stores.Attributes;
using IPA.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
using System.IO;
using Boolean = IPA.Config.Data.Boolean;
using System.Collections;
using IPA.Utilities;
using System.ComponentModel;
using System.Collections.Concurrent;
using IPA.Utilities.Async; using IPA.Utilities.Async;
#if NET3
using Net3_Proxy;
using Array = Net3_Proxy.Array;
#endif
[assembly: InternalsVisibleTo(IPA.Config.Stores.GeneratedStore.AssemblyVisibilityTarget)]
namespace IPA.Config.Stores
{
internal static partial class GeneratedStoreImpl
{
public static T Create<T>() where T : class => (T)Create(typeof(T));
public static IConfigStore Create(Type type) => Create(type, null);
private static readonly MethodInfo CreateGParent =
typeof(GeneratedStoreImpl).GetMethod(nameof(Create), BindingFlags.NonPublic | BindingFlags.Static, null,
CallingConventions.Any, new[] { typeof(IGeneratedStore) }, Array.Empty<ParameterModifier>());
internal static T Create<T>(IGeneratedStore parent) where T : class => (T)Create(typeof(T), parent);
private static IConfigStore Create(Type type, IGeneratedStore parent)
=> GetCreator(type)(parent);
private static readonly SingleCreationValueCache<Type, (GeneratedStoreCreator ctor, Type type)> generatedCreators
= new SingleCreationValueCache<Type, (GeneratedStoreCreator ctor, Type type)>();
#if NET3
using Net3_Proxy;
using Array = Net3_Proxy.Array;
#endif
[assembly: InternalsVisibleTo(IPA.Config.Stores.GeneratedStore.AssemblyVisibilityTarget)]
namespace IPA.Config.Stores
{
internal static partial class GeneratedStoreImpl
{
public static T Create<T>() where T : class => (T)Create(typeof(T));
public static IConfigStore Create(Type type) => Create(type, null);
private static readonly MethodInfo CreateGParent =
typeof(GeneratedStoreImpl).GetMethod(nameof(Create), BindingFlags.NonPublic | BindingFlags.Static, null,
CallingConventions.Any, new[] { typeof(IGeneratedStore) }, Array.Empty<ParameterModifier>());
internal static T Create<T>(IGeneratedStore parent) where T : class => (T)Create(typeof(T), parent);
private static IConfigStore Create(Type type, IGeneratedStore parent)
=> GetCreator(type)(parent);
private static readonly SingleCreationValueCache<Type, (GeneratedStoreCreator ctor, Type type)> generatedCreators
= new SingleCreationValueCache<Type, (GeneratedStoreCreator ctor, Type type)>();
private static (GeneratedStoreCreator ctor, Type type) GetCreatorAndGeneratedType(Type t) private static (GeneratedStoreCreator ctor, Type type) GetCreatorAndGeneratedType(Type t)
=> generatedCreators.GetOrAdd(t, MakeCreator);
internal static GeneratedStoreCreator GetCreator(Type t)
=> GetCreatorAndGeneratedType(t).ctor;
internal static Type GetGeneratedType(Type t)
=> GetCreatorAndGeneratedType(t).type;
internal const string GeneratedAssemblyName = "IPA.Config.Generated";
private static AssemblyBuilder assembly = null;
private static AssemblyBuilder Assembly
{
get
{
if (assembly == null)
{
var name = new AssemblyName(GeneratedAssemblyName);
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
}
return assembly;
}
}
internal static void DebugSaveAssembly(string file)
{
Assembly.Save(file);
}
private static ModuleBuilder module = null;
private static ModuleBuilder Module
{
get
{
if (module == null)
module = Assembly.DefineDynamicModule(Assembly.GetName().Name, Assembly.GetName().Name + ".dll");
return module;
}
}
// TODO: does this need to be a SingleCreationValueCache or similar?
private static readonly Dictionary<Type, Dictionary<Type, FieldInfo>> TypeRequiredConverters = new Dictionary<Type, Dictionary<Type, FieldInfo>>();
private static void CreateAndInitializeConvertersFor(Type type, IEnumerable<SerializedMemberInfo> structure)
{
if (!TypeRequiredConverters.TryGetValue(type, out var converters))
{
var converterFieldType = Module.DefineType($"{type.FullName}<Converters>",
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.AnsiClass); // a static class
var uniqueConverterTypes = structure.Where(m => m.HasConverter).Select(m => m.Converter).Distinct().ToArray();
converters = new Dictionary<Type, FieldInfo>(uniqueConverterTypes.Length);
foreach (var convType in uniqueConverterTypes)
{
var field = converterFieldType.DefineField($"<converter>_{convType}", convType,
FieldAttributes.FamORAssem | FieldAttributes.InitOnly | FieldAttributes.Static);
converters.Add(convType, field);
}
var cctor = converterFieldType.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
{
var il = cctor.GetILGenerator();
foreach (var kvp in converters)
{
var typeCtor = kvp.Key.GetConstructor(Type.EmptyTypes);
il.Emit(OpCodes.Newobj, typeCtor);
il.Emit(OpCodes.Stsfld, kvp.Value);
}
il.Emit(OpCodes.Ret);
}
TypeRequiredConverters.Add(type, converters);
converterFieldType.CreateType();
}
foreach (var member in structure.Where(m => m.HasConverter))
member.ConverterField = converters[member.Converter];
}
}
}
=> generatedCreators.GetOrAdd(t, MakeCreator);
internal static GeneratedStoreCreator GetCreator(Type t)
=> GetCreatorAndGeneratedType(t).ctor;
internal static Type GetGeneratedType(Type t)
=> GetCreatorAndGeneratedType(t).type;
internal const string GeneratedAssemblyName = "IPA.Config.Generated";
private static AssemblyBuilder assembly = null;
private static AssemblyBuilder Assembly
{
get
{
if (assembly == null)
{
var name = new AssemblyName(GeneratedAssemblyName);
assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.RunAndSave);
}
return assembly;
}
}
internal static void DebugSaveAssembly(string file)
{
Assembly.Save(file);
}
private static ModuleBuilder module = null;
private static ModuleBuilder Module
{
get
{
if (module == null)
module = Assembly.DefineDynamicModule(Assembly.GetName().Name, Assembly.GetName().Name + ".dll");
return module;
}
}
// TODO: does this need to be a SingleCreationValueCache or similar?
private static readonly Dictionary<Type, Dictionary<Type, FieldInfo>> TypeRequiredConverters = new Dictionary<Type, Dictionary<Type, FieldInfo>>();
private static void CreateAndInitializeConvertersFor(Type type, IEnumerable<SerializedMemberInfo> structure)
{
if (!TypeRequiredConverters.TryGetValue(type, out var converters))
{
var converterFieldType = Module.DefineType($"{type.FullName}<Converters>",
TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract | TypeAttributes.AnsiClass); // a static class
var uniqueConverterTypes = structure.Where(m => m.HasConverter).Select(m => m.Converter).Distinct().ToArray();
converters = new Dictionary<Type, FieldInfo>(uniqueConverterTypes.Length);
foreach (var convType in uniqueConverterTypes)
{
var field = converterFieldType.DefineField($"<converter>_{convType}", convType,
FieldAttributes.FamORAssem | FieldAttributes.InitOnly | FieldAttributes.Static);
converters.Add(convType, field);
}
var cctor = converterFieldType.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
{
var il = cctor.GetILGenerator();
foreach (var kvp in converters)
{
var typeCtor = kvp.Key.GetConstructor(Type.EmptyTypes);
il.Emit(OpCodes.Newobj, typeCtor);
il.Emit(OpCodes.Stsfld, kvp.Value);
}
il.Emit(OpCodes.Ret);
}
TypeRequiredConverters.Add(type, converters);
converterFieldType.CreateType();
}
foreach (var member in structure.Where(m => m.HasConverter))
member.ConverterField = converters[member.Converter];
}
}
}

+ 1
- 1
IPA.Loader/Config/Stores/GeneratedStoreImpl/ObjectStructure.cs View File

@ -147,7 +147,7 @@ namespace IPA.Config.Stores
} }
if (prop.GetGetMethod(true)?.IsPrivate ?? true) if (prop.GetGetMethod(true)?.IsPrivate ?? true)
{ // we enter this block if the getter is inacessible or doesn't exist { // we enter this block if the getter is inacessible or doesn't exist
continue; // ignore props without getter
continue; // ignore props without getter
} }
var smi = new SerializedMemberInfo var smi = new SerializedMemberInfo


+ 1
- 1
docs/index.md View File

@ -5,7 +5,7 @@ uid: home
# ![BSIPA](images/banner_dark.svg) # ![BSIPA](images/banner_dark.svg)
[![Build status](https://ci.appveyor.com/api/projects/status/1ruhnnfeudrrd097?svg=true)](https://ci.appveyor.com/project/nike4613/beatsaber-ipa-reloaded-9smsb)
[![Build](https://github.com/bsmg/BeatSaber-IPA-Reloaded/workflows/Build/badge.svg)](https://ci.appveyor.com/project/nike4613/beatsaber-ipa-reloaded-9smsb)
BSIPA - The Unity mod injector for the new age (pending confirmation). BSIPA - The Unity mod injector for the new age (pending confirmation).


Loading…
Cancel
Save