- added scriptable virtual overrides for PostBeginPlay, Tick, BeginPlay, Activate and Deactivate.

This commit is contained in:
Christoph Oelckers 2016-11-21 14:59:17 +01:00
parent 7d99552903
commit 97763b5a2b
6 changed files with 162 additions and 16 deletions

View file

@ -258,6 +258,14 @@ void DThinker::PostBeginPlay ()
{
}
DEFINE_ACTION_FUNCTION(DThinker, PostBeginPlay)
{
PARAM_SELF_PROLOGUE(DThinker);
self->VMSuperCall();
self->PostBeginPlay();
return 0;
}
void DThinker::PostSerialize()
{
}
@ -421,6 +429,14 @@ void DThinker::Tick ()
{
}
DEFINE_ACTION_FUNCTION(DThinker, Tick)
{
PARAM_SELF_PROLOGUE(DThinker);
self->VMSuperCall();
self->Tick();
return 0;
}
size_t DThinker::PropagateMark()
{
// Do not choke on partially initialized objects (as happens when loading a savegame fails)

View file

@ -4112,6 +4112,15 @@ void AActor::Tick ()
}
}
DEFINE_ACTION_FUNCTION(AActor, Tick)
{
PARAM_SELF_PROLOGUE(AActor);
self->VMSuperCall();
self->Tick();
return 0;
}
//==========================================================================
//
// AActor :: CheckNoDelay
@ -4580,6 +4589,15 @@ void AActor::BeginPlay ()
}
}
DEFINE_ACTION_FUNCTION(AActor, BeginPlay)
{
PARAM_SELF_PROLOGUE(AActor);
self->VMSuperCall();
self->BeginPlay();
return 0;
}
void AActor::PostBeginPlay ()
{
if (Renderer != NULL)
@ -4635,6 +4653,15 @@ void AActor::Activate (AActor *activator)
}
}
DEFINE_ACTION_FUNCTION(AActor, Activate)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(activator, AActor);
self->VMSuperCall();
self->Activate(activator);
return 0;
}
void AActor::Deactivate (AActor *activator)
{
if ((flags3 & MF3_ISMONSTER) && (health > 0 || (flags & MF_ICECORPSE)))
@ -4655,6 +4682,15 @@ void AActor::Deactivate (AActor *activator)
}
}
DEFINE_ACTION_FUNCTION(AActor, Deactivate)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_OBJECT(activator, AActor);
self->VMSuperCall();
self->Deactivate(activator);
return 0;
}
//
// P_RemoveMobj

View file

@ -1280,22 +1280,18 @@ void APlayerPawn::PlayRunning ()
void APlayerPawn::PlayAttacking ()
{
static int VIndex = -1;
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(APlayerPawn), "PlayAttacking");
// Without the type cast this picks the 'void *' assignment...
VINDEX(APlayerPawn, PlayAttacking);
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
void APlayerPawn::PlayAttacking2 ()
{
static int VIndex = -1;
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(APlayerPawn), "PlayAttacking2");
// Without the type cast this picks the 'void *' assignment...
VINDEX(APlayerPawn, PlayAttacking2);
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
void APlayerPawn::ThrowPoisonBag ()

View file

@ -35,6 +35,9 @@ VMEXPORTED_NATIVES_START
VMEXPORTED_NATIVES_FUNC(Destroy)
VMEXPORTED_NATIVES_FUNC(Tick)
VMEXPORTED_NATIVES_FUNC(PostBeginPlay)
VMEXPORTED_NATIVES_FUNC(BeginPlay)
VMEXPORTED_NATIVES_FUNC(Activate)
VMEXPORTED_NATIVES_FUNC(Deactivate)
VMEXPORTED_NATIVES_END
@ -48,6 +51,15 @@ inline int GetVirtualIndex(PClass *cls, const char *funcname)
return VIndex;
}
#define VINDEX(cls, funcname) \
static int VIndex = -1; \
if (VIndex < 0) { \
VIndex = GetVirtualIndex(RUNTIME_CLASS(cls), #funcname); \
if (VIndex < 0) I_Error("Unable to find virtual function in " #cls, #funcname); \
}
#define VFUNC this->GetClass()->Virtuals[VIndex]
template<class T>
class DVMObject : public T
{
@ -84,28 +96,103 @@ public:
{
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= OF_SuperCall;
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template Destroy<void, T>(this);
}
else
{
static int VIndex = -1;
if (VIndex < 0) VIndex = GetVirtualIndex(RUNTIME_CLASS(DObject), "Destroy");
VINDEX(DObject, Destroy);
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(this->GetClass()->Virtuals[VIndex], params, 1, nullptr, 0, nullptr);
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
}
void Tick()
{
ExportedNatives<T>::Get()->template Tick<void, T>(this);
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template Tick<void, T>(this);
}
else
{
VINDEX(DThinker, Tick);
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
}
void PostBeginPlay()
{
ExportedNatives<T>::Get()->template PostBeginPlay<void, T>(this);
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template PostBeginPlay<void, T>(this);
}
else
{
VINDEX(DThinker, PostBeginPlay);
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
}
void BeginPlay()
{
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template BeginPlay<void, T>(this);
}
else
{
VINDEX(AActor, BeginPlay);
// Without the type cast this picks the 'void *' assignment...
VMValue params[1] = { (DObject*)this };
VMFrameStack stack;
stack.Call(VFUNC, params, 1, nullptr, 0, nullptr);
}
}
void Activate(AActor *activator)
{
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template Activate<void, T>(this, activator);
}
else
{
VINDEX(AActor, Activate);
// Without the type cast this picks the 'void *' assignment...
VMValue params[2] = { (DObject*)this, (DObject*)activator };
VMFrameStack stack;
stack.Call(VFUNC, params, 2, nullptr, 0, nullptr);
}
}
void Deactivate(AActor *activator)
{
if (this->ObjectFlags & OF_SuperCall)
{
this->ObjectFlags &= ~OF_SuperCall;
ExportedNatives<T>::Get()->template Deactivate<void, T>(this, activator);
}
else
{
VINDEX(AActor, Deactivate);
// Without the type cast this picks the 'void *' assignment...
VMValue params[2] = { (DObject*)this, (DObject*)activator };
VMFrameStack stack;
stack.Call(VFUNC, params, 2, nullptr, 0, nullptr);
}
}
};
template<class T>
@ -130,7 +217,13 @@ VMEXPORT_NATIVES_END(DObject)
VMEXPORT_NATIVES_START(DThinker, DObject)
VMEXPORT_NATIVES_FUNC(Tick)
VMEXPORT_NATIVES_FUNC(PostBeginPlay)
VMEXPORT_NATIVES_END(DThinker)
VMEXPORT_NATIVES_END(DThinker)
VMEXPORT_NATIVES_START(AActor, DThinker)
VMEXPORT_NATIVES_FUNC(BeginPlay)
VMEXPORT_NATIVES_FUNC(Activate)
VMEXPORT_NATIVES_FUNC(Deactivate)
VMEXPORT_NATIVES_END(AActor)
/*
VMEXPORT_NATIVES_START(AActor, DThinker)

View file

@ -62,7 +62,10 @@ class Actor : Thinker native
{
return sin(fb * (180./32)) * 8;
}
virtual native void BeginPlay();
virtual native void Activate(Actor activator);
virtual native void Deactivate(Actor activator);
native static readonly<Actor> GetDefaultByType(class<Actor> cls);
native static double deltaangle(double ang1, double ang2);

View file

@ -10,6 +10,8 @@ class Object native
class Thinker : Object native
{
virtual native void Tick();
virtual native void PostBeginPlay();
}
class ThinkerIterator : Object native