Skip to content

Commit

Permalink
.NET: Simplify callback system a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
praydog committed Apr 1, 2024
1 parent c525f06 commit a2994f5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 33 deletions.
5 changes: 5 additions & 0 deletions csharp-api/REFrameworkNET/API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ REFrameworkNET::API::API(uintptr_t param)

void REFrameworkNET::API::Init_Internal(const REFrameworkPluginInitializeParam* param)
{
if (s_api != nullptr) {
Console::WriteLine("REFrameworkNET.API Init_Internal called but API is already initialized.");
return;
}

Console::WriteLine("REFrameworkNET.API Init_Internal called.");
s_api = reframework::API::initialize(param).get();
Callbacks::Impl::Setup(this);
Expand Down
31 changes: 23 additions & 8 deletions csharp-api/REFrameworkNET/Callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,19 @@
#include "Callbacks.hpp"

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Collections::Generic;

namespace REFrameworkNET {
namespace Callbacks {
void Impl::Setup(REFrameworkNET::API^ api) {
if (s_setup) {
Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks called but already setup.");
return;
}

s_setup = true;

Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks called.");

reframework::API* nativeApi = api->GetNativeImplementation();
Expand All @@ -23,20 +32,26 @@ void Impl::Setup(REFrameworkNET::API^ api) {
continue;
}

if (type->GetField("FUNCTION_PRE_CALLBACK_ADDRESS") == nullptr) {
continue;
}
const auto wantedFlags = System::Reflection::BindingFlags::NonPublic | System::Reflection::BindingFlags::Static;

if (type->GetField("FUNCTION_POST_CALLBACK_ADDRESS") == nullptr) {
if (type->GetField("TriggerPostDelegate", wantedFlags) == nullptr || type->GetField("TriggerPreDelegate", wantedFlags) == nullptr) {
continue;
}

auto eventName = type->Name;
auto eventNameStr = msclr::interop::marshal_as<std::string>(eventName);
auto eventHandlerPre = (uintptr_t)type->GetField("FUNCTION_PRE_CALLBACK_ADDRESS")->GetValue(nullptr);
auto eventHandlerPost = (uintptr_t)type->GetField("FUNCTION_POST_CALLBACK_ADDRESS")->GetValue(nullptr);
nativeApi->param()->functions->on_pre_application_entry(eventNameStr.c_str(), (REFOnPreApplicationEntryCb)eventHandlerPre);
nativeApi->param()->functions->on_post_application_entry(eventNameStr.c_str(), (REFOnPostApplicationEntryCb)eventHandlerPost);
auto triggerPost = type->GetField("TriggerPostDelegate", wantedFlags)->GetValue(nullptr);
auto triggerPre = type->GetField("TriggerPreDelegate", wantedFlags)->GetValue(nullptr);

if (triggerPre == nullptr || triggerPost == nullptr) {
System::Console::WriteLine("REFrameworkNET.Callbacks SetupCallbacks: TriggerPreDelegate or TriggerPostDelegate is null for " + eventName);
continue;
}

IntPtr preHookPtr = Marshal::GetFunctionPointerForDelegate(triggerPre);
IntPtr postHookPtr = Marshal::GetFunctionPointerForDelegate(triggerPost);
nativeApi->param()->functions->on_pre_application_entry(eventNameStr.c_str(), (REFOnPreApplicationEntryCb)preHookPtr.ToPointer());
nativeApi->param()->functions->on_post_application_entry(eventNameStr.c_str(), (REFOnPostApplicationEntryCb)postHookPtr.ToPointer());
}
}
}
Expand Down
38 changes: 13 additions & 25 deletions csharp-api/REFrameworkNET/Callbacks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,26 @@ using namespace System::Collections::Generic;
namespace REFrameworkNET {
ref class API;

public ref class BaseCallback {
public:
delegate void Delegate();
};

#define GENERATE_POCKET_CLASS(EVENT_NAME) \
static void EVENT_NAME##PreHandler_Internal(); \
static void EVENT_NAME##PostHandler_Internal(); \
public ref class EVENT_NAME { \
public: \
delegate void Delegate(); \
static event Delegate^ Pre; \
static event Delegate^ Post; \
static event BaseCallback::Delegate^ Pre; \
static event BaseCallback::Delegate^ Post; \
internal: \
static void TriggerPre() { \
Pre(); \
} \
static void TriggerPost() { \
Post(); \
} \
static System::Reflection::MethodInfo^ TriggerPreMethod = nullptr;\
static System::Reflection::MethodInfo^ TriggerPostMethod = nullptr;\
static uintptr_t FUNCTION_PRE_CALLBACK_ADDRESS = (uintptr_t)&EVENT_NAME##PreHandler_Internal; \
static uintptr_t FUNCTION_POST_CALLBACK_ADDRESS = (uintptr_t)&EVENT_NAME##PostHandler_Internal; \
static BaseCallback::Delegate^ TriggerPreDelegate = gcnew BaseCallback::Delegate(&EVENT_NAME::TriggerPre); \
static BaseCallback::Delegate^ TriggerPostDelegate = gcnew BaseCallback::Delegate(&EVENT_NAME::TriggerPost); \
}; \
void EVENT_NAME##PreHandler_Internal() { \
if (Callbacks::##EVENT_NAME::TriggerPreMethod == nullptr) { \
auto self = System::Reflection::Assembly::LoadFrom(System::Reflection::Assembly::GetExecutingAssembly()->Location); \
auto type = self->GetType("REFrameworkNET.Callbacks." #EVENT_NAME); \
Callbacks::##EVENT_NAME::TriggerPreMethod = type->GetMethod("TriggerPre", System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public); \
} \
Callbacks::##EVENT_NAME::TriggerPreMethod->Invoke(nullptr, nullptr); \
} \
void EVENT_NAME##PostHandler_Internal() { \
if (Callbacks::##EVENT_NAME::TriggerPostMethod == nullptr) { \
auto self = System::Reflection::Assembly::LoadFrom(System::Reflection::Assembly::GetExecutingAssembly()->Location); \
auto type = self->GetType("REFrameworkNET.Callbacks." #EVENT_NAME); \
Callbacks::##EVENT_NAME::TriggerPostMethod = type->GetMethod("TriggerPost", System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public); \
} \
Callbacks::##EVENT_NAME::TriggerPostMethod->Invoke(nullptr, nullptr); \
}

namespace Callbacks {
GENERATE_POCKET_CLASS(Initialize)
Expand Down Expand Up @@ -425,6 +410,9 @@ namespace Callbacks {
public ref class Impl {
public:
static void Setup(REFrameworkNET::API^ api);

private:
static bool s_setup = false;
};
};
}

0 comments on commit a2994f5

Please sign in to comment.