Add popup UI method to Client
This commit is contained in:
parent
926d968eed
commit
ea8a9184bc
3 changed files with 163 additions and 0 deletions
|
@ -1,8 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
using RobocraftX.Services;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
using GamecraftModdingAPI.Utility;
|
using GamecraftModdingAPI.Utility;
|
||||||
|
using RobocraftX.Common;
|
||||||
|
|
||||||
namespace GamecraftModdingAPI.App
|
namespace GamecraftModdingAPI.App
|
||||||
{
|
{
|
||||||
|
@ -14,6 +18,12 @@ namespace GamecraftModdingAPI.App
|
||||||
// extensible engine
|
// extensible engine
|
||||||
protected static AppEngine appEngine = new AppEngine();
|
protected static AppEngine appEngine = new AppEngine();
|
||||||
|
|
||||||
|
protected static Func<object> ErrorHandlerInstanceGetter;
|
||||||
|
|
||||||
|
protected static Action<object, Error> EnqueueError;
|
||||||
|
|
||||||
|
protected static Action<object> HandleErrorClosed;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An event that fires whenever the main menu is loaded.
|
/// An event that fires whenever the main menu is loaded.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -74,9 +84,76 @@ namespace GamecraftModdingAPI.App
|
||||||
get => appEngine.IsInMenu;
|
get => appEngine.IsInMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Open a popup which prompts the user to click a button.
|
||||||
|
/// This reuses Gamecraft's error dialog popup
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="popup">The popup to display. Use an instance of SingleChoicePrompt or DualChoicePrompt.</param>
|
||||||
|
public void PromptUser(Error popup)
|
||||||
|
{
|
||||||
|
// if the stuff wasn't mostly set to internal, this would be written as:
|
||||||
|
// RobocraftX.Services.ErrorHandler.Instance.EqueueError(error);
|
||||||
|
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
||||||
|
EnqueueError(errorHandlerInstance, popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/*public void CloseCurrentPrompt()
|
||||||
|
{
|
||||||
|
// RobocraftX.Services.ErrorHandler.Instance.HandlePopupClosed();
|
||||||
|
// FIXME: this is a call that is also called when closing, not the actual closing action itself (so it doesn't work)
|
||||||
|
object errorHandlerInstance = ErrorHandlerInstanceGetter();
|
||||||
|
HandleErrorClosed(errorHandlerInstance);
|
||||||
|
}*/
|
||||||
|
|
||||||
internal static void Init()
|
internal static void Init()
|
||||||
{
|
{
|
||||||
|
// this would have been so much simpler if this didn't involve a bunch of internal fields & classes
|
||||||
|
Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler");
|
||||||
|
Type errorHandle = AccessTools.TypeByName("RobocraftX.Services.ErrorHandle");
|
||||||
|
ErrorHandlerInstanceGetter = (Func<object>) AccessTools.Method("GamecraftModdingAPI.App.Client:GenInstanceGetter")
|
||||||
|
.MakeGenericMethod(errorHandler)
|
||||||
|
.Invoke(null, new object[0]);
|
||||||
|
EnqueueError = (Action<object, Error>) AccessTools.Method("GamecraftModdingAPI.App.Client:GenEnqueueError")
|
||||||
|
.MakeGenericMethod(errorHandler, errorHandle)
|
||||||
|
.Invoke(null, new object[0]);
|
||||||
|
/*HandleErrorClosed = (Action<object>) AccessTools.Method("GamecraftModdingAPI.App.Client:GenHandlePopupClosed")
|
||||||
|
.MakeGenericMethod(errorHandler)
|
||||||
|
.Invoke(null, new object[0]);*/
|
||||||
|
// register engines
|
||||||
MenuEngineManager.AddMenuEngine(appEngine);
|
MenuEngineManager.AddMenuEngine(appEngine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creating delegates once is faster than reflection every time
|
||||||
|
// Admittedly, this way is more difficult to code and less readable
|
||||||
|
private static Func<object> GenInstanceGetter<T>()
|
||||||
|
{
|
||||||
|
Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler");
|
||||||
|
MethodInfo instance = AccessTools.PropertyGetter(errorHandler, "Instance");
|
||||||
|
Func<T> getterSimple = (Func<T>) Delegate.CreateDelegate(typeof(Func<T>), null, instance);
|
||||||
|
Func<object> getterCasted = () => (object) getterSimple();
|
||||||
|
return getterCasted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Action<object, Error> GenEnqueueError<T, TRes>()
|
||||||
|
{
|
||||||
|
Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler");
|
||||||
|
MethodInfo enqueueError = AccessTools.Method(errorHandler, "EnqueueError");
|
||||||
|
Func<T, Error, TRes> enqueueSimple =
|
||||||
|
(Func<T, Error, TRes>) Delegate.CreateDelegate(typeof(Func<T, Error, TRes>), enqueueError);
|
||||||
|
Action<object, Error> enqueueCasted =
|
||||||
|
(object instance, Error error) => { enqueueSimple((T) instance, error); };
|
||||||
|
return enqueueCasted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Action<object> GenHandlePopupClosed<T>()
|
||||||
|
{
|
||||||
|
Type errorHandler = AccessTools.TypeByName("RobocraftX.Services.ErrorHandler");
|
||||||
|
MethodInfo handlePopupClosed = AccessTools.Method(errorHandler, "HandlePopupClosed");
|
||||||
|
Action<T> handleSimple =
|
||||||
|
(Action<T>) Delegate.CreateDelegate(typeof(Action<T>), handlePopupClosed);
|
||||||
|
Action<object> handleCasted = (object instance) => handleSimple((T) instance);
|
||||||
|
return handleCasted;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
GamecraftModdingAPI/App/ClientAlertTest.cs
Normal file
59
GamecraftModdingAPI/App/ClientAlertTest.cs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
using RobocraftX.Services;
|
||||||
|
|
||||||
|
using GamecraftModdingAPI.Tests;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.App
|
||||||
|
{
|
||||||
|
#if TEST
|
||||||
|
/// <summary>
|
||||||
|
/// Client popups tests.
|
||||||
|
/// Only available in TEST builds.
|
||||||
|
/// </summary>
|
||||||
|
[APITestClass]
|
||||||
|
public static class ClientAlertTest
|
||||||
|
{
|
||||||
|
private static DualChoicePrompt popup2 = null;
|
||||||
|
|
||||||
|
private static SingleChoicePrompt popup1 = null;
|
||||||
|
|
||||||
|
[APITestStartUp]
|
||||||
|
public static void StartUp2()
|
||||||
|
{
|
||||||
|
popup2 = new DualChoicePrompt("This is a test double-button popup",
|
||||||
|
"The cake is a lie",
|
||||||
|
"lmao",
|
||||||
|
() => { },
|
||||||
|
"kek",
|
||||||
|
() => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
[APITestStartUp]
|
||||||
|
public static void StartUp1()
|
||||||
|
{
|
||||||
|
popup1 = new SingleChoicePrompt("The cake is a lie",
|
||||||
|
"This is a test single-button popup",
|
||||||
|
"qwertyuiop",
|
||||||
|
() => { });
|
||||||
|
}
|
||||||
|
|
||||||
|
[APITestCase(TestType.Menu)]
|
||||||
|
public static void TestPopUp2()
|
||||||
|
{
|
||||||
|
Client c = new Client();
|
||||||
|
c.PromptUser(popup2);
|
||||||
|
//c.CloseCurrentPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
[APITestCase(TestType.Menu)]
|
||||||
|
public static void TestPopUp1()
|
||||||
|
{
|
||||||
|
Client c = new Client();
|
||||||
|
c.PromptUser(popup1);
|
||||||
|
//c.CloseCurrentPrompt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
27
GamecraftModdingAPI/App/UserPrompts.cs
Normal file
27
GamecraftModdingAPI/App/UserPrompts.cs
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
using System;
|
||||||
|
using HarmonyLib;
|
||||||
|
|
||||||
|
using RobocraftX.Services;
|
||||||
|
|
||||||
|
namespace GamecraftModdingAPI.App
|
||||||
|
{
|
||||||
|
public class DualChoicePrompt : MultiChoiceError
|
||||||
|
{
|
||||||
|
public DualChoicePrompt(string errorMessage, string title, string firstButtonText, Action firstButtonAction, string secondButtonText, Action secondButtonAction) : base(errorMessage, firstButtonText, firstButtonAction, secondButtonText, secondButtonAction)
|
||||||
|
{
|
||||||
|
// internal readonly field smh
|
||||||
|
new Traverse(this).Field<string>("Title").Value = title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SingleChoicePrompt : SingleChoiceError
|
||||||
|
{
|
||||||
|
public SingleChoicePrompt(string errorMessage, string buttonText, Action buttonClickAction) : base(errorMessage, buttonText, buttonClickAction)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleChoicePrompt(string titleText, string errorMessage, string buttonText, Action buttonClickAction) : base(titleText, errorMessage, buttonText, buttonClickAction)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue