Use PField and not PSymbolVariable for ACS's Get/SetUserVariable

This commit is contained in:
Randy Heit 2013-08-21 22:39:28 -05:00
parent 4cf0ef7e3f
commit 5aff8156ba
2 changed files with 40 additions and 42 deletions

View file

@ -16,6 +16,7 @@
#define VARF_Optional (1<<0) // func param is optional
#define VARF_Method (1<<1) // func has an implied self parameter
#define VARF_Action (1<<2) // func has implied owner and state parameters
#define VARF_Native (1<<3) // func is native code/don't auto serialize field
// Symbol information -------------------------------------------------------

View file

@ -4273,59 +4273,56 @@ int DLevelScript::LineFromID(int id)
}
}
bool GetVarAddrType(AActor *self, FName varname, int index, void *&addr, PType *&type)
{
PField *var = dyn_cast<PField>(self->GetClass()->Symbols.FindSymbol(varname, true));
PArray *arraytype;
BYTE *baddr = reinterpret_cast<BYTE *>(self);
if (var == NULL || (var->Flags & VARF_Native))
{
return false;
}
type = var->Type;
arraytype = dyn_cast<PArray>(type);
if (arraytype != NULL)
{
// unwrap contained type
type = arraytype->ElementType;
// offset by index (if in bounds)
if ((unsigned)index < arraytype->ElementCount)
{ // out of bounds
return false;
}
baddr += arraytype->ElementSize * index;
}
else if (index != 0)
{ // ignore attempts to set indexed values on non-arrays
return false;
}
addr = baddr;
return true;
}
static void SetUserVariable(AActor *self, FName varname, int index, int value)
{
int max;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
void *addr;
PType *type;
if (var == NULL || !var->bUserVar)
if (GetVarAddrType(self, varname, index, addr, type))
{
return;
}
if (var->ValueType.Type == VAL_Int)
{
max = 1;
}
else if (var->ValueType.Type == VAL_Array && var->ValueType.BaseType == VAL_Int)
{
max = var->ValueType.size;
}
else
{
return;
}
// Set the value of the specified user variable.
if (index >= 0 && index < max)
{
((int *)(reinterpret_cast<BYTE *>(self) + var->offset))[index] = value;
type->SetValue(addr, value);
}
}
static int GetUserVariable(AActor *self, FName varname, int index)
{
int max;
PSymbolVariable *var = dyn_cast<PSymbolVariable>(self->GetClass()->Symbols.FindSymbol(varname, true));
void *addr;
PType *type;
if (var == NULL || !var->bUserVar)
if (GetVarAddrType(self, varname, index, addr, type))
{
return 0;
}
if (var->ValueType.Type == VAL_Int)
{
max = 1;
}
else if (var->ValueType.Type == VAL_Array && var->ValueType.BaseType == VAL_Int)
{
max = var->ValueType.size;
}
else
{
return 0;
}
// Get the value of the specified user variable.
if (index >= 0 && index < max)
{
return ((int *)(reinterpret_cast<BYTE *>(self) + var->offset))[index];
return type->GetValueInt(addr);
}
return 0;
}