1
0
mirror of synced 2025-01-31 03:53:44 +01:00

impr: Added support for returning results from scripts

This commit is contained in:
WerWolv 2024-05-18 12:57:29 +02:00
parent 1d6676f059
commit 6b6a6ae5f0
6 changed files with 60 additions and 27 deletions

View File

@ -275,8 +275,7 @@ namespace ImGuiExt {
if (m_textureId == nullptr)
return;
auto glTextureId = static_cast<GLuint>(reinterpret_cast<intptr_t>(m_textureId));
glDeleteTextures(1, &glTextureId);
glDeleteTextures(1, reinterpret_cast<GLuint*>(&m_textureId));
}
int UpdateStringSizeCallback(ImGuiInputTextCallbackData *data) {

View File

@ -39,6 +39,7 @@ add_imhex_plugin(
LIBRARIES
c_api
fonts
ui
)

View File

@ -23,6 +23,7 @@
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/utils.hpp>
#include <toasts/toast_notification.hpp>
extern "C" void igSetCurrentContext(ImGuiContext* ctx);
@ -236,17 +237,26 @@ namespace hex::script::loader {
const bool hasMain = m_methodExists("Main", scriptPath);
const bool hasOnLoad = m_methodExists("OnLoad", scriptPath);
const auto scriptName = entry.path().stem().string();
if (hasMain) {
this->addScript(entry.path().stem().string(), false, [this, scriptPath] {
hex::unused(m_runMethod("Main", false, scriptPath));
this->addScript(scriptName, false, [this, scriptPath] {
auto result = m_runMethod("Main", false, scriptPath);
if (result != 0) {
ui::ToastError::open(hex::format("Script '{}' running failed with code {}", result));
}
});
} else if (hasOnLoad) {
this->addScript(entry.path().stem().string(), true, [] {});
this->addScript(scriptName, true, [] {});
}
if (hasOnLoad) {
hex::unused(m_runMethod("OnLoad", true, scriptPath));
auto result = m_runMethod("OnLoad", true, scriptPath);
if (result != 0) {
TaskManager::doLater([=] {
ui::ToastError::open(hex::format("Script '{}' loading failed with code {}", scriptName, result));
});
}
}
}

View File

@ -8,6 +8,12 @@ namespace ImHex
public class EntryPoint
{
private const int ResultSuccess = 0x0000_0000;
private const int ResultError = 0x1000_0001;
private const int ResultMethodNotFound = 0x1000_0002;
private const int ResultLoaderError = 0x1000_0003;
private const int ResultLoaderInvalidCommand = 0x1000_0004;
private static void Log(string message)
{
Console.WriteLine($"[.NET Script] {message}");
@ -21,7 +27,7 @@ namespace ImHex
catch (Exception e)
{
Log($"Exception in AssemblyLoader: {e}");
return 1;
return ResultLoaderError;
}
}
@ -35,17 +41,17 @@ namespace ImHex
var path = splitArgs[2];
// Get the parent folder of the passed path
string? basePath = Path.GetDirectoryName(path);
var basePath = Path.GetDirectoryName(path);
if (basePath == null)
{
Log("Failed to get base path");
return 1;
return ResultError;
}
// Create a new assembly context
AssemblyLoadContext? context = new("ScriptDomain_" + basePath, true);
int result = 0;
int result;
try
{
if (type is "LOAD")
@ -53,7 +59,7 @@ namespace ImHex
// If the script has been loaded already, don't do it again
if (LoadedPlugins.Contains(path))
{
return 0;
return ResultSuccess;
}
// Check if the plugin is already loaded
@ -87,7 +93,7 @@ namespace ImHex
if (libraryModule == null)
{
Log("Refusing to load non-ImHex script");
return 1;
return ResultError;
}
else
{
@ -96,7 +102,7 @@ namespace ImHex
if (libraryType == null)
{
Log("Failed to find Library type in ImHexLibrary");
return 1;
return ResultError;
}
// Load Initialize function in the Library type
@ -104,7 +110,7 @@ namespace ImHex
if (initMethod == null)
{
Log("Failed to find Initialize method");
return 1;
return ResultError;
}
// Execute it
@ -117,11 +123,11 @@ namespace ImHex
if (entryPointTypes.Length == 0)
{
Log("Failed to find Script entrypoint");
return 1;
return ResultError;
} else if (entryPointTypes.Length > 1)
{
Log("Found multiple Script entrypoints");
return 1;
return ResultError;
}
var entryPointType = entryPointTypes[0];
@ -132,11 +138,27 @@ namespace ImHex
var method = entryPointType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public);
if (method == null)
{
return 2;
return ResultMethodNotFound;
}
// Execute it
method.Invoke(null, null);
var returnValue = method.Invoke(null, null);
switch (returnValue)
{
case null:
result = ResultSuccess;
break;
case int intValue:
result = intValue;
break;
case uint intValue:
result = (int)intValue;
break;
default:
result = ResultError;
Log($"Invalid return value from script: {returnValue.GetType().Name} {{{returnValue}}}");
break;
}
}
else if (type == "CHECK")
{
@ -145,13 +167,13 @@ namespace ImHex
}
else
{
return 1;
return ResultLoaderInvalidCommand;
}
}
catch (Exception e)
{
Log($"Exception in AssemblyLoader: {e}");
return 3;
return ResultLoaderError;
}
finally
{

View File

@ -8,9 +8,6 @@ public static class Library
}
}
public interface IScript {
static void Main() { }
static void OnLoad() { }
public interface IScript
{
}

View File

@ -3,14 +3,18 @@ using ImGuiNET;
class Script : IScript {
public static void OnLoad()
public static int OnLoad()
{
// This function is executed the first time the Plugin is loaded
return 1;
}
public static void Main()
public static int Main()
{
// This function is executed when the plugin is selected in the "Run Script..." menu
return 1;
}
}