bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret) { if (ActionFunc != nullptr) { ActionCycles.Clock(); VMValue params[3] = { self, stateowner, VMValue(info) }; // If the function returns a state, store it at *stateret. // If it doesn't return a state but stateret is non-nullptr, we need // to set *stateret to nullptr. if (stateret != nullptr) { *stateret = nullptr; if (ActionFunc->Proto == nullptr || ActionFunc->Proto->ReturnTypes.Size() == 0 || ActionFunc->Proto->ReturnTypes[0] != TypeState) { stateret = nullptr; } } try { if (stateret == nullptr) { VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, nullptr, 0); } else { VMReturn ret; ret.PointerAt((void **)stateret); VMCall(ActionFunc, params, ActionFunc->ImplicitArgs, &ret, 1); } } catch (CVMAbortException &err) { err.MaybePrintMessage(); const char *callinfo = ""; if (info != nullptr && info->mStateType == STATE_Psprite) { if (stateowner->IsKindOf(NAME_Weapon) && stateowner != self) callinfo = "weapon "; else callinfo = "overlay "; } err.stacktrace.AppendFormat("Called from %sstate %s in %s\n", callinfo, FState::StaticGetStateName(this).GetChars(), stateowner->GetClass()->TypeName.GetChars()); throw; throw; } ActionCycles.Unclock(); return true; } else { return false; } }
bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info, FState **stateret) { if (ActionFunc != NULL) { ActionCycles.Clock(); static VMFrameStack stack; VMValue params[3] = { self, stateowner, VMValue(info, ATAG_STATEINFO) }; // If the function returns a state, store it at *stateret. // If it doesn't return a state but stateret is non-NULL, we need // to set *stateret to NULL. if (stateret != NULL) { *stateret = NULL; if (ActionFunc->Proto == NULL || ActionFunc->Proto->ReturnTypes.Size() == 0 || ActionFunc->Proto->ReturnTypes[0] != TypeState) { stateret = NULL; } } if (stateret == NULL) { stack.Call(ActionFunc, params, countof(params), NULL, 0, NULL); } else { VMReturn ret; ret.PointerAt((void **)stateret); stack.Call(ActionFunc, params, countof(params), &ret, 1, NULL); } ActionCycles.Unclock(); return true; } else { return false; } }