Browse Source

Switched EnumerableExtensions Prepend and Append to use custom enumerators

4.0.0-beta
Anairkoen Schno 4 years ago
parent
commit
cdd0b219b0
4 changed files with 94 additions and 9 deletions
  1. +0
    -1
      IPA.Loader/Loader/PluginExecutor.cs
  2. +94
    -8
      IPA.Loader/Utilities/EnumerableExtensions.cs
  3. BIN
      Refs/MainAssembly.dll
  4. BIN
      Refs/Unity.TextMeshPro.dll

+ 0
- 1
IPA.Loader/Loader/PluginExecutor.cs View File

@ -96,7 +96,6 @@ namespace IPA.Loader
throw new InvalidOperationException($"Method {method} on {type.FullName} has both an [Init] attribute and a lifecycle attribute."); throw new InvalidOperationException($"Method {method} on {type.FullName} has both an [Init] attribute and a lifecycle attribute.");
} }
// TODO: how do I make this work for .NET 3? FEC.LightExpression but hacked to work on .NET 3?
var metaParam = Expression.Parameter(typeof(PluginMetadata), "meta"); var metaParam = Expression.Parameter(typeof(PluginMetadata), "meta");
var objVar = ExpressionEx.Variable(type, "objVar"); var objVar = ExpressionEx.Variable(type, "objVar");
var persistVar = ExpressionEx.Variable(typeof(object), "persistVar"); var persistVar = ExpressionEx.Variable(typeof(object), "persistVar");


+ 94
- 8
IPA.Loader/Utilities/EnumerableExtensions.cs View File

@ -33,10 +33,53 @@ namespace IPA.Utilities
this.first = first; this.first = first;
} }
public IEnumerator<T> GetEnumerator()
{ // TODO: a custom impl that is less garbage
yield return first;
foreach (var v in rest) yield return v;
public IEnumerator<T> GetEnumerator() => new PrependEnumerator(this);
private sealed class PrependEnumerator : IEnumerator<T>
{
private readonly IEnumerator<T> restEnum;
private readonly PrependEnumerable<T> enumerable;
private int state = 0;
public PrependEnumerator(PrependEnumerable<T> enumerable)
{
this.enumerable = enumerable;
restEnum = enumerable.rest.GetEnumerator();
}
public T Current { get; private set; }
object IEnumerator.Current => Current;
public void Dispose() => restEnum.Dispose();
public bool MoveNext()
{
switch (state)
{
case 0:
Current = enumerable.first;
state++;
return true;
case 1:
if (!restEnum.MoveNext())
{
state = 2;
return false;
}
else
Current = restEnum.Current;
return true;
case 2:
default:
return false;
}
}
public void Reset()
{
restEnum.Reset();
state = 0;
}
} }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
@ -63,10 +106,53 @@ namespace IPA.Utilities
this.last = last; this.last = last;
} }
public IEnumerator<T> GetEnumerator()
{ // TODO: a custom impl that is less garbage
foreach (var v in rest) yield return v;
yield return last;
public IEnumerator<T> GetEnumerator() => new AppendEnumerator(this);
private sealed class AppendEnumerator : IEnumerator<T>
{
private readonly IEnumerator<T> restEnum;
private readonly AppendEnumerable<T> enumerable;
private int state = 0;
public AppendEnumerator(AppendEnumerable<T> enumerable)
{
this.enumerable = enumerable;
restEnum = enumerable.rest.GetEnumerator();
}
public T Current { get; private set; }
object IEnumerator.Current => Current;
public void Dispose() => restEnum.Dispose();
public bool MoveNext()
{
switch (state)
{
case 0:
if (!restEnum.MoveNext())
{
state = 1;
goto case 1;
}
else
Current = restEnum.Current;
return true;
case 1:
Current = enumerable.last;
state++;
return true;
case 2:
default:
return false;
}
}
public void Reset()
{
restEnum.Reset();
state = 0;
}
} }
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();


BIN
Refs/MainAssembly.dll View File


BIN
Refs/Unity.TextMeshPro.dll View File


Loading…
Cancel
Save