Made all virtual base functions for the event handler scripted

This was by far the largest block of native virtuals, and they were only native to be able to allow checking if the event was implemented for the current handler. This can easily be done by looking at the byte code, just like VMCall also does but in turn it removes more than half of the existing native virtuals from the interface.
This commit is contained in:
Christoph Oelckers 2018-11-29 18:46:28 +01:00
parent 762a100d60
commit 3acd9c8116
2 changed files with 70 additions and 128 deletions

View file

@ -32,6 +32,7 @@
*/
#include "events.h"
#include "vm.h"
#include "vmintern.h"
#include "r_utility.h"
#include "g_levellocals.h"
#include "gi.h"
@ -665,48 +666,19 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, Find)
ACTION_RETURN_OBJECT(nullptr);
}
#define DEFINE_EMPTY_HANDLER(cls, funcname) DEFINE_ACTION_FUNCTION(cls, funcname) \
{ \
PARAM_SELF_PROLOGUE(cls); \
return 0; \
// Check if the handler implements a callback for this event. This is used to avoid setting up the data for any event that the handler won't process
static bool isEmpty(VMFunction *func)
{
auto code = static_cast<VMScriptFunction *>(func)->Code;
return (code == nullptr || code->word == (0x00808000|OP_RET));
}
DEFINE_EMPTY_HANDLER(DStaticEventHandler, OnRegister)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, OnUnregister)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLoaded)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldUnloaded)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingSpawned)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDied)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingRevived)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDamaged)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldThingDestroyed)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLinePreActivated)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLineActivated)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldSectorDamaged);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLineDamaged);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldLightning)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, WorldTick)
//DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderFrame)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, RenderOverlay)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerEntered)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerRespawned)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerDied)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PlayerDisconnected)
DEFINE_EMPTY_HANDLER(DStaticEventHandler, UiProcess);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, InputProcess);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, UiTick);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, PostUiTick);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, ConsoleProcess);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, NetworkProcess);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, CheckReplacement);
DEFINE_EMPTY_HANDLER(DStaticEventHandler, NewGame)
static bool isEmptyInt(VMFunction *func)
{
auto code = static_cast<VMScriptFunction *>(func)->Code;
return (code == nullptr || code->word == (0x00048000|OP_RET));
}
// ===========================================
//
@ -719,8 +691,7 @@ void DStaticEventHandler::OnRegister()
IFVIRTUAL(DStaticEventHandler, OnRegister)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_OnRegister_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}
@ -731,8 +702,7 @@ void DStaticEventHandler::OnUnregister()
IFVIRTUAL(DStaticEventHandler, OnUnregister)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_OnUnregister_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}
@ -752,8 +722,7 @@ void DStaticEventHandler::WorldLoaded()
IFVIRTUAL(DStaticEventHandler, WorldLoaded)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldLoaded_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -765,8 +734,7 @@ void DStaticEventHandler::WorldUnloaded()
IFVIRTUAL(DStaticEventHandler, WorldUnloaded)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldUnloaded_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -778,8 +746,7 @@ void DStaticEventHandler::WorldThingSpawned(AActor* actor)
IFVIRTUAL(DStaticEventHandler, WorldThingSpawned)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingSpawned_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
@ -792,8 +759,7 @@ void DStaticEventHandler::WorldThingDied(AActor* actor, AActor* inflictor)
IFVIRTUAL(DStaticEventHandler, WorldThingDied)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingDied_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
e.Inflictor = inflictor;
@ -807,8 +773,7 @@ void DStaticEventHandler::WorldThingRevived(AActor* actor)
IFVIRTUAL(DStaticEventHandler, WorldThingRevived)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingRevived_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
@ -821,8 +786,7 @@ void DStaticEventHandler::WorldThingDamaged(AActor* actor, AActor* inflictor, AA
IFVIRTUAL(DStaticEventHandler, WorldThingDamaged)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingDamaged_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
e.Inflictor = inflictor;
@ -841,8 +805,7 @@ void DStaticEventHandler::WorldThingDestroyed(AActor* actor)
IFVIRTUAL(DStaticEventHandler, WorldThingDestroyed)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldThingDestroyed_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
VMValue params[2] = { (DStaticEventHandler*)this, &e };
@ -855,8 +818,7 @@ void DStaticEventHandler::WorldLinePreActivated(line_t* line, AActor* actor, int
IFVIRTUAL(DStaticEventHandler, WorldLinePreActivated)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldLinePreActivated_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
e.ActivatedLine = line;
@ -873,8 +835,7 @@ void DStaticEventHandler::WorldLineActivated(line_t* line, AActor* actor, int ac
IFVIRTUAL(DStaticEventHandler, WorldLineActivated)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldLineActivated_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
e.Thing = actor;
e.ActivatedLine = line;
@ -889,8 +850,7 @@ int DStaticEventHandler::WorldSectorDamaged(sector_t* sector, AActor* source, in
IFVIRTUAL(DStaticEventHandler, WorldSectorDamaged)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldSectorDamaged_VMPtr)
return damage;
if (isEmpty(func)) return damage;
FWorldEvent e = E_SetupWorldEvent();
e.DamageSource = source;
e.DamageSector = sector;
@ -913,8 +873,7 @@ int DStaticEventHandler::WorldLineDamaged(line_t* line, AActor* source, int dama
IFVIRTUAL(DStaticEventHandler, WorldLineDamaged)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldLineDamaged_VMPtr)
return damage;
if (isEmpty(func)) return damage;
FWorldEvent e = E_SetupWorldEvent();
e.DamageSource = source;
e.DamageLine = line;
@ -937,8 +896,7 @@ void DStaticEventHandler::WorldLightning()
IFVIRTUAL(DStaticEventHandler, WorldLightning)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldLightning_VMPtr)
return;
if (isEmpty(func)) return;
FWorldEvent e = E_SetupWorldEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -950,8 +908,7 @@ void DStaticEventHandler::WorldTick()
IFVIRTUAL(DStaticEventHandler, WorldTick)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_WorldTick_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}
@ -976,8 +933,7 @@ void DStaticEventHandler::RenderFrame()
IFVIRTUAL(DStaticEventHandler, RenderFrame)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_RenderFrame_VMPtr)
return;
if (isEmpty(func)) return;
FRenderEvent e = E_SetupRenderEvent();
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -990,8 +946,7 @@ void DStaticEventHandler::RenderOverlay(EHudState state)
IFVIRTUAL(DStaticEventHandler, RenderOverlay)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_RenderOverlay_VMPtr)
return;
if (isEmpty(func)) return;
FRenderEvent e = E_SetupRenderEvent();
e.HudState = int(state);
VMValue params[2] = { (DStaticEventHandler*)this, &e };
@ -1004,8 +959,7 @@ void DStaticEventHandler::PlayerEntered(int num, bool fromhub)
IFVIRTUAL(DStaticEventHandler, PlayerEntered)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_PlayerEntered_VMPtr)
return;
if (isEmpty(func)) return;
FPlayerEvent e = { num, fromhub };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -1017,8 +971,7 @@ void DStaticEventHandler::PlayerRespawned(int num)
IFVIRTUAL(DStaticEventHandler, PlayerRespawned)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_PlayerRespawned_VMPtr)
return;
if (isEmpty(func)) return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -1030,8 +983,7 @@ void DStaticEventHandler::PlayerDied(int num)
IFVIRTUAL(DStaticEventHandler, PlayerDied)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_PlayerDied_VMPtr)
return;
if (isEmpty(func)) return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -1043,8 +995,7 @@ void DStaticEventHandler::PlayerDisconnected(int num)
IFVIRTUAL(DStaticEventHandler, PlayerDisconnected)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_PlayerDisconnected_VMPtr)
return;
if (isEmpty(func)) return;
FPlayerEvent e = { num, false };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -1096,8 +1047,7 @@ bool DStaticEventHandler::UiProcess(const event_t* ev)
IFVIRTUAL(DStaticEventHandler, UiProcess)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_UiProcess_VMPtr)
return false;
if (isEmptyInt(func)) return false;
FUiEvent e = ev;
int processed;
@ -1142,9 +1092,7 @@ bool DStaticEventHandler::InputProcess(const event_t* ev)
IFVIRTUAL(DStaticEventHandler, InputProcess)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_InputProcess_VMPtr)
return false;
if (isEmptyInt(func)) return false;
FInputEvent e = ev;
//
@ -1163,8 +1111,7 @@ void DStaticEventHandler::UiTick()
IFVIRTUAL(DStaticEventHandler, UiTick)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_UiTick_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}
@ -1175,8 +1122,7 @@ void DStaticEventHandler::PostUiTick()
IFVIRTUAL(DStaticEventHandler, PostUiTick)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_PostUiTick_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}
@ -1189,8 +1135,7 @@ void DStaticEventHandler::ConsoleProcess(int player, FString name, int arg1, int
IFVIRTUAL(DStaticEventHandler, ConsoleProcess)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_ConsoleProcess_VMPtr)
return;
if (isEmpty(func)) return;
FConsoleEvent e;
//
@ -1210,8 +1155,7 @@ void DStaticEventHandler::ConsoleProcess(int player, FString name, int arg1, int
IFVIRTUAL(DStaticEventHandler, NetworkProcess)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_NetworkProcess_VMPtr)
return;
if (isEmpty(func)) return;
FConsoleEvent e;
//
@ -1233,8 +1177,7 @@ void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor *
IFVIRTUAL(DStaticEventHandler, CheckReplacement)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_CheckReplacement_VMPtr)
return;
if (isEmpty(func)) return;
FReplaceEvent e = { replacee, *replacement, *final };
VMValue params[2] = { (DStaticEventHandler*)this, &e };
VMCall(func, params, 2, nullptr, 0);
@ -1249,8 +1192,7 @@ void DStaticEventHandler::NewGame()
IFVIRTUAL(DStaticEventHandler, NewGame)
{
// don't create excessive DObjects if not going to be processed anyway
if (func == DStaticEventHandler_NewGame_VMPtr)
return;
if (isEmpty(func)) return;
VMValue params[1] = { (DStaticEventHandler*)this };
VMCall(func, params, 1, nullptr, 0);
}

View file

@ -308,49 +308,49 @@ class StaticEventHandler : Object native play version("2.4")
// these are called when the handler gets registered or unregistered
// you can set Order/IsUiProcessor here.
virtual native void OnRegister();
virtual native void OnUnregister();
virtual void OnRegister() {}
virtual void OnUnregister() {}
// actual handlers are here
virtual native void WorldLoaded(WorldEvent e);
virtual native void WorldUnloaded(WorldEvent e);
virtual native void WorldThingSpawned(WorldEvent e);
virtual native void WorldThingDied(WorldEvent e);
virtual native void WorldThingRevived(WorldEvent e);
virtual native void WorldThingDamaged(WorldEvent e);
virtual native void WorldThingDestroyed(WorldEvent e);
virtual native void WorldLinePreActivated(WorldEvent e);
virtual native void WorldLineActivated(WorldEvent e);
virtual native void WorldSectorDamaged(WorldEvent e);
virtual native void WorldLineDamaged(WorldEvent e);
virtual native void WorldLightning(WorldEvent e); // for the sake of completeness.
virtual native void WorldTick();
virtual void WorldLoaded(WorldEvent e) {}
virtual void WorldUnloaded(WorldEvent e) {}
virtual void WorldThingSpawned(WorldEvent e) {}
virtual void WorldThingDied(WorldEvent e) {}
virtual void WorldThingRevived(WorldEvent e) {}
virtual void WorldThingDamaged(WorldEvent e) {}
virtual void WorldThingDestroyed(WorldEvent e) {}
virtual void WorldLinePreActivated(WorldEvent e) {}
virtual void WorldLineActivated(WorldEvent e) {}
virtual void WorldSectorDamaged(WorldEvent e) {}
virtual void WorldLineDamaged(WorldEvent e) {}
virtual void WorldLightning(WorldEvent e) {} // for the sake of completeness.
virtual void WorldTick() {}
//
//virtual native ui void RenderFrame(RenderEvent e);
virtual native ui void RenderOverlay(RenderEvent e);
//virtual ui void RenderFrame(RenderEvent e) {}
virtual ui void RenderOverlay(RenderEvent e) {}
//
virtual native void PlayerEntered(PlayerEvent e);
virtual native void PlayerRespawned(PlayerEvent e);
virtual native void PlayerDied(PlayerEvent e);
virtual native void PlayerDisconnected(PlayerEvent e);
virtual void PlayerEntered(PlayerEvent e) {}
virtual void PlayerRespawned(PlayerEvent e) {}
virtual void PlayerDied(PlayerEvent e) {}
virtual void PlayerDisconnected(PlayerEvent e) {}
//
virtual native ui bool UiProcess(UiEvent e);
virtual native ui bool InputProcess(InputEvent e);
virtual native ui void UiTick();
virtual native ui void PostUiTick();
virtual ui bool UiProcess(UiEvent e) { return false; }
virtual ui bool InputProcess(InputEvent e) { return false; }
virtual ui void UiTick() {}
virtual ui void PostUiTick() {}
//
virtual native ui void ConsoleProcess(ConsoleEvent e);
virtual native void NetworkProcess(ConsoleEvent e);
virtual ui void ConsoleProcess(ConsoleEvent e) {}
virtual void NetworkProcess(ConsoleEvent e) {}
//
virtual native void CheckReplacement(ReplaceEvent e);
virtual void CheckReplacement(ReplaceEvent e) {}
//
virtual native void NewGame();
virtual void NewGame() {}
// this value will be queried on Register() to decide the relative order of this handler to every other.
// this is most useful in UI systems.