- Use the standard DObject type system for the PSymbol hierarchy.

SVN r2264 (scripting)
This commit is contained in:
Randy Heit 2010-04-03 02:06:51 +00:00
parent ef3c020c8c
commit 549ddf8035
9 changed files with 65 additions and 95 deletions

View file

@ -82,7 +82,7 @@ static void UnloadDehSupp ();
// This is a list of all the action functions used by each of Doom's states.
static TArray<PSymbol *> Actions;
static TArray<PSymbolActionFunction *> Actions;
// These are the original heights of every Doom 2 thing. They are used if a patch
// specifies that a thing should be hanging from the ceiling but doesn't specify
@ -156,7 +156,7 @@ static TArray<MBFParamState> MBFParamStates;
// Data on how to correctly modify the codepointers
struct CodePointerAlias
{
char name[20];
FName name;
char alias[20];
BYTE params;
};
@ -630,11 +630,9 @@ void SetDehParams(FState * state, int codepointer)
FScriptPosition * pos = new FScriptPosition(FString("DEHACKED"), 0);
// Let's identify the codepointer we're dealing with.
PSymbolActionFunction * sym; PSymbol * s;
s = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true);
if (!s || s->SymbolType != SYM_ActionFunction) return;
sym = static_cast<PSymbolActionFunction*>(s);
PSymbolActionFunction *sym;
sym = dyn_cast<PSymbolActionFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(FName(MBFCodePointers[codepointer].name), true));
if (sym == NULL) return;
// Bleargh! This will all have to be redone once scripting works
@ -1598,22 +1596,20 @@ static int PatchWeapon (int weapNum)
return result;
}
static void SetPointer(FState *state, PSymbol *sym, int frame = 0)
static void SetPointer(FState *state, PSymbolActionFunction *sym, int frame = 0)
{
if (sym==NULL || sym->SymbolType != SYM_ActionFunction)
if (sym == NULL)
{
state->SetAction(NULL);
return;
}
else
{
FString symname = sym->SymbolName.GetChars();
state->SetAction(static_cast<PSymbolActionFunction*>(sym)->Function);
state->SetAction(sym->Function);
// Note: CompareNoCase() calls stricmp() and therefore returns 0 when they're the same.
for (unsigned int i = 0; i < MBFCodePointers.Size(); i++)
{
if (!symname.CompareNoCase(MBFCodePointers[i].name))
if (sym->SymbolName == MBFCodePointers[i].name)
{
MBFParamState newstate;
newstate.state = state;
@ -1667,7 +1663,9 @@ static int PatchPointer (int ptrNum)
{
int index = atoi(Line2);
if ((unsigned)(index) >= Actions.Size())
{
SetPointer(state, NULL);
}
else
{
SetPointer(state, Actions[index], CodePConv[ptrNum]);
@ -1990,14 +1988,14 @@ static int PatchCodePtrs (int dummy)
// This skips the action table and goes directly to the internal symbol table
// DEH compatible functions are easy to recognize.
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true);
if (sym == NULL || sym->SymbolType != SYM_ActionFunction)
PSymbolActionFunction *sym = dyn_cast<PSymbolActionFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true));
if (sym == NULL)
{
Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2);
}
else
{
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments;
FString &args = sym->Arguments;
if (args.Len() != 0 && (args[0] < 'a' || args[0] > 'z'))
{
Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2);
@ -2579,14 +2577,14 @@ static bool LoadDehSupp ()
// or AActor so this will find all of them.
FString name = "A_";
name << sc.String;
PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true);
if (sym == NULL || sym->SymbolType != SYM_ActionFunction)
PSymbolActionFunction *sym = dyn_cast<PSymbolActionFunction>(RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true));
if (sym == NULL)
{
sc.ScriptError("Unknown code pointer '%s'", sc.String);
}
else
{
FString &args = static_cast<PSymbolActionFunction*>(sym)->Arguments;
FString &args = sym->Arguments;
if (args.Len() != 0 && (args[0] < 'a' || args[0] > 'z'))
{
sc.ScriptError("Incompatible code pointer '%s'", sc.String);
@ -2814,8 +2812,7 @@ static bool LoadDehSupp ()
temp.alias[19]=0;
sc.MustGetStringName(",");
sc.MustGetString();
strncpy(temp.name, sc.String, 19);
temp.name[19]=0;
temp.name = sc.String;
sc.MustGetStringName(",");
sc.MustGetNumber();
temp.params = sc.Number;

View file

@ -394,11 +394,8 @@ void DObject::SerializeUserVars(FArchive &arc)
while (it.NextPair(pair))
{
PSymbol *sym = pair->Value;
if (sym->SymbolType == SYM_Variable)
{
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
if (var->bUserVar)
PSymbolVariable *var = dyn_cast<PSymbolVariable>(pair->Value);
if (var != NULL && var->bUserVar)
{
count = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
@ -412,7 +409,6 @@ void DObject::SerializeUserVars(FArchive &arc)
}
}
}
}
// Write terminator.
varname = NAME_None;
arc << varname;
@ -423,19 +419,14 @@ void DObject::SerializeUserVars(FArchive &arc)
arc << varname;
while (varname != NAME_None)
{
PSymbol *sym = symt->FindSymbol(varname, true);
PSymbolVariable *var = dyn_cast<PSymbolVariable>(symt->FindSymbol(varname, true));
DWORD wanted = 0;
if (sym != NULL && sym->SymbolType == SYM_Variable)
{
PSymbolVariable *var = static_cast<PSymbolVariable *>(sym);
if (var->bUserVar)
if (var != NULL && var->bUserVar)
{
wanted = var->ValueType.Type == VAL_Array ? var->ValueType.size : 1;
varloc = (int *)(reinterpret_cast<BYTE *>(this) + var->offset);
}
}
count = arc.ReadCount();
for (j = 0; j < MIN(wanted, count); ++j)
{

View file

@ -10,25 +10,16 @@
// Symbol information -------------------------------------------------------
enum ESymbolType
{
SYM_Const,
SYM_Variable,
SYM_ActionFunction,
SYM_VMFunction
};
class PSymbol : public DObject
{
DECLARE_ABSTRACT_CLASS(PSymbol, DObject);
public:
virtual ~PSymbol();
ESymbolType SymbolType;
FName SymbolName;
protected:
PSymbol(FName name, ESymbolType type) { SymbolType = type; SymbolName = name; }
PSymbol(FName name) { SymbolName = name; }
};
// A constant value ---------------------------------------------------------
@ -44,8 +35,8 @@ public:
double Float;
};
PSymbolConst(FName name) : PSymbol(name, SYM_Const) {}
PSymbolConst() : PSymbol(NAME_None, SYM_Const) {}
PSymbolConst(FName name) : PSymbol(name) {}
PSymbolConst() : PSymbol(NAME_None) {}
};
// A variable ---------------------------------------------------------
@ -59,8 +50,8 @@ public:
intptr_t offset;
bool bUserVar;
PSymbolVariable(FName name) : PSymbol(name, SYM_Variable) {}
PSymbolVariable() : PSymbol(NAME_None, SYM_Variable) {}
PSymbolVariable(FName name) : PSymbol(name) {}
PSymbolVariable() : PSymbol(NAME_None) {}
};
// An action function -------------------------------------------------------
@ -98,8 +89,8 @@ public:
VMFunction *Function;
int defaultparameterindex;
PSymbolActionFunction(FName name) : PSymbol(name, SYM_ActionFunction) {}
PSymbolActionFunction() : PSymbol(NAME_None, SYM_ActionFunction) {}
PSymbolActionFunction(FName name) : PSymbol(name) {}
PSymbolActionFunction() : PSymbol(NAME_None) {}
};
// A VM function ------------------------------------------------------------
@ -111,8 +102,8 @@ class PSymbolVMFunction : public PSymbol
public:
VMFunction *Function;
PSymbolVMFunction(FName name) : PSymbol(name, SYM_VMFunction) {}
PSymbolVMFunction() : PSymbol(NAME_None, SYM_VMFunction) {}
PSymbolVMFunction(FName name) : PSymbol(name) {}
PSymbolVMFunction() : PSymbol(NAME_None) {}
};
// A symbol table -----------------------------------------------------------

View file

@ -2976,12 +2976,10 @@ int DLevelScript::LineFromID(int id)
static void SetUserVariable(AActor *self, FName varname, int index, int value)
{
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
int max;
PSymbolVariable *var;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable ||
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar)
if (var == NULL || !var->bUserVar)
{
return;
}
@ -3006,12 +3004,10 @@ static void SetUserVariable(AActor *self, FName varname, int index, int value)
static int GetUserVariable(AActor *self, FName varname, int index)
{
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
int max;
PSymbolVariable *var;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable ||
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar)
if (var == NULL || !var->bUserVar)
{
return 0;
}

View file

@ -65,6 +65,7 @@
#include "thingdef_exp.h"
#include "a_sharedglobal.h"
#include "vmbuilder.h"
#include "stats.h"
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void InitThingdef();
@ -368,7 +369,9 @@ static void FinishThingdef()
void LoadActors ()
{
int lastlump, lump;
cycle_t timer;
timer.Reset(); timer.Clock();
FScriptPosition::ResetErrorCounter();
InitThingdef();
lastlump = 0;
@ -382,5 +385,8 @@ void LoadActors ()
I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter);
}
FinishThingdef();
timer.Unclock();
Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS());
// Base time: ~52 ms
}

View file

@ -3132,12 +3132,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserVar)
PARAM_NAME (varname);
PARAM_INT (value);
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
PSymbolVariable *var;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable ||
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar ||
var->ValueType.Type != VAL_Int)
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Int)
{
Printf("%s is not a user variable in class %s\n", varname.GetChars(),
self->GetClass()->TypeName.GetChars());
@ -3161,12 +3158,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray)
PARAM_INT (pos);
PARAM_INT (value);
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
PSymbolVariable *var;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable ||
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar ||
var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
{
Printf("%s is not a user array in class %s\n", varname.GetChars(),
self->GetClass()->TypeName.GetChars());

View file

@ -525,11 +525,7 @@ FVariableInfo *FindVariable(const char * string, const PClass *cls)
PSymbolActionFunction *FindGlobalActionFunction(const char *name)
{
PSymbol *sym = RUNTIME_CLASS(AActor)->Symbols.FindSymbol(name, false);
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
return static_cast<PSymbolActionFunction*>(sym);
else
return NULL;
return dyn_cast<PSymbolActionFunction>(RUNTIME_CLASS(AActor)->Symbols.FindSymbol(name, false));
}

View file

@ -453,9 +453,9 @@ ExpVal FxConstant::EvalExpression (AActor *self)
FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos)
{
FxExpression *x;
if (sym->SymbolType == SYM_Const)
PSymbolConst *csym = dyn_cast<PSymbolConst>(sym);
if (csym != NULL)
{
PSymbolConst *csym = static_cast<PSymbolConst*>(sym);
switch(csym->ValueType)
{
case VAL_Int:
@ -2728,12 +2728,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
// see if the current class (if valid) defines something with this name.
if ((sym = ctx.FindInClass(Identifier)) != NULL)
{
if (sym->SymbolType == SYM_Const)
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
{
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars());
newex = FxConstant::MakeConstant(sym, ScriptPosition);
}
else if (sym->SymbolType == SYM_Variable)
else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolVariable)))
{
PSymbolVariable *vsym = static_cast<PSymbolVariable*>(sym);
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->offset);
@ -2747,12 +2747,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
// now check the global identifiers.
else if ((sym = ctx.FindGlobal(Identifier)) != NULL)
{
if (sym->SymbolType == SYM_Const)
if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst)))
{
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global constant\n", Identifier.GetChars());
newex = FxConstant::MakeConstant(sym, ScriptPosition);
}
else if (sym->SymbolType == SYM_Variable) // global variables will always be native
else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolVariable))) // global variables will always be native
{
PSymbolVariable *vsym = static_cast<PSymbolVariable*>(sym);
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable, address %d\n", Identifier.GetChars(), vsym->offset);

View file

@ -272,10 +272,9 @@ do_stop:
goto endofstate;
}
PSymbol *sym = bag.Info->Symbols.FindSymbol (FName(sc.String, true), true);
if (sym != NULL && sym->SymbolType == SYM_ActionFunction)
PSymbolActionFunction *afd = dyn_cast<PSymbolActionFunction>(bag.Info->Symbols.FindSymbol (FName(sc.String, true), true));
if (afd != NULL)
{
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
tcall->Function = afd->Function;
if (!afd->Arguments.IsEmpty())
{