|
|
@@ -1,8 +1,12 @@ |
|
|
|
using System; |
|
|
|
using System.Reflection; |
|
|
|
using HarmonyLib; |
|
|
|
|
|
|
|
using RobocraftX.Services; |
|
|
|
using UnityEngine; |
|
|
|
|
|
|
|
using GamecraftModdingAPI.Utility; |
|
|
|
using RobocraftX.Common; |
|
|
|
|
|
|
|
namespace GamecraftModdingAPI.App |
|
|
|
{ |
|
|
@@ -14,6 +18,12 @@ namespace GamecraftModdingAPI.App |
|
|
|
// extensible engine |
|
|
|
protected static AppEngine appEngine = new AppEngine(); |
|
|
|
|
|
|
|
protected static Func<object> ErrorHandlerInstanceGetter; |
|
|
|
|
|
|
|
protected static Action<object, Error> EnqueueError; |
|
|
|
|
|
|
|
protected static Action<object> HandleErrorClosed; |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// An event that fires whenever the main menu is loaded. |
|
|
|
/// </summary> |
|
|
@@ -74,9 +84,76 @@ namespace GamecraftModdingAPI.App |
|
|
|
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() |
|
|
|
{ |
|
|
|
// 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); |
|
|
|
} |
|
|
|
|
|
|
|
// 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; |
|
|
|
} |
|
|
|
} |
|
|
|
} |