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

View file

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

View file

@ -10,25 +10,16 @@
// Symbol information ------------------------------------------------------- // Symbol information -------------------------------------------------------
enum ESymbolType
{
SYM_Const,
SYM_Variable,
SYM_ActionFunction,
SYM_VMFunction
};
class PSymbol : public DObject class PSymbol : public DObject
{ {
DECLARE_ABSTRACT_CLASS(PSymbol, DObject); DECLARE_ABSTRACT_CLASS(PSymbol, DObject);
public: public:
virtual ~PSymbol(); virtual ~PSymbol();
ESymbolType SymbolType;
FName SymbolName; FName SymbolName;
protected: protected:
PSymbol(FName name, ESymbolType type) { SymbolType = type; SymbolName = name; } PSymbol(FName name) { SymbolName = name; }
}; };
// A constant value --------------------------------------------------------- // A constant value ---------------------------------------------------------
@ -44,8 +35,8 @@ public:
double Float; double Float;
}; };
PSymbolConst(FName name) : PSymbol(name, SYM_Const) {} PSymbolConst(FName name) : PSymbol(name) {}
PSymbolConst() : PSymbol(NAME_None, SYM_Const) {} PSymbolConst() : PSymbol(NAME_None) {}
}; };
// A variable --------------------------------------------------------- // A variable ---------------------------------------------------------
@ -59,8 +50,8 @@ public:
intptr_t offset; intptr_t offset;
bool bUserVar; bool bUserVar;
PSymbolVariable(FName name) : PSymbol(name, SYM_Variable) {} PSymbolVariable(FName name) : PSymbol(name) {}
PSymbolVariable() : PSymbol(NAME_None, SYM_Variable) {} PSymbolVariable() : PSymbol(NAME_None) {}
}; };
// An action function ------------------------------------------------------- // An action function -------------------------------------------------------
@ -98,8 +89,8 @@ public:
VMFunction *Function; VMFunction *Function;
int defaultparameterindex; int defaultparameterindex;
PSymbolActionFunction(FName name) : PSymbol(name, SYM_ActionFunction) {} PSymbolActionFunction(FName name) : PSymbol(name) {}
PSymbolActionFunction() : PSymbol(NAME_None, SYM_ActionFunction) {} PSymbolActionFunction() : PSymbol(NAME_None) {}
}; };
// A VM function ------------------------------------------------------------ // A VM function ------------------------------------------------------------
@ -111,8 +102,8 @@ class PSymbolVMFunction : public PSymbol
public: public:
VMFunction *Function; VMFunction *Function;
PSymbolVMFunction(FName name) : PSymbol(name, SYM_VMFunction) {} PSymbolVMFunction(FName name) : PSymbol(name) {}
PSymbolVMFunction() : PSymbol(NAME_None, SYM_VMFunction) {} PSymbolVMFunction() : PSymbol(NAME_None) {}
}; };
// A symbol table ----------------------------------------------------------- // 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) static void SetUserVariable(AActor *self, FName varname, int index, int value)
{ {
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
int max; int max;
PSymbolVariable *var; PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable || if (var == NULL || !var->bUserVar)
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar)
{ {
return; 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) static int GetUserVariable(AActor *self, FName varname, int index)
{ {
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true);
int max; int max;
PSymbolVariable *var; PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
if (sym == NULL || sym->SymbolType != SYM_Variable || if (var == NULL || !var->bUserVar)
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar)
{ {
return 0; return 0;
} }

View file

@ -65,6 +65,7 @@
#include "thingdef_exp.h" #include "thingdef_exp.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
#include "vmbuilder.h" #include "vmbuilder.h"
#include "stats.h"
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void InitThingdef(); void InitThingdef();
@ -368,7 +369,9 @@ static void FinishThingdef()
void LoadActors () void LoadActors ()
{ {
int lastlump, lump; int lastlump, lump;
cycle_t timer;
timer.Reset(); timer.Clock();
FScriptPosition::ResetErrorCounter(); FScriptPosition::ResetErrorCounter();
InitThingdef(); InitThingdef();
lastlump = 0; lastlump = 0;
@ -382,5 +385,8 @@ void LoadActors ()
I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter); I_Error("%d errors while parsing DECORATE scripts", FScriptPosition::ErrorCounter);
} }
FinishThingdef(); 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_NAME (varname);
PARAM_INT (value); PARAM_INT (value);
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true); PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
PSymbolVariable *var;
if (sym == NULL || sym->SymbolType != SYM_Variable || if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Int)
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar ||
var->ValueType.Type != VAL_Int)
{ {
Printf("%s is not a user variable in class %s\n", varname.GetChars(), Printf("%s is not a user variable in class %s\n", varname.GetChars(),
self->GetClass()->TypeName.GetChars()); self->GetClass()->TypeName.GetChars());
@ -3161,12 +3158,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray)
PARAM_INT (pos); PARAM_INT (pos);
PARAM_INT (value); PARAM_INT (value);
PSymbol *sym = self->GetClass()->Symbols.FindSymbol(varname, true); PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
PSymbolVariable *var;
if (sym == NULL || sym->SymbolType != SYM_Variable || if (var == NULL || !var->bUserVar || var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
!(var = static_cast<PSymbolVariable *>(sym))->bUserVar ||
var->ValueType.Type != VAL_Array || var->ValueType.BaseType != VAL_Int)
{ {
Printf("%s is not a user array in class %s\n", varname.GetChars(), Printf("%s is not a user array in class %s\n", varname.GetChars(),
self->GetClass()->TypeName.GetChars()); self->GetClass()->TypeName.GetChars());

View file

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

View file

@ -453,9 +453,9 @@ ExpVal FxConstant::EvalExpression (AActor *self)
FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos) FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos)
{ {
FxExpression *x; 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) switch(csym->ValueType)
{ {
case VAL_Int: case VAL_Int:
@ -2728,12 +2728,12 @@ FxExpression *FxIdentifier::Resolve(FCompileContext& ctx)
// see if the current class (if valid) defines something with this name. // see if the current class (if valid) defines something with this name.
if ((sym = ctx.FindInClass(Identifier)) != NULL) 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()); ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as class constant\n", Identifier.GetChars());
newex = FxConstant::MakeConstant(sym, ScriptPosition); newex = FxConstant::MakeConstant(sym, ScriptPosition);
} }
else if (sym->SymbolType == SYM_Variable) else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolVariable)))
{ {
PSymbolVariable *vsym = static_cast<PSymbolVariable*>(sym); PSymbolVariable *vsym = static_cast<PSymbolVariable*>(sym);
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as member variable, index %d\n", Identifier.GetChars(), vsym->offset); 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. // now check the global identifiers.
else if ((sym = ctx.FindGlobal(Identifier)) != NULL) 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()); ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global constant\n", Identifier.GetChars());
newex = FxConstant::MakeConstant(sym, ScriptPosition); 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); PSymbolVariable *vsym = static_cast<PSymbolVariable*>(sym);
ScriptPosition.Message(MSG_DEBUGLOG, "Resolving name '%s' as global variable, address %d\n", Identifier.GetChars(), vsym->offset); 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; goto endofstate;
} }
PSymbol *sym = bag.Info->Symbols.FindSymbol (FName(sc.String, true), true); PSymbolActionFunction *afd = dyn_cast<PSymbolActionFunction>(bag.Info->Symbols.FindSymbol (FName(sc.String, true), true));
if (sym != NULL && sym->SymbolType == SYM_ActionFunction) if (afd != NULL)
{ {
PSymbolActionFunction *afd = static_cast<PSymbolActionFunction *>(sym);
tcall->Function = afd->Function; tcall->Function = afd->Function;
if (!afd->Arguments.IsEmpty()) if (!afd->Arguments.IsEmpty())
{ {