Skip to content

Commit

Permalink
Fix support for Unity 2022.1 or earlier
Browse files Browse the repository at this point in the history
  • Loading branch information
nowsprinting committed Jun 11, 2023
1 parent db1758c commit 759b262
Show file tree
Hide file tree
Showing 23 changed files with 651 additions and 21 deletions.
6 changes: 6 additions & 0 deletions Runtime/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// Copyright (c) 2023 Koji Hasegawa.
// This software is released under the MIT License.

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("TestHelper.Tests")]
3 changes: 3 additions & 0 deletions Runtime/AssemblyInfo.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 33 additions & 21 deletions Runtime/Attributes/GameViewResolutionAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
// This software is released under the MIT License.

using System;
using System.Reflection;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
using NUnit.Framework.Internal;
using UnityEngine;
#if UNITY_EDITOR
using TestHelper.Wrappers.UnityEditor;
using UnityEditor;
#endif

Expand All @@ -19,9 +19,6 @@ namespace TestHelper.Attributes
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method)]
public class GameViewResolutionAttribute : NUnitAttribute, IApplyToContext
{
private static Type s_gameView;
private static MethodInfo s_setCustomResolution;

private readonly uint _width;
private readonly uint _height;
private readonly string _name;
Expand Down Expand Up @@ -59,27 +56,42 @@ private void SetResolutionUsingPlayModeWindow()
private void SetResolution()
{
#if UNITY_EDITOR
if (s_setCustomResolution == null)
var gameViewSizes = GameViewSizesWrapper.CreateInstance();
if (gameViewSizes == null)
{
Debug.LogError("GameViewSizes instance creation failed.");
return;
}

var gameViewSizeGroup = gameViewSizes.CurrentGroup();
if (gameViewSizeGroup == null)
{
Debug.LogError("GameViewSizeGroup instance creation failed.");
return;
}

var gameViewSize = GameViewSizeWrapper.CreateInstance((int)_width, (int)_height, _name);
if (gameViewSize == null)
{
Debug.LogError("GameViewSize instance creation failed.");
return;
}

var index = gameViewSizeGroup.IndexOf(gameViewSize);
if (index == -1)
{
var assembly = Assembly.Load("UnityEditor.dll");
s_gameView = assembly.GetType("UnityEditor.GameView");
if (s_gameView == null)
{
Debug.LogError("GameView type not found.");
return;
}
gameViewSizeGroup.AddCustomSize(gameViewSize);
index = gameViewSizeGroup.IndexOf(gameViewSize);
}

s_setCustomResolution =
s_gameView.GetMethod("SetCustomResolution", BindingFlags.Instance | BindingFlags.NonPublic);
if (s_setCustomResolution == null)
{
Debug.LogError("SetCustomResolution method not found.");
return;
}
var gameView = GameViewWrapper.GetWindow();
if (gameView == null)
{
Debug.LogError("GameView instance creation failed.");
return;
}

var gameView = EditorWindow.GetWindow(s_gameView, false, null, true);
s_setCustomResolution.Invoke(gameView, new object[] { new Vector2(_width, _height), _name });
gameView.SelectedSizeIndex(index);
#endif
}
}
Expand Down
3 changes: 3 additions & 0 deletions Runtime/Wrappers.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Runtime/Wrappers/UnityEditor.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 106 additions & 0 deletions Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// Copyright (c) 2023 Koji Hasegawa.
// This software is released under the MIT License.

#if UNITY_EDITOR
using System;
using System.Reflection;
using UnityEngine;

namespace TestHelper.Wrappers.UnityEditor
{
/// <summary>
/// Wrapper for <c>UnityEditor.GameViewSizeGroup</c>.
/// </summary>
public class GameViewSizeGroupWrapper
{
private static readonly Assembly s_editorAssembly = Assembly.Load("UnityEditor.dll");
private static readonly Type s_gameViewSizeGroup = s_editorAssembly.GetType("UnityEditor.GameViewSizeGroup");
private static readonly MethodInfo s_getTotalCount = s_gameViewSizeGroup.GetMethod("GetTotalCount");
private static readonly MethodInfo s_getGameViewSize = s_gameViewSizeGroup.GetMethod("GetGameViewSize");
private static readonly MethodInfo s_addCustomSize = s_gameViewSizeGroup.GetMethod("AddCustomSize");
private static readonly MethodInfo s_removeCustomSize = s_gameViewSizeGroup.GetMethod("RemoveCustomSize");

private readonly object _instance;

private GameViewSizeGroupWrapper(object gameViewSizeGroup)
{
_instance = gameViewSizeGroup;
}

public static GameViewSizeGroupWrapper CreateInstance(object gameViewSizeGroup)
{
if (s_gameViewSizeGroup == null)
{
Debug.LogError("GameViewSizeGroup type not found.");
return null;
// Note: Do not use Exception (and Assert). Because freezes async tests on UTF v1.3.4, See UUM-25085.
}

if (s_getTotalCount == null)
{
Debug.LogError("GetTotalCount method not found.");
return null;
}

if (s_getGameViewSize == null)
{
Debug.LogError("GetGameViewSize method not found.");
return null;
}

if (s_addCustomSize == null)
{
Debug.LogError("AddCustomSize method not found.");
return null;
}

if (s_removeCustomSize == null)
{
Debug.LogError("RemoveCustomSize method not found.");
return null;
}

return new GameViewSizeGroupWrapper(gameViewSizeGroup);
}

public int GetTotalCount()
{
var res = s_getTotalCount.Invoke(_instance, null);
return (int)res;
}

public GameViewSizeWrapper GetGameViewSize(int index)
{
var res = s_getGameViewSize.Invoke(_instance, new object[] { index });
return new GameViewSizeWrapper(res);
}

public void AddCustomSize(GameViewSizeWrapper size)
{
s_addCustomSize.Invoke(_instance, new object[] { size.GetInnerInstance() });
}

public void RemoveCustomSize(int index)
{
s_removeCustomSize.Invoke(_instance, new object[] { index });
}

/// <summary>
/// Found same type, width, and height.
/// </summary>
public int IndexOf(GameViewSizeWrapper size)
{
for (var i = 0; i < GetTotalCount(); i++)
{
var gameViewSize = GetGameViewSize(i);
if (gameViewSize.Equals(size))
{
return i;
}
}

return -1;
}
}
}
#endif
3 changes: 3 additions & 0 deletions Runtime/Wrappers/UnityEditor/GameViewSizeGroupWrapper.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

141 changes: 141 additions & 0 deletions Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// Copyright (c) 2023 Koji Hasegawa.
// This software is released under the MIT License.

#if UNITY_EDITOR
using System;
using System.Reflection;
using UnityEngine;

namespace TestHelper.Wrappers.UnityEditor
{
/// <summary>
/// Wrapper for <c>UnityEditor.GameViewSize</c>.
/// </summary>
public class GameViewSizeWrapper
{
private static readonly Assembly s_editorAssembly = Assembly.Load("UnityEditor.dll");

private static readonly Type s_gameViewSize = s_editorAssembly.GetType("UnityEditor.GameViewSize");

private static readonly FieldInfo s_gameViewSizeGameViewSizeType =
s_gameViewSize.GetField("m_SizeType", BindingFlags.NonPublic | BindingFlags.Instance);

private static readonly FieldInfo s_gameViewSizeWidth =
s_gameViewSize.GetField("m_Width", BindingFlags.NonPublic | BindingFlags.Instance);

private static readonly FieldInfo s_gameViewSizeHeight =
s_gameViewSize.GetField("m_Height", BindingFlags.NonPublic | BindingFlags.Instance);

private static readonly Type s_gameViewSizeType = s_editorAssembly.GetType("UnityEditor.GameViewSizeType");
private static readonly object s_typeFixedResolution = Enum.Parse(s_gameViewSizeType, "FixedResolution");

private static readonly ConstructorInfo s_gameViewSizeConstructor = s_gameViewSize.GetConstructor(new[]
{
s_gameViewSizeType, typeof(int), typeof(int), typeof(string)
});

private readonly object _instance;
private readonly int _width;
private readonly int _height;

internal GameViewSizeWrapper(object instance)
{
_instance = instance;
if (_instance == null)
{
return;
}

_width = (int)s_gameViewSizeWidth.GetValue(_instance);
_height = (int)s_gameViewSizeHeight.GetValue(_instance);
}

internal object GetInnerInstance()
{
return _instance;
}

public static GameViewSizeWrapper CreateInstance(int width, int height, string baseText)
{
if (s_gameViewSize == null)
{
Debug.LogError("GameViewSize type not found.");
return null;
// Note: Do not use Exception (and Assert). Because freezes async tests on UTF v1.3.4, See UUM-25085.
}

if (s_gameViewSizeGameViewSizeType == null)
{
Debug.LogError("GameViewSize.m_SizeType field not found.");
return null;
}

if (s_gameViewSizeWidth == null)
{
Debug.LogError("GameViewSize.m_Width field not found.");
return null;
}

if (s_gameViewSizeHeight == null)
{
Debug.LogError("GameViewSize.m_Height field not found.");
return null;
}

if (s_typeFixedResolution == null)
{
Debug.LogError("GameViewSizeType.FixedResolution not found.");
return null;
}

if (s_gameViewSizeConstructor == null)
{
Debug.LogError("GameViewSize constructor not found.");
return null;
}

var instance = s_gameViewSizeConstructor.Invoke(new[] { s_typeFixedResolution, width, height, baseText });
if (instance == null)
{
Debug.LogError("GameViewSize instance creation failed.");
return null;
}

return new GameViewSizeWrapper(instance);
}

public string DisplayText()
{
var displayTextProperty = s_gameViewSize.GetProperty("displayText");
if (displayTextProperty == null)
{
throw new NullReferenceException("GameViewSize.displayText property not found.");
}

var displayText = displayTextProperty.GetValue(_instance);
return displayText as string;
}

/// <summary>
/// Same type, width, and height.
/// </summary>
public bool Equals(GameViewSizeWrapper other)
{
if (other?.GetInnerInstance() == null)
{
return false;
}

var otherType = s_gameViewSizeGameViewSizeType.GetValue(other.GetInnerInstance());
if (!otherType.Equals(s_typeFixedResolution))
{
return false;
}

var otherWidth = (int)s_gameViewSizeWidth.GetValue(other.GetInnerInstance());
var otherHeight = (int)s_gameViewSizeHeight.GetValue(other.GetInnerInstance());
return otherWidth == _width && otherHeight == _height;
}
}
}
#endif
3 changes: 3 additions & 0 deletions Runtime/Wrappers/UnityEditor/GameViewSizeWrapper.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 759b262

Please sign in to comment.