mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
- build full argument lists for action function calls.
This uses one static global array to avoid frequent reallocations.
This commit is contained in:
parent
97573a0452
commit
16053c7cdb
3 changed files with 70 additions and 13 deletions
29
src/info.cpp
29
src/info.cpp
|
@ -148,6 +148,7 @@ void FState::CheckCallerType(AActor *self, AActor *stateowner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TArray<VMValue> actionParams;
|
||||||
|
|
||||||
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret)
|
||||||
{
|
{
|
||||||
|
@ -155,7 +156,6 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
|
||||||
{
|
{
|
||||||
ActionCycles.Clock();
|
ActionCycles.Clock();
|
||||||
|
|
||||||
VMValue params[3] = { self, stateowner, VMValue(info) };
|
|
||||||
// If the function returns a state, store it at *stateret.
|
// If the function returns a state, store it at *stateret.
|
||||||
// If it doesn't return a state but stateret is non-nullptr, we need
|
// If it doesn't return a state but stateret is non-nullptr, we need
|
||||||
// to set *stateret to nullptr.
|
// to set *stateret to nullptr.
|
||||||
|
@ -169,19 +169,36 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
|
||||||
stateret = nullptr;
|
stateret = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VMReturn ret;
|
||||||
|
ret.PointerAt((void **)stateret);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CheckCallerType(self, stateowner);
|
CheckCallerType(self, stateowner);
|
||||||
|
|
||||||
if (stateret == nullptr)
|
// Build the parameter array. Action functions have never any explicit parameters but need to pass the defaults
|
||||||
|
// and fill in the implicit arguments of the called function.
|
||||||
|
|
||||||
|
if (ActionFunc->DefaultArgs.Size() > 0)
|
||||||
{
|
{
|
||||||
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0);
|
auto index = actionParams.Append(ActionFunc->DefaultArgs);
|
||||||
|
if (ActionFunc->ImplicitArgs >= 1)
|
||||||
|
{
|
||||||
|
actionParams[index] = self;
|
||||||
|
}
|
||||||
|
if (ActionFunc->ImplicitArgs == 3)
|
||||||
|
{
|
||||||
|
actionParams[index + 1] = stateowner;
|
||||||
|
actionParams[index + 2] = VMValue(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
VMCallAction(ActionFunc, &actionParams[index], ActionFunc->DefaultArgs.Size(), &ret, stateret != nullptr);
|
||||||
|
actionParams.Clamp(index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VMReturn ret;
|
VMValue params[3] = { self, stateowner, VMValue(info) };
|
||||||
ret.PointerAt((void **)stateret);
|
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, stateret != nullptr);
|
||||||
VMCallAction(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
|
|
|
@ -96,12 +96,13 @@ static FRandom pr_bfgselfdamage("BFGSelfDamage");
|
||||||
// until there is no next state
|
// until there is no next state
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
extern TArray<VMValue> actionParams; // this can use the same storage as CallAction
|
||||||
|
|
||||||
|
|
||||||
bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
{
|
{
|
||||||
INTBOOL result = false;
|
INTBOOL result = false;
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
VMValue params[3] = { actor, this, 0 };
|
|
||||||
|
|
||||||
// We accept return types of `state`, `(int|bool)` or `state, (int|bool)`.
|
// We accept return types of `state`, `(int|bool)` or `state, (int|bool)`.
|
||||||
// The last one is for the benefit of A_Warp and A_Teleport.
|
// The last one is for the benefit of A_Warp and A_Teleport.
|
||||||
|
@ -139,7 +140,6 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
VMReturn *wantret;
|
VMReturn *wantret;
|
||||||
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
||||||
|
|
||||||
params[2] = VMValue(&stp);
|
|
||||||
retval = true; // assume success
|
retval = true; // assume success
|
||||||
wantret = NULL; // assume no return value wanted
|
wantret = NULL; // assume no return value wanted
|
||||||
numret = 0;
|
numret = 0;
|
||||||
|
@ -167,10 +167,33 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
wantret = &ret[1];
|
wantret = &ret[1];
|
||||||
numret = 1;
|
numret = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
state->CheckCallerType(actor, this);
|
state->CheckCallerType(actor, this);
|
||||||
VMCallAction(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
|
||||||
|
if (state->ActionFunc->DefaultArgs.Size() > 0)
|
||||||
|
{
|
||||||
|
auto index = actionParams.Append(state->ActionFunc->DefaultArgs);
|
||||||
|
if (state->ActionFunc->ImplicitArgs >= 1)
|
||||||
|
{
|
||||||
|
actionParams[index] = actor;
|
||||||
|
}
|
||||||
|
if (state->ActionFunc->ImplicitArgs == 3)
|
||||||
|
{
|
||||||
|
actionParams[index + 1] = this;
|
||||||
|
actionParams[index + 2] = VMValue(&stp);
|
||||||
|
}
|
||||||
|
|
||||||
|
VMCallAction(state->ActionFunc, &actionParams[index], state->ActionFunc->DefaultArgs.Size(), wantret, numret);
|
||||||
|
actionParams.Clamp(index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VMValue params[3] = { actor, this, VMValue(&stp) };
|
||||||
|
VMCallAction(state->ActionFunc, params, state->ActionFunc->ImplicitArgs, wantret, numret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
{
|
{
|
||||||
|
|
23
src/tarray.h
23
src/tarray.h
|
@ -278,13 +278,30 @@ public:
|
||||||
return Count++;
|
return Count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Append(const TArray<T> &item)
|
unsigned Append(const TArray<T> &item)
|
||||||
{
|
{
|
||||||
unsigned start = Reserve(item.Size());
|
unsigned start = Count;
|
||||||
|
|
||||||
|
Grow(item.Size());
|
||||||
|
|
||||||
for (unsigned i = 0; i < item.Size(); i++)
|
for (unsigned i = 0; i < item.Size(); i++)
|
||||||
{
|
{
|
||||||
Array[start + i] = item[i];
|
new(&Array[start + i]) T(item[i]);
|
||||||
}
|
}
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned Append(TArray<T> &&item)
|
||||||
|
{
|
||||||
|
unsigned start = Count;
|
||||||
|
|
||||||
|
Grow(item.Size());
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < item.Size(); i++)
|
||||||
|
{
|
||||||
|
new(&Array[start + i]) T(std::move(item[i]));
|
||||||
|
}
|
||||||
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pop ()
|
bool Pop ()
|
||||||
|
|
Loading…
Reference in a new issue