2016-03-01 15:47:10 +00:00
|
|
|
#ifndef DOBJTYPE_H
|
|
|
|
#define DOBJTYPE_H
|
|
|
|
|
|
|
|
#ifndef __DOBJECT_H__
|
|
|
|
#error You must #include "dobject.h" to get dobjtype.h
|
|
|
|
#endif
|
|
|
|
|
2016-04-03 22:45:04 +00:00
|
|
|
typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
|
2017-02-06 20:39:21 +00:00
|
|
|
class PStruct;
|
2016-04-03 22:45:04 +00:00
|
|
|
|
2016-11-17 12:10:19 +00:00
|
|
|
#include "vm.h"
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
// Variable/parameter/field flags -------------------------------------------
|
|
|
|
|
|
|
|
// Making all these different storage types use a common set of flags seems
|
|
|
|
// like the simplest thing to do.
|
|
|
|
|
2016-10-09 13:47:31 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
VARF_Optional = (1<<0), // func param is optional
|
|
|
|
VARF_Method = (1<<1), // func has an implied self parameter
|
|
|
|
VARF_Action = (1<<2), // func has implied owner and state parameters
|
2016-11-22 18:20:31 +00:00
|
|
|
VARF_Native = (1<<3), // func is native code, field is natively defined
|
2016-10-09 13:47:31 +00:00
|
|
|
VARF_ReadOnly = (1<<4), // field is read only, do not write to it
|
|
|
|
VARF_Private = (1<<5), // field is private to containing class
|
|
|
|
VARF_Protected = (1<<6), // field is only accessible by containing class and children.
|
|
|
|
VARF_Deprecated = (1<<7), // Deprecated fields should output warnings when used.
|
2016-10-11 16:53:10 +00:00
|
|
|
VARF_Virtual = (1<<8), // function is virtual
|
|
|
|
VARF_Final = (1<<9), // Function may not be overridden in subclasses
|
|
|
|
VARF_In = (1<<10),
|
|
|
|
VARF_Out = (1<<11),
|
2016-10-20 23:12:54 +00:00
|
|
|
VARF_Implicit = (1<<12), // implicitly created parameters (i.e. do not compare types when checking function signatures)
|
2017-01-15 15:55:30 +00:00
|
|
|
VARF_Static = (1<<13),
|
2016-11-08 10:12:56 +00:00
|
|
|
VARF_InternalAccess = (1<<14), // overrides VARF_ReadOnly for internal script code.
|
2016-11-11 19:05:07 +00:00
|
|
|
VARF_Override = (1<<15), // overrides a virtual function from the parent class.
|
2016-11-19 00:23:56 +00:00
|
|
|
VARF_Ref = (1<<16), // argument is passed by reference.
|
2017-01-15 15:55:30 +00:00
|
|
|
VARF_Transient = (1<<17), // don't auto serialize field.
|
|
|
|
VARF_Meta = (1<<18), // static class data (by necessity read only.)
|
2017-01-21 00:07:44 +00:00
|
|
|
VARF_VarArg = (1<<19), // [ZZ] vararg: don't typecheck values after ... in function signature
|
2017-02-17 15:58:16 +00:00
|
|
|
VARF_UI = (1<<20), // [ZZ] ui: object is ui-scope only (can't modify playsim)
|
|
|
|
VARF_Play = (1<<21), // [ZZ] play: object is playsim-scope only (can't access ui)
|
2017-02-18 02:07:12 +00:00
|
|
|
VARF_VirtualScope = (1<<22), // [ZZ] virtualscope: object should use the scope of the particular class it's being used with (methods only)
|
2016-10-09 13:47:31 +00:00
|
|
|
};
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
// An action function -------------------------------------------------------
|
|
|
|
|
|
|
|
struct FState;
|
|
|
|
struct StateCallData;
|
|
|
|
class VMFrameStack;
|
|
|
|
struct VMValue;
|
|
|
|
struct VMReturn;
|
|
|
|
class VMFunction;
|
2017-01-24 10:57:42 +00:00
|
|
|
struct FNamespaceManager;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
// Basic information shared by all types ------------------------------------
|
|
|
|
|
|
|
|
// Only one copy of a type is ever instantiated at one time.
|
|
|
|
// - Enums, classes, and structs are defined by their names and outer classes.
|
|
|
|
// - Pointers are uniquely defined by the type they point at.
|
|
|
|
// - ClassPointers are also defined by their class restriction.
|
|
|
|
// - Arrays are defined by their element type and count.
|
|
|
|
// - DynArrays are defined by their element type.
|
|
|
|
// - Maps are defined by their key and value types.
|
|
|
|
// - Prototypes are defined by the argument and return types.
|
|
|
|
// - Functions are defined by their names and outer objects.
|
|
|
|
// In table form:
|
|
|
|
// Outer Name Type Type2 Count
|
|
|
|
// Enum * *
|
|
|
|
// Class * *
|
|
|
|
// Struct * *
|
|
|
|
// Function * *
|
|
|
|
// Pointer *
|
|
|
|
// ClassPointer + *
|
|
|
|
// Array * *
|
|
|
|
// DynArray *
|
|
|
|
// Map * *
|
|
|
|
// Prototype *+ *+
|
|
|
|
|
|
|
|
struct ZCC_ExprConstant;
|
2016-10-07 11:59:29 +00:00
|
|
|
class PType : public PTypeBase
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2016-10-07 11:59:29 +00:00
|
|
|
DECLARE_ABSTRACT_CLASS(PType, PTypeBase)
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
2016-10-28 08:44:01 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
public:
|
2017-02-07 19:25:52 +00:00
|
|
|
PClass *TypeTableType; // The type to use for hashing into the type table
|
2016-03-01 15:47:10 +00:00
|
|
|
unsigned int Size; // this type's size
|
|
|
|
unsigned int Align; // this type's preferred alignment
|
|
|
|
PType *HashNext; // next type in this type table
|
|
|
|
PSymbolTable Symbols;
|
2016-10-16 10:47:26 +00:00
|
|
|
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
|
2016-10-16 17:42:22 +00:00
|
|
|
FString mDescriptiveName;
|
2016-10-28 12:43:29 +00:00
|
|
|
BYTE loadOp, storeOp, moveOp, RegType, RegCount;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-10-28 08:44:01 +00:00
|
|
|
PType(unsigned int size = 1, unsigned int align = 1);
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual ~PType();
|
2016-11-14 13:12:27 +00:00
|
|
|
virtual bool isNumeric() { return false; }
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-04-03 04:10:43 +00:00
|
|
|
// Writes the value of a variable of this type at (addr) to an archive, preceded by
|
|
|
|
// a tag indicating its type. The tag is there so that variable types can be changed
|
|
|
|
// without completely breaking savegames, provided that the change isn't between
|
|
|
|
// totally unrelated types.
|
2016-09-20 16:27:47 +00:00
|
|
|
virtual void WriteValue(FSerializer &ar, const char *key,const void *addr) const;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
|
|
|
// Returns true if the stored value was compatible. False otherwise.
|
|
|
|
// If the value was incompatible, then the memory at *addr is unchanged.
|
2016-09-20 16:27:47 +00:00
|
|
|
virtual bool ReadValue(FSerializer &ar, const char *key,void *addr) const;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-04-03 22:45:04 +00:00
|
|
|
// Sets the default value for this type at (base + offset)
|
|
|
|
// If the default value is binary 0, then this function doesn't need
|
|
|
|
// to do anything, because PClass::Extend() takes care of that.
|
|
|
|
//
|
|
|
|
// The stroffs array is so that types that need special initialization
|
|
|
|
// and destruction (e.g. strings) can add their offsets to it for special
|
|
|
|
// initialization when the object is created and destruction when the
|
|
|
|
// object is destroyed.
|
|
|
|
virtual void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const;
|
2016-11-17 21:21:08 +00:00
|
|
|
virtual void SetPointer(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
|
2017-02-07 13:48:27 +00:00
|
|
|
virtual void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const;
|
2016-04-03 22:45:04 +00:00
|
|
|
|
|
|
|
// Initialize the value, if needed (e.g. strings)
|
|
|
|
virtual void InitializeValue(void *addr, const void *def) const;
|
|
|
|
|
|
|
|
// Destroy the value, if needed (e.g. strings)
|
|
|
|
virtual void DestroyValue(void *addr) const;
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
// Sets the value of a variable of this type at (addr)
|
|
|
|
virtual void SetValue(void *addr, int val);
|
2016-03-30 03:05:25 +00:00
|
|
|
virtual void SetValue(void *addr, double val);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
// Gets the value of a variable of this type at (addr)
|
|
|
|
virtual int GetValueInt(void *addr) const;
|
2016-03-30 03:24:59 +00:00
|
|
|
virtual double GetValueFloat(void *addr) const;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
// Gets the opcode to store from a register to memory
|
2016-10-28 08:44:01 +00:00
|
|
|
int GetStoreOp() const
|
|
|
|
{
|
|
|
|
return storeOp;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
// Gets the opcode to load from memory to a register
|
2016-10-28 08:44:01 +00:00
|
|
|
int GetLoadOp() const
|
|
|
|
{
|
|
|
|
return loadOp;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-10-20 23:12:54 +00:00
|
|
|
// Gets the opcode to move from register to another register
|
2016-10-28 08:44:01 +00:00
|
|
|
int GetMoveOp() const
|
|
|
|
{
|
|
|
|
return moveOp;
|
|
|
|
}
|
2016-10-20 23:12:54 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
// Gets the register type for this type
|
2016-10-28 08:44:01 +00:00
|
|
|
int GetRegType() const
|
|
|
|
{
|
|
|
|
return RegType;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-10-28 12:43:29 +00:00
|
|
|
int GetRegCount() const
|
|
|
|
{
|
|
|
|
return RegCount;
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
// Returns true if this type matches the two identifiers. Referring to the
|
|
|
|
// above table, any type is identified by at most two characteristics. Each
|
|
|
|
// type that implements this function will cast these to the appropriate type.
|
|
|
|
// It is up to the caller to make sure they are the correct types. There is
|
|
|
|
// only one prototype for this function in order to simplify type table
|
|
|
|
// management.
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
|
|
|
|
// Get the type IDs used by IsMatch
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
|
2016-10-16 17:42:22 +00:00
|
|
|
const char *DescriptiveName() const;
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
static void StaticInit();
|
|
|
|
};
|
|
|
|
|
|
|
|
// Not-really-a-type types --------------------------------------------------
|
|
|
|
|
|
|
|
class PErrorType : public PType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PErrorType, PType);
|
|
|
|
public:
|
2016-12-05 12:24:42 +00:00
|
|
|
PErrorType(int which = 1) : PType(0, which) {}
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class PVoidType : public PType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PVoidType, PType);
|
|
|
|
public:
|
|
|
|
PVoidType() : PType(0, 1) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Some categorization typing -----------------------------------------------
|
|
|
|
|
|
|
|
class PBasicType : public PType
|
|
|
|
{
|
|
|
|
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
|
|
|
|
public:
|
|
|
|
PBasicType();
|
|
|
|
PBasicType(unsigned int size, unsigned int align);
|
|
|
|
};
|
|
|
|
|
|
|
|
class PCompoundType : public PType
|
|
|
|
{
|
|
|
|
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
|
|
|
|
};
|
|
|
|
|
|
|
|
class PNamedType : public PCompoundType
|
|
|
|
{
|
|
|
|
DECLARE_ABSTRACT_CLASS(PNamedType, PCompoundType);
|
|
|
|
public:
|
2016-10-07 11:59:29 +00:00
|
|
|
PTypeBase *Outer; // object this type is contained within
|
2016-03-01 15:47:10 +00:00
|
|
|
FName TypeName; // this type's name
|
|
|
|
|
2016-10-16 17:42:22 +00:00
|
|
|
PNamedType() : Outer(NULL) {
|
|
|
|
mDescriptiveName = "NamedType";
|
|
|
|
}
|
|
|
|
PNamedType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
|
|
|
|
mDescriptiveName = name.GetChars();
|
|
|
|
}
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Basic types --------------------------------------------------------------
|
|
|
|
|
|
|
|
class PInt : public PBasicType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PInt, PBasicType);
|
|
|
|
public:
|
2016-11-14 13:12:27 +00:00
|
|
|
PInt(unsigned int size, bool unsign, bool compatible = true);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual void SetValue(void *addr, int val);
|
2016-03-30 03:05:25 +00:00
|
|
|
virtual void SetValue(void *addr, double val);
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual int GetValueInt(void *addr) const;
|
2016-03-30 03:24:59 +00:00
|
|
|
virtual double GetValueFloat(void *addr) const;
|
2016-11-14 13:12:27 +00:00
|
|
|
virtual bool isNumeric() override { return IntCompatible; }
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
bool Unsigned;
|
2016-11-14 13:12:27 +00:00
|
|
|
bool IntCompatible;
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PInt();
|
2016-10-28 08:44:01 +00:00
|
|
|
void SetOps();
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class PBool : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PBool, PInt);
|
|
|
|
public:
|
|
|
|
PBool();
|
|
|
|
};
|
|
|
|
|
|
|
|
class PFloat : public PBasicType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PFloat, PBasicType);
|
|
|
|
public:
|
|
|
|
PFloat(unsigned int size);
|
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual void SetValue(void *addr, int val);
|
2016-03-30 03:05:25 +00:00
|
|
|
virtual void SetValue(void *addr, double val);
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual int GetValueInt(void *addr) const;
|
2016-03-30 03:24:59 +00:00
|
|
|
virtual double GetValueFloat(void *addr) const;
|
2016-11-14 13:12:27 +00:00
|
|
|
virtual bool isNumeric() override { return true; }
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PFloat();
|
2016-10-28 08:44:01 +00:00
|
|
|
void SetOps();
|
2016-03-01 15:47:10 +00:00
|
|
|
private:
|
|
|
|
struct SymbolInitF
|
|
|
|
{
|
|
|
|
ENamedName Name;
|
|
|
|
double Value;
|
|
|
|
};
|
|
|
|
struct SymbolInitI
|
|
|
|
{
|
|
|
|
ENamedName Name;
|
|
|
|
int Value;
|
|
|
|
};
|
|
|
|
|
|
|
|
void SetSingleSymbols();
|
|
|
|
void SetDoubleSymbols();
|
|
|
|
void SetSymbols(const SymbolInitF *syminit, size_t count);
|
|
|
|
void SetSymbols(const SymbolInitI *syminit, size_t count);
|
|
|
|
};
|
|
|
|
|
|
|
|
class PString : public PBasicType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PString, PBasicType);
|
|
|
|
public:
|
|
|
|
PString();
|
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 22:45:04 +00:00
|
|
|
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special=NULL) const override;
|
|
|
|
void InitializeValue(void *addr, const void *def) const override;
|
|
|
|
void DestroyValue(void *addr) const override;
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Variations of integer types ----------------------------------------------
|
|
|
|
|
|
|
|
class PName : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PName, PInt);
|
|
|
|
public:
|
|
|
|
PName();
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class PSound : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PSound, PInt);
|
|
|
|
public:
|
|
|
|
PSound();
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
2016-11-21 12:45:33 +00:00
|
|
|
class PSpriteID : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PSpriteID, PInt);
|
|
|
|
public:
|
|
|
|
PSpriteID();
|
|
|
|
|
|
|
|
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PTextureID : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PTextureID, PInt);
|
|
|
|
public:
|
|
|
|
PTextureID();
|
|
|
|
|
|
|
|
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
|
|
|
};
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
class PColor : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PColor, PInt);
|
|
|
|
public:
|
|
|
|
PColor();
|
|
|
|
};
|
|
|
|
|
2016-11-14 13:12:27 +00:00
|
|
|
class PStateLabel : public PInt
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PStateLabel, PInt);
|
|
|
|
public:
|
|
|
|
PStateLabel();
|
|
|
|
};
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
// Pointers -----------------------------------------------------------------
|
|
|
|
|
|
|
|
class PPointer : public PBasicType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PPointer, PBasicType);
|
2017-03-03 19:11:13 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
public:
|
2017-03-03 19:11:13 +00:00
|
|
|
typedef void(*WriteHandler)(FSerializer &ar, const char *key, const void *addr);
|
|
|
|
typedef bool(*ReadHandler)(FSerializer &ar, const char *key, void *addr);
|
|
|
|
|
2016-10-21 17:18:39 +00:00
|
|
|
PPointer();
|
2016-11-05 12:51:46 +00:00
|
|
|
PPointer(PType *pointsat, bool isconst = false);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
PType *PointedType;
|
2016-11-05 12:51:46 +00:00
|
|
|
bool IsConst;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-03-03 19:11:13 +00:00
|
|
|
WriteHandler writer = nullptr;
|
|
|
|
ReadHandler reader = nullptr;
|
|
|
|
|
|
|
|
void InstallHandlers(WriteHandler w, ReadHandler r)
|
|
|
|
{
|
|
|
|
writer = w;
|
|
|
|
reader = r;
|
|
|
|
}
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
2016-11-17 21:21:08 +00:00
|
|
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
2016-10-28 08:44:01 +00:00
|
|
|
void SetOps();
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
2016-11-21 18:36:14 +00:00
|
|
|
class PStatePointer : public PPointer
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PStatePointer, PPointer);
|
|
|
|
public:
|
|
|
|
PStatePointer();
|
|
|
|
|
|
|
|
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
class PClassPointer : public PPointer
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PClassPointer, PPointer);
|
|
|
|
public:
|
2017-02-07 13:48:27 +00:00
|
|
|
PClassPointer(class PClass *restrict = nullptr);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
class PClass *ClassRestriction;
|
|
|
|
|
2017-01-17 23:11:04 +00:00
|
|
|
bool isCompatible(PType *type);
|
2016-11-17 21:21:08 +00:00
|
|
|
|
2017-02-15 10:55:08 +00:00
|
|
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *special = NULL) const override;
|
2016-03-01 15:47:10 +00:00
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Compound types -----------------------------------------------------------
|
|
|
|
|
2017-01-23 18:09:36 +00:00
|
|
|
class PEnum : public PInt
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2017-01-23 18:09:36 +00:00
|
|
|
DECLARE_CLASS(PEnum, PInt);
|
2016-03-01 15:47:10 +00:00
|
|
|
public:
|
2016-10-07 11:59:29 +00:00
|
|
|
PEnum(FName name, PTypeBase *outer);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-01-23 18:09:36 +00:00
|
|
|
PTypeBase *Outer;
|
|
|
|
FName EnumName;
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PEnum();
|
|
|
|
};
|
|
|
|
|
|
|
|
class PArray : public PCompoundType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PArray, PCompoundType);
|
|
|
|
public:
|
|
|
|
PArray(PType *etype, unsigned int ecount);
|
|
|
|
|
|
|
|
PType *ElementType;
|
|
|
|
unsigned int ElementCount;
|
|
|
|
unsigned int ElementSize;
|
|
|
|
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-04-03 22:45:04 +00:00
|
|
|
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *special) const override;
|
2016-11-17 21:21:08 +00:00
|
|
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *special) const override;
|
2016-04-03 22:45:04 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PArray();
|
|
|
|
};
|
|
|
|
|
2017-01-02 20:40:52 +00:00
|
|
|
class PResizableArray : public PArray
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PResizableArray, PArray);
|
|
|
|
public:
|
|
|
|
PResizableArray(PType *etype);
|
|
|
|
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
PResizableArray();
|
|
|
|
};
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
class PDynArray : public PCompoundType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PDynArray, PCompoundType);
|
|
|
|
public:
|
2017-02-06 20:39:21 +00:00
|
|
|
PDynArray(PType *etype, PStruct *backing);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
PType *ElementType;
|
2017-02-06 20:39:21 +00:00
|
|
|
PStruct *BackingType;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
2017-02-07 13:48:27 +00:00
|
|
|
|
|
|
|
void WriteValue(FSerializer &ar, const char *key, const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key, void *addr) const override;
|
|
|
|
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
|
|
|
|
void InitializeValue(void *addr, const void *def) const override;
|
|
|
|
void DestroyValue(void *addr) const override;
|
|
|
|
void SetPointerArray(void *base, unsigned offset, TArray<size_t> *ptrofs = NULL) const override;
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PDynArray();
|
|
|
|
};
|
|
|
|
|
|
|
|
class PMap : public PCompoundType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PMap, PCompoundType);
|
|
|
|
public:
|
|
|
|
PMap(PType *keytype, PType *valtype);
|
|
|
|
|
|
|
|
PType *KeyType;
|
|
|
|
PType *ValueType;
|
|
|
|
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
protected:
|
|
|
|
PMap();
|
|
|
|
};
|
|
|
|
|
|
|
|
class PStruct : public PNamedType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PStruct, PNamedType);
|
2017-01-11 22:46:03 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
public:
|
2016-10-07 11:59:29 +00:00
|
|
|
PStruct(FName name, PTypeBase *outer);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
TArray<PField *> Fields;
|
2016-11-03 12:38:40 +00:00
|
|
|
bool HasNativeFields;
|
2017-01-11 22:46:03 +00:00
|
|
|
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use thes two functions for it.
|
|
|
|
VMFunction *mConstructor = nullptr;
|
|
|
|
VMFunction *mDestructor = nullptr;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-04-03 21:18:59 +00:00
|
|
|
virtual PField *AddField(FName name, PType *type, DWORD flags=0);
|
2016-11-22 18:20:31 +00:00
|
|
|
virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = 0);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
2016-04-03 22:45:04 +00:00
|
|
|
void SetDefaultValue(void *base, unsigned offset, TArray<FTypeAndOffset> *specials) const override;
|
2016-11-17 21:21:08 +00:00
|
|
|
void SetPointer(void *base, unsigned offset, TArray<size_t> *specials) const override;
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-09-20 16:27:47 +00:00
|
|
|
static void WriteFields(FSerializer &ar, const void *addr, const TArray<PField *> &fields);
|
|
|
|
bool ReadFields(FSerializer &ar, void *addr) const;
|
2016-03-01 15:47:10 +00:00
|
|
|
protected:
|
|
|
|
PStruct();
|
|
|
|
};
|
|
|
|
|
2016-11-19 11:12:29 +00:00
|
|
|
// a native struct will always be abstract and cannot be instantiated. All variables are references.
|
|
|
|
// In addition, native structs can have methods (but no virtual ones.)
|
|
|
|
class PNativeStruct : public PStruct
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PNativeStruct, PStruct);
|
|
|
|
public:
|
2017-01-23 18:09:36 +00:00
|
|
|
PNativeStruct(FName name = NAME_None, PTypeBase *outer = nullptr);
|
2016-11-19 11:12:29 +00:00
|
|
|
};
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
class PPrototype : public PCompoundType
|
|
|
|
{
|
|
|
|
DECLARE_CLASS(PPrototype, PCompoundType);
|
|
|
|
public:
|
|
|
|
PPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
|
|
|
|
|
|
|
|
TArray<PType *> ArgumentTypes;
|
|
|
|
TArray<PType *> ReturnTypes;
|
|
|
|
|
|
|
|
size_t PropagateMark();
|
|
|
|
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
|
|
|
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
|
|
|
protected:
|
|
|
|
PPrototype();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Meta-info for every class derived from DObject ---------------------------
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
TentativeClass = UINT_MAX,
|
|
|
|
};
|
|
|
|
|
2016-11-19 11:12:29 +00:00
|
|
|
class PClass : public PNativeStruct
|
2016-03-01 15:47:10 +00:00
|
|
|
{
|
2016-11-19 11:12:29 +00:00
|
|
|
DECLARE_CLASS(PClass, PNativeStruct);
|
2016-03-01 15:47:10 +00:00
|
|
|
// We unravel _WITH_META here just as we did for PType.
|
2017-02-27 22:28:19 +00:00
|
|
|
protected:
|
|
|
|
TArray<FTypeAndOffset> MetaInits;
|
2016-11-11 19:05:07 +00:00
|
|
|
void Derive(PClass *newclass, FName name);
|
2017-02-27 22:28:19 +00:00
|
|
|
void InitializeSpecials(void *addr, void *defaults, TArray<FTypeAndOffset> PClass::*Inits);
|
2016-10-08 20:16:10 +00:00
|
|
|
void SetSuper();
|
2017-02-27 22:28:19 +00:00
|
|
|
PField *AddMetaField(FName name, PType *type, DWORD flags);
|
2016-03-01 15:47:10 +00:00
|
|
|
public:
|
2016-09-20 16:27:47 +00:00
|
|
|
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
|
|
|
void WriteAllFields(FSerializer &ar, const void *addr) const;
|
|
|
|
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
|
|
|
bool ReadAllFields(FSerializer &ar, void *addr) const;
|
2016-11-11 13:40:32 +00:00
|
|
|
void InitializeDefaults();
|
2016-11-11 19:05:07 +00:00
|
|
|
int FindVirtualIndex(FName name, PPrototype *proto);
|
|
|
|
virtual void DeriveData(PClass *newclass);
|
2016-04-03 04:10:43 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
static void StaticInit();
|
|
|
|
static void StaticShutdown();
|
|
|
|
static void StaticBootstrap();
|
|
|
|
|
|
|
|
// Per-class information -------------------------------------
|
2017-02-27 22:28:19 +00:00
|
|
|
TArray<FTypeAndOffset> SpecialInits;
|
2016-03-01 15:47:10 +00:00
|
|
|
PClass *ParentClass; // the class this class derives from
|
|
|
|
const size_t *Pointers; // object pointers defined by this class *only*
|
|
|
|
const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default
|
2017-02-07 13:48:27 +00:00
|
|
|
const size_t *ArrayPointers; // dynamic arrays containing object pointers.
|
2016-03-01 15:47:10 +00:00
|
|
|
BYTE *Defaults;
|
2017-02-27 22:28:19 +00:00
|
|
|
BYTE *Meta; // Per-class static script data
|
|
|
|
unsigned MetaSize;
|
2016-03-01 15:47:10 +00:00
|
|
|
bool bRuntimeClass; // class was defined at run-time, not compile-time
|
2016-10-31 16:02:47 +00:00
|
|
|
bool bExported; // This type has been declared in a script
|
2016-11-13 11:02:41 +00:00
|
|
|
bool bDecorateClass; // may be subject to some idiosyncracies due to DECORATE backwards compatibility
|
2016-11-11 19:05:07 +00:00
|
|
|
TArray<VMFunction*> Virtuals; // virtual function table
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
void (*ConstructNative)(void *);
|
|
|
|
|
|
|
|
// The rest are all functions and static data ----------------
|
|
|
|
PClass();
|
|
|
|
~PClass();
|
|
|
|
void InsertIntoHash();
|
2017-02-27 22:28:19 +00:00
|
|
|
DObject *CreateNew();
|
2016-03-01 15:47:10 +00:00
|
|
|
PClass *CreateDerivedClass(FName name, unsigned int size);
|
2016-04-03 21:18:59 +00:00
|
|
|
PField *AddField(FName name, PType *type, DWORD flags=0) override;
|
2016-03-01 15:47:10 +00:00
|
|
|
void InitializeActorInfo();
|
|
|
|
void BuildFlatPointers();
|
2017-02-07 13:48:27 +00:00
|
|
|
void BuildArrayPointers();
|
2017-02-27 23:45:16 +00:00
|
|
|
void InitMeta();
|
2017-02-27 22:28:19 +00:00
|
|
|
void DestroySpecials(void *addr);
|
2016-03-01 15:47:10 +00:00
|
|
|
const PClass *NativeClass() const;
|
|
|
|
|
|
|
|
// Returns true if this type is an ancestor of (or same as) the passed type.
|
|
|
|
bool IsAncestorOf(const PClass *ti) const
|
|
|
|
{
|
|
|
|
while (ti)
|
|
|
|
{
|
|
|
|
if (this == ti)
|
|
|
|
return true;
|
|
|
|
ti = ti->ParentClass;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2017-02-08 14:47:22 +00:00
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
inline bool IsDescendantOf(const PClass *ti) const
|
|
|
|
{
|
|
|
|
return ti->IsAncestorOf(this);
|
|
|
|
}
|
|
|
|
|
2017-02-08 14:47:22 +00:00
|
|
|
inline bool IsDescendantOf(FName ti) const
|
|
|
|
{
|
|
|
|
auto me = this;
|
|
|
|
while (me)
|
|
|
|
{
|
|
|
|
if (me->TypeName == ti)
|
|
|
|
return true;
|
|
|
|
me = me->ParentClass;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
// Find a type, given its name.
|
2016-04-03 04:10:43 +00:00
|
|
|
const PClass *FindParentClass(FName name) const;
|
|
|
|
PClass *FindParentClass(FName name) { return const_cast<PClass *>(const_cast<const PClass *>(this)->FindParentClass(name)); }
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
static PClass *FindClass(const char *name) { return FindClass(FName(name, true)); }
|
|
|
|
static PClass *FindClass(const FString &name) { return FindClass(FName(name, true)); }
|
|
|
|
static PClass *FindClass(ENamedName name) { return FindClass(FName(name)); }
|
|
|
|
static PClass *FindClass(FName name);
|
|
|
|
static PClassActor *FindActor(const char *name) { return FindActor(FName(name, true)); }
|
|
|
|
static PClassActor *FindActor(const FString &name) { return FindActor(FName(name, true)); }
|
|
|
|
static PClassActor *FindActor(ENamedName name) { return FindActor(FName(name)); }
|
|
|
|
static PClassActor *FindActor(FName name);
|
2016-11-28 13:39:25 +00:00
|
|
|
static VMFunction *FindFunction(FName cls, FName func);
|
2017-01-31 12:41:23 +00:00
|
|
|
static void FindFunction(VMFunction **pptr, FName cls, FName func);
|
2016-11-12 12:09:19 +00:00
|
|
|
PClass *FindClassTentative(FName name);
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
static TArray<PClass *> AllClasses;
|
2017-01-31 12:41:23 +00:00
|
|
|
static TArray<VMFunction**> FunctionPtrList;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
|
|
|
static bool bShutdown;
|
2017-01-13 12:51:47 +00:00
|
|
|
static bool bVMOperational;
|
2016-03-01 15:47:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Type tables --------------------------------------------------------------
|
|
|
|
|
|
|
|
struct FTypeTable
|
|
|
|
{
|
|
|
|
enum { HASH_SIZE = 1021 };
|
|
|
|
|
|
|
|
PType *TypeHash[HASH_SIZE];
|
|
|
|
|
|
|
|
PType *FindType(PClass *metatype, intptr_t parm1, intptr_t parm2, size_t *bucketnum);
|
|
|
|
void AddType(PType *type, PClass *metatype, intptr_t parm1, intptr_t parm2, size_t bucket);
|
|
|
|
void AddType(PType *type);
|
|
|
|
void Clear();
|
|
|
|
|
|
|
|
static size_t Hash(const PClass *p1, intptr_t p2, intptr_t p3);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
extern FTypeTable TypeTable;
|
|
|
|
|
|
|
|
// Returns a type from the TypeTable. Will create one if it isn't present.
|
|
|
|
PMap *NewMap(PType *keytype, PType *valuetype);
|
|
|
|
PArray *NewArray(PType *type, unsigned int count);
|
2017-01-02 20:40:52 +00:00
|
|
|
PResizableArray *NewResizableArray(PType *type);
|
2016-03-01 15:47:10 +00:00
|
|
|
PDynArray *NewDynArray(PType *type);
|
2016-11-05 12:51:46 +00:00
|
|
|
PPointer *NewPointer(PType *type, bool isconst = false);
|
2016-03-01 15:47:10 +00:00
|
|
|
PClassPointer *NewClassPointer(PClass *restrict);
|
2016-10-07 11:59:29 +00:00
|
|
|
PEnum *NewEnum(FName name, PTypeBase *outer);
|
|
|
|
PStruct *NewStruct(FName name, PTypeBase *outer);
|
2016-11-21 18:20:27 +00:00
|
|
|
PNativeStruct *NewNativeStruct(FName name, PTypeBase *outer);
|
2016-03-01 15:47:10 +00:00
|
|
|
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
|
|
|
|
|
|
|
|
// Built-in types -----------------------------------------------------------
|
|
|
|
|
|
|
|
extern PErrorType *TypeError;
|
2016-12-05 12:24:42 +00:00
|
|
|
extern PErrorType *TypeAuto;
|
2016-03-01 15:47:10 +00:00
|
|
|
extern PVoidType *TypeVoid;
|
|
|
|
extern PInt *TypeSInt8, *TypeUInt8;
|
|
|
|
extern PInt *TypeSInt16, *TypeUInt16;
|
|
|
|
extern PInt *TypeSInt32, *TypeUInt32;
|
|
|
|
extern PBool *TypeBool;
|
|
|
|
extern PFloat *TypeFloat32, *TypeFloat64;
|
|
|
|
extern PString *TypeString;
|
|
|
|
extern PName *TypeName;
|
|
|
|
extern PSound *TypeSound;
|
|
|
|
extern PColor *TypeColor;
|
2016-11-21 12:45:33 +00:00
|
|
|
extern PTextureID *TypeTextureID;
|
|
|
|
extern PSpriteID *TypeSpriteID;
|
2016-10-09 13:47:31 +00:00
|
|
|
extern PStruct *TypeVector2;
|
|
|
|
extern PStruct *TypeVector3;
|
2016-11-21 11:38:39 +00:00
|
|
|
extern PStruct *TypeColorStruct;
|
2016-11-28 17:15:18 +00:00
|
|
|
extern PStruct *TypeStringStruct;
|
2016-03-01 15:47:10 +00:00
|
|
|
extern PStatePointer *TypeState;
|
2017-02-05 12:14:22 +00:00
|
|
|
extern PPointer *TypeFont;
|
2016-11-14 13:12:27 +00:00
|
|
|
extern PStateLabel *TypeStateLabel;
|
2016-10-21 17:18:39 +00:00
|
|
|
extern PPointer *TypeNullPtr;
|
2017-01-10 23:57:31 +00:00
|
|
|
extern PPointer *TypeVoidPtr;
|
2016-03-01 15:47:10 +00:00
|
|
|
|
2017-01-23 18:09:36 +00:00
|
|
|
// Enumerations for serializing types in an archive -------------------------
|
|
|
|
|
2017-01-19 22:42:12 +00:00
|
|
|
inline bool &DObject::BoolVar(FName field)
|
|
|
|
{
|
|
|
|
return *(bool*)ScriptVar(field, TypeBool);
|
|
|
|
}
|
|
|
|
|
2017-01-15 15:55:30 +00:00
|
|
|
inline int &DObject::IntVar(FName field)
|
|
|
|
{
|
|
|
|
return *(int*)ScriptVar(field, TypeSInt32);
|
|
|
|
}
|
|
|
|
|
2017-02-28 12:40:46 +00:00
|
|
|
inline FSoundID &DObject::SoundVar(FName field)
|
|
|
|
{
|
|
|
|
return *(FSoundID*)ScriptVar(field, TypeSound);
|
|
|
|
}
|
|
|
|
|
2017-01-18 09:33:03 +00:00
|
|
|
inline PalEntry &DObject::ColorVar(FName field)
|
|
|
|
{
|
|
|
|
return *(PalEntry*)ScriptVar(field, TypeColor);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline FName &DObject::NameVar(FName field)
|
|
|
|
{
|
|
|
|
return *(FName*)ScriptVar(field, TypeName);
|
|
|
|
}
|
|
|
|
|
2017-01-15 15:55:30 +00:00
|
|
|
inline double &DObject::FloatVar(FName field)
|
|
|
|
{
|
|
|
|
return *(double*)ScriptVar(field, TypeFloat64);
|
|
|
|
}
|
|
|
|
|
2017-02-27 23:45:16 +00:00
|
|
|
inline FString &DObject::StringVar(FName field)
|
|
|
|
{
|
|
|
|
return *(FString*)ScriptVar(field, TypeString);
|
|
|
|
}
|
|
|
|
|
2017-01-18 17:46:24 +00:00
|
|
|
template<class T>
|
|
|
|
inline T *&DObject::PointerVar(FName field)
|
|
|
|
{
|
|
|
|
return *(T**)ScriptVar(field, nullptr); // pointer check is more tricky and for the handful of uses in the DECORATE parser not worth the hassle.
|
|
|
|
}
|
2017-01-24 10:57:42 +00:00
|
|
|
|
|
|
|
void RemoveUnusedSymbols();
|
|
|
|
|
2016-03-01 15:47:10 +00:00
|
|
|
#endif
|