- added SetRandomSeed function for ZScript. This uses the same RNG syntax as the other random functions.

This commit is contained in:
Christoph Oelckers 2017-05-31 11:33:57 +02:00
parent afa2888acb
commit 1465102ba0
3 changed files with 108 additions and 0 deletions

View file

@ -334,6 +334,8 @@ xx(FRandom)
xx(Random2)
xx(RandomPick)
xx(FRandomPick)
xx(SetRandomSeed)
xx(BuiltinRandomSeed)
xx(GetClass)
xx(GetParentClass)
xx(GetClassName)

View file

@ -5906,6 +5906,82 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
return out;
}
//==========================================================================
//
//
//
//==========================================================================
FxRandomSeed::FxRandomSeed(FRandom * r, FxExpression *s, const FScriptPosition &pos, bool nowarn)
: FxExpression(EFX_Random, pos)
{
EmitTail = false;
seed = new FxIntCast(s, nowarn);
rng = r;
ValueType = TypeVoid;
}
//==========================================================================
//
//
//
//==========================================================================
FxRandomSeed::~FxRandomSeed()
{
SAFE_DELETE(seed);
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxRandomSeed::Resolve(FCompileContext &ctx)
{
CHECKRESOLVED();
RESOLVE(seed, ctx);
return this;
};
//==========================================================================
//
//
//
//==========================================================================
int BuiltinRandomSeed(VMValue *param, TArray<VMValue> &defaultparam, int numparam, VMReturn *ret, int numret)
{
PARAM_PROLOGUE;
PARAM_POINTER(rng, FRandom)
PARAM_INT(seed);
rng->Init(seed);
return 0;
}
ExpEmit FxRandomSeed::Emit(VMFunctionBuilder *build)
{
// Call DecoRandom to generate a random number.
VMFunction *callfunc;
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinRandomSeed, BuiltinRandomSeed);
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolVMFunction)));
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
callfunc = ((PSymbolVMFunction *)sym)->Function;
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
EmitParameter(build, seed, ScriptPosition);
build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1);
ExpEmit call;
if (EmitTail) call.Final = true;
return call;
}
//==========================================================================
//
//
@ -7537,6 +7613,7 @@ FxFunctionCall::FxFunctionCall(FName methodname, FName rngname, FArgumentList &a
case NAME_RandomPick:
case NAME_FRandomPick:
case NAME_Random2:
case NAME_SetRandomSeed:
RNG = FRandom::StaticFindRNG(rngname.GetChars());
break;
@ -7790,6 +7867,14 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
}
break;
case NAME_SetRandomSeed:
if (CheckArgSize(NAME_Random, ArgList, 1, 1, ScriptPosition))
{
func = new FxRandomSeed(RNG, ArgList[0], ScriptPosition, ctx.FromDecorate);
ArgList[0] = nullptr;
}
break;
case NAME_Random:
// allow calling Random without arguments to default to (0, 255)
if (ArgList.Size() == 0)

View file

@ -1321,6 +1321,27 @@ public:
};
//==========================================================================
//
//
//
//==========================================================================
class FxRandomSeed : public FxExpression
{
protected:
bool EmitTail;
FRandom *rng;
FxExpression *seed;
public:
FxRandomSeed(FRandom *, FxExpression *mi, const FScriptPosition &pos, bool nowarn);
~FxRandomSeed();
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
};
//==========================================================================
//
// FxMemberBase