Esempio n. 1
0
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;
	}
}
Esempio n. 2
0
DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action = NAME_None, hfunc handler = nullptr)
{
	auto c = PClass::FindClass(gameinfo.MessageBoxClass);
	if (!c->IsDescendantOf(NAME_MessageBoxMenu)) c = PClass::FindClass(NAME_MessageBoxMenu);
	auto p = c->CreateNew();
	FString namestr = message;

	IFVIRTUALPTRNAME(p, NAME_MessageBoxMenu, Init)
	{
		VMValue params[] = { p, parent, &namestr, messagemode, playsound, action.GetIndex(), reinterpret_cast<void*>(handler) };
		VMCall(func, params, countof(params), nullptr, 0);
		return (DMenu*)p;
	}
Esempio n. 3
0
double AInventory::GetSpeedFactor()
{
	double factor = 1.;
	auto self = this;
	while (self != nullptr)
	{
		IFVIRTUALPTR(self, AInventory, GetSpeedFactor)
		{
			VMValue params[1] = { (DObject*)self };
			double retval;
			VMReturn ret(&retval);
			VMCall(func, params, 1, &ret, 1);
			factor *= retval;
		}
		self = self->Inventory;
	}
Esempio n. 4
0
void ezExpressionVM::Execute(const ezExpressionByteCode& byteCode, ezArrayPtr<const ezExpression::Stream> inputs,
                             ezArrayPtr<ezExpression::Stream> outputs, ezUInt32 uiNumInstances)
{
  // Input mapping
  {
    auto inputNames = byteCode.GetInputs();

    m_InputMapping.Clear();
    m_InputMapping.Reserve(inputNames.GetCount());

    for (auto& inputName : inputNames)
    {
      bool bInputFound = false;

      for (ezUInt32 i = 0; i < inputs.GetCount(); ++i)
      {
        if (inputs[i].m_sName == inputName)
        {
          inputs[i].ValidateDataSize(uiNumInstances, "Input");

          m_InputMapping.PushBack(i);
          bInputFound = true;
          break;
        }
      }

      EZ_ASSERT_DEV(bInputFound, "Bytecode expects an input '{0}'", inputName);
    }
  }

  // Output mapping
  {
    auto outputNames = byteCode.GetOutputs();

    m_OutputMapping.Clear();
    m_OutputMapping.Reserve(outputNames.GetCount());

    for (auto& outputName : outputNames)
    {
      bool bOutputFound = false;

      for (ezUInt32 i = 0; i < outputs.GetCount(); ++i)
      {
        if (outputs[i].m_sName == outputName)
        {
          outputs[i].ValidateDataSize(uiNumInstances, "Output");

          m_OutputMapping.PushBack(i);
          bOutputFound = true;
          break;
        }
      }

      EZ_ASSERT_DEV(bOutputFound, "Bytecode expects an output '{0}'", outputName);
    }
  }

  ezSimdVec4f* pRegisters = m_Registers.GetData();
  const ezUInt32 uiNumRegisters = (uiNumInstances + 3) / 4;
  const ezUInt32 uiLastInstanceIndex = uiNumInstances - 1;

  const ezUInt32 uiTotalNumRegisters = byteCode.GetNumTempRegisters() * uiNumRegisters;
  if (uiTotalNumRegisters > m_Registers.GetCount())
  {
    EZ_REPORT_FAILURE("Not enough registers to execute bytecode. Needs {0} but only has {1}.", uiTotalNumRegisters, m_Registers.GetCount());
    return;
  }

  // Execute bytecode
  const ezExpressionByteCode::StorageType* pByteCode = byteCode.GetByteCode();
  const ezExpressionByteCode::StorageType* pByteCodeEnd = byteCode.GetByteCodeEnd();

  while (pByteCode < pByteCodeEnd)
  {
    ezExpressionByteCode::OpCode::Enum opCode = ezExpressionByteCode::GetOpCode(pByteCode);

    switch (opCode)
    {
        // unary
      case ezExpressionByteCode::OpCode::Abs_R:
        VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x.Abs(); });
        break;

      case ezExpressionByteCode::OpCode::Sqrt_R:
        VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x.GetSqrt(); });
        break;

      case ezExpressionByteCode::OpCode::Mov_R:
        VMOperation1(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x; });
        break;

      case ezExpressionByteCode::OpCode::Mov_C:
        VMOperation1_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& x) { return x; });
        break;

      case ezExpressionByteCode::OpCode::Mov_I:
        VMLoadInput(pByteCode, pRegisters, uiNumRegisters, inputs, m_InputMapping);
        break;

      case ezExpressionByteCode::OpCode::Mov_O:
        VMStoreOutput(pByteCode, pRegisters, uiNumRegisters, outputs, m_OutputMapping);
        break;

        // binary
      case ezExpressionByteCode::OpCode::Add_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a + b; });
        break;

      case ezExpressionByteCode::OpCode::Add_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a + b; });
        break;

      case ezExpressionByteCode::OpCode::Sub_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a - b; });
        break;

      case ezExpressionByteCode::OpCode::Sub_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a - b; });
        break;

      case ezExpressionByteCode::OpCode::Mul_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMul(b); });
        break;

      case ezExpressionByteCode::OpCode::Mul_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMul(b); });
        break;

      case ezExpressionByteCode::OpCode::Div_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompDiv(b); });
        break;

      case ezExpressionByteCode::OpCode::Div_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompDiv(b); });
        break;

      case ezExpressionByteCode::OpCode::Min_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMin(b); });
        break;

      case ezExpressionByteCode::OpCode::Min_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMin(b); });
        break;

      case ezExpressionByteCode::OpCode::Max_RR:
        VMOperation2(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMax(b); });
        break;

      case ezExpressionByteCode::OpCode::Max_CR:
        VMOperation2_C(pByteCode, pRegisters, uiNumRegisters, [](const ezSimdVec4f& a, const ezSimdVec4f& b) { return a.CompMax(b); });
        break;

        // call
      case ezExpressionByteCode::OpCode::Call:
        VMCall(pByteCode, pRegisters, uiNumRegisters);
        break;

      default:
        EZ_ASSERT_NOT_IMPLEMENTED;
        return;
    }
  }
}
Esempio n. 5
0
	IFVM(PlayerPawn, BringUpWeapon)
	{
		VMValue param = player->mo;
		VMCall(func, &param, 1, nullptr, 0);
	}