Provide a way to expose a native class to zscript for virtual functions overriding

This commit is contained in:
Leonard2 2016-11-06 11:28:01 +01:00
parent ad19e439a6
commit 33e2c74642
4 changed files with 24 additions and 13 deletions

View File

@ -57,14 +57,15 @@
ClassReg DObject::RegistrationInfo = ClassReg DObject::RegistrationInfo =
{ {
NULL, // MyClass nullptr, // MyClass
"DObject", // Name "DObject", // Name
NULL, // ParentType nullptr, // ParentType
NULL, // Pointers &DVMObject<DObject>::RegistrationInfo, // VMExport
&DObject::InPlaceConstructor, // ConstructNative nullptr, // Pointers
&DObject::InitNativeFields, &DObject::InPlaceConstructor, // ConstructNative
sizeof(DObject), // SizeOf &DObject::InitNativeFields, // InitNatives
CLASSREG_PClass, // MetaClassNum sizeof(DObject), // SizeOf
CLASSREG_PClass, // MetaClassNum
}; };
_DECLARE_TI(DObject) _DECLARE_TI(DObject)

View File

@ -109,6 +109,7 @@ struct ClassReg
PClass *MyClass; PClass *MyClass;
const char *Name; const char *Name;
ClassReg *ParentType; ClassReg *ParentType;
ClassReg *VMExport;
const size_t *Pointers; const size_t *Pointers;
void (*ConstructNative)(void *); void (*ConstructNative)(void *);
void(*InitNatives)(); void(*InitNatives)();
@ -186,11 +187,12 @@ protected: \
# define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo; # define _DECLARE_TI(cls) ClassReg * const cls::RegistrationInfoPtr __attribute__((section(SECTION_CREG))) = &cls::RegistrationInfo;
#endif #endif
#define _IMP_PCLASS(cls, ptrs, create, initn) \ #define _IMP_PCLASS(cls, ptrs, create, initn, vmexport) \
ClassReg cls::RegistrationInfo = {\ ClassReg cls::RegistrationInfo = {\
nullptr, \ nullptr, \
#cls, \ #cls, \
&cls::Super::RegistrationInfo, \ &cls::Super::RegistrationInfo, \
vmexport, \
ptrs, \ ptrs, \
create, \ create, \
initn, \ initn, \
@ -199,9 +201,9 @@ protected: \
_DECLARE_TI(cls) \ _DECLARE_TI(cls) \
PClass *cls::StaticType() const { return RegistrationInfo.MyClass; } PClass *cls::StaticType() const { return RegistrationInfo.MyClass; }
#define IMPLEMENT_CLASS(cls, isabstract, ptrs, fields) \ #define IMPLEMENT_CLASS(cls, isabstract, ptrs, fields, vmexport) \
_X_CONSTRUCTOR_##isabstract##(cls) \ _X_CONSTRUCTOR_##isabstract##(cls) \
_IMP_PCLASS(cls, _X_POINTERS_##ptrs##(cls), _X_ABSTRACT_##isabstract##(cls), _X_FIELDS_##fields##(cls)) _IMP_PCLASS(cls, _X_POINTERS_##ptrs##(cls), _X_ABSTRACT_##isabstract##(cls), _X_FIELDS_##fields##(cls), _X_VMEXPORT_##vmexport##(cls))
// Taking the address of a field in an object at address 1 instead of // Taking the address of a field in an object at address 1 instead of
// address 0 keeps GCC from complaining about possible misuse of offsetof. // address 0 keeps GCC from complaining about possible misuse of offsetof.
@ -218,6 +220,8 @@ protected: \
#define _X_CONSTRUCTOR_false(cls) void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; } #define _X_CONSTRUCTOR_false(cls) void cls::InPlaceConstructor(void *mem) { new((EInPlace *)mem) cls; }
#define _X_ABSTRACT_true(cls) nullptr #define _X_ABSTRACT_true(cls) nullptr
#define _X_ABSTRACT_false(cls) cls::InPlaceConstructor #define _X_ABSTRACT_false(cls) cls::InPlaceConstructor
#define _X_VMEXPORT_true(cls) &DVMObject<cls>::RegistrationInfo
#define _X_VMEXPORT_false(cls) nullptr
enum EObjectFlags enum EObjectFlags
{ {
@ -643,6 +647,7 @@ ClassReg DVMObject<T>::RegistrationInfo =
DVMObject<T>::FormatClassName(), DVMObject<T>::FormatClassName(),
&DVMObject<T>::Super::RegistrationInfo, &DVMObject<T>::Super::RegistrationInfo,
nullptr, nullptr,
nullptr,
DVMObject<T>::InPlaceConstructor, DVMObject<T>::InPlaceConstructor,
nullptr, nullptr,
sizeof(DVMObject<T>), sizeof(DVMObject<T>),

View File

@ -2847,7 +2847,7 @@ PClass *ClassReg::RegisterClass()
assert(0 && "Class registry has an invalid meta class identifier"); assert(0 && "Class registry has an invalid meta class identifier");
} }
if (metaclasses[MetaClassNum]->MyClass == NULL) if (metaclasses[MetaClassNum]->MyClass == nullptr)
{ // Make sure the meta class is already registered before registering this one { // Make sure the meta class is already registered before registering this one
metaclasses[MetaClassNum]->RegisterClass(); metaclasses[MetaClassNum]->RegisterClass();
} }
@ -2855,10 +2855,14 @@ PClass *ClassReg::RegisterClass()
SetupClass(cls); SetupClass(cls);
cls->InsertIntoHash(); cls->InsertIntoHash();
if (ParentType != NULL) if (ParentType != nullptr)
{ {
cls->ParentClass = ParentType->RegisterClass(); cls->ParentClass = ParentType->RegisterClass();
} }
if (VMExport != nullptr)
{
cls->VMExported = VMExport->RegisterClass();
}
return cls; return cls;
} }

View File

@ -769,6 +769,7 @@ public:
// Per-class information ------------------------------------- // Per-class information -------------------------------------
PClass *ParentClass; // the class this class derives from PClass *ParentClass; // the class this class derives from
PClass *VMExported; // this is here to allow script classes to override native virtual functions
const size_t *Pointers; // object pointers defined by this class *only* 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 const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default
BYTE *Defaults; BYTE *Defaults;