2016-11-11 23:33:40 +00:00
// Templates really are powerful
# define VMEXPORTED_NATIVES_START \
template < class owner > class ExportedNatives : public ExportedNatives < typename owner : : Super > { } ; \
template < > class ExportedNatives < void > { \
protected : ExportedNatives < void > ( ) { } \
public : \
static ExportedNatives < void > * Get ( ) { static ExportedNatives < void > * Instance = nullptr ; if ( Instance = = nullptr ) Instance = new ExportedNatives < void > ; return Instance ; } \
ExportedNatives < void > ( const ExportedNatives < void > & ) = delete ; \
ExportedNatives < void > ( ExportedNatives < void > & & ) = delete ;
# define VMEXPORTED_NATIVES_FUNC(func) \
template < class ret , class object , class . . . args > ret func ( void * ptr , args . . . arglist ) { return ret ( ) ; }
# define VMEXPORTED_NATIVES_END };
# define VMEXPORT_NATIVES_START(cls, parent) \
template < > class ExportedNatives < cls > : public ExportedNatives < parent > { \
protected : ExportedNatives < cls > ( ) { } \
public : \
static ExportedNatives < cls > * Get ( ) { static ExportedNatives < cls > * Instance = nullptr ; if ( Instance = = nullptr ) Instance = new ExportedNatives < cls > ; return Instance ; } \
ExportedNatives < cls > ( const ExportedNatives < cls > & ) = delete ; \
ExportedNatives < cls > ( ExportedNatives < cls > & & ) = delete ;
# define VMEXPORT_NATIVES_FUNC(func) \
template < class ret , class object , class . . . args > ret func ( void * ptr , args . . . arglist ) { return static_cast < object * > ( ptr ) - > object : : func ( arglist . . . ) ; }
# define VMEXPORT_NATIVES_END(cls) };
//Initial list
VMEXPORTED_NATIVES_START
VMEXPORTED_NATIVES_FUNC ( Destroy )
VMEXPORTED_NATIVES_FUNC ( Tick )
2016-11-11 23:57:21 +00:00
VMEXPORTED_NATIVES_FUNC ( PostBeginPlay )
2016-11-21 13:59:17 +00:00
VMEXPORTED_NATIVES_FUNC ( BeginPlay )
VMEXPORTED_NATIVES_FUNC ( Activate )
VMEXPORTED_NATIVES_FUNC ( Deactivate )
2016-11-23 20:26:59 +00:00
VMEXPORTED_NATIVES_FUNC ( DoSpecialDamage )
2016-11-24 12:45:43 +00:00
VMEXPORTED_NATIVES_FUNC ( UseInventory )
2016-11-11 23:33:40 +00:00
VMEXPORTED_NATIVES_END
2016-11-19 12:56:29 +00:00
inline int GetVirtualIndex ( PClass * cls , const char * funcname )
{
// Look up the virtual function index in the defining class because this may have gotten overloaded in subclasses with something different than a virtual override.
auto sym = dyn_cast < PFunction > ( cls - > Symbols . FindSymbol ( funcname , false ) ) ;
assert ( sym ! = nullptr ) ;
auto VIndex = sym - > Variants [ 0 ] . Implementation - > VirtualIndex ;
assert ( VIndex > = 0 ) ;
return VIndex ;
}
2016-11-21 13:59:17 +00:00
# define VINDEX(cls, funcname) \
static int VIndex = - 1 ; \
if ( VIndex < 0 ) { \
VIndex = GetVirtualIndex ( RUNTIME_CLASS ( cls ) , # funcname ) ; \
2016-11-21 18:09:58 +00:00
if ( VIndex < 0 ) I_Error ( " Unable to find virtual function %s in " # cls , # funcname ) ; \
2016-11-21 13:59:17 +00:00
}
# define VFUNC this->GetClass()->Virtuals[VIndex]
2016-11-11 23:33:40 +00:00
template < class T >
class DVMObject : public T
{
public :
static char * FormatClassName ( )
{
static char * name = nullptr ;
if ( name = = nullptr )
{
name = new char [ 64 ] ;
mysnprintf ( name , 64 , " DVMObject<%s> " , Super : : RegistrationInfo . Name ) ;
atterm ( [ ] { delete [ ] DVMObject < T > : : RegistrationInfo . Name ; } ) ;
}
return name ;
}
virtual PClass * StaticType ( ) const
{
return RegistrationInfo . MyClass ;
}
static ClassReg RegistrationInfo ;
static ClassReg * const RegistrationInfoPtr ;
typedef T Super ;
private :
typedef DVMObject < T > ThisClass ;
static void InPlaceConstructor ( void * mem )
{
new ( ( EInPlace * ) mem ) DVMObject < T > ;
}
public :
void Destroy ( )
{
2016-11-11 23:57:21 +00:00
if ( this - > ObjectFlags & OF_SuperCall )
2016-11-11 23:33:40 +00:00
{
2016-11-21 13:59:17 +00:00
this - > ObjectFlags & = ~ OF_SuperCall ;
2016-11-11 23:33:40 +00:00
ExportedNatives < T > : : Get ( ) - > template Destroy < void , T > ( this ) ;
}
else
{
2016-11-21 13:59:17 +00:00
VINDEX ( DObject , Destroy ) ;
2016-11-11 23:33:40 +00:00
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 1 ] = { ( DObject * ) this } ;
VMFrameStack stack ;
2016-11-21 13:59:17 +00:00
stack . Call ( VFUNC , params , 1 , nullptr , 0 , nullptr ) ;
2016-11-11 23:33:40 +00:00
}
}
void Tick ( )
{
2016-11-21 13:59:17 +00:00
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
ExportedNatives < T > : : Get ( ) - > template Tick < void , T > ( this ) ;
}
else
{
VINDEX ( DThinker , Tick ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 1 ] = { ( DObject * ) this } ;
VMFrameStack stack ;
stack . Call ( VFUNC , params , 1 , nullptr , 0 , nullptr ) ;
}
2016-11-11 23:33:40 +00:00
}
2016-11-11 23:57:21 +00:00
void PostBeginPlay ( )
{
2016-11-21 13:59:17 +00:00
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
ExportedNatives < T > : : Get ( ) - > template PostBeginPlay < void , T > ( this ) ;
}
else
{
VINDEX ( DThinker , PostBeginPlay ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 1 ] = { ( DObject * ) this } ;
VMFrameStack stack ;
stack . Call ( VFUNC , params , 1 , nullptr , 0 , nullptr ) ;
}
2016-11-11 23:57:21 +00:00
}
2016-11-21 13:59:17 +00:00
void BeginPlay ( )
{
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
ExportedNatives < T > : : Get ( ) - > template BeginPlay < void , T > ( this ) ;
}
else
{
VINDEX ( AActor , BeginPlay ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 1 ] = { ( DObject * ) this } ;
VMFrameStack stack ;
stack . Call ( VFUNC , params , 1 , nullptr , 0 , nullptr ) ;
}
}
void Activate ( AActor * activator )
{
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
ExportedNatives < T > : : Get ( ) - > template Activate < void , T > ( this , activator ) ;
}
else
{
VINDEX ( AActor , Activate ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 2 ] = { ( DObject * ) this , ( DObject * ) activator } ;
VMFrameStack stack ;
stack . Call ( VFUNC , params , 2 , nullptr , 0 , nullptr ) ;
}
}
void Deactivate ( AActor * activator )
{
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
ExportedNatives < T > : : Get ( ) - > template Deactivate < void , T > ( this , activator ) ;
}
else
{
VINDEX ( AActor , Deactivate ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 2 ] = { ( DObject * ) this , ( DObject * ) activator } ;
VMFrameStack stack ;
stack . Call ( VFUNC , params , 2 , nullptr , 0 , nullptr ) ;
}
}
2016-11-23 20:26:59 +00:00
int DoSpecialDamage ( AActor * target , int damage , FName damagetype )
{
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
return ExportedNatives < T > : : Get ( ) - > template DoSpecialDamage < int , T > ( this , target , damage , damagetype ) ;
}
else
{
VINDEX ( AActor , DoSpecialDamage ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 4 ] = { ( DObject * ) this , ( DObject * ) target , damage , damagetype . GetIndex ( ) } ;
VMReturn ret ;
VMFrameStack stack ;
int retval ;
ret . IntAt ( & retval ) ;
stack . Call ( VFUNC , params , 4 , & ret , 1 , nullptr ) ;
return retval ;
}
}
2016-11-24 12:45:43 +00:00
bool UseInventory ( AInventory * item )
{
if ( this - > ObjectFlags & OF_SuperCall )
{
this - > ObjectFlags & = ~ OF_SuperCall ;
return ExportedNatives < T > : : Get ( ) - > template UseInventory < bool , T > ( this , item ) ;
}
else
{
VINDEX ( AActor , UseInventory ) ;
// Without the type cast this picks the 'void *' assignment...
VMValue params [ 2 ] = { ( DObject * ) this , ( DObject * ) item } ;
VMReturn ret ;
VMFrameStack stack ;
int retval ;
ret . IntAt ( & retval ) ;
stack . Call ( VFUNC , params , 2 , & ret , 1 , nullptr ) ;
return ! ! retval ;
}
}
2016-11-21 13:59:17 +00:00
2016-11-11 23:33:40 +00:00
} ;
template < class T >
ClassReg DVMObject < T > : : RegistrationInfo =
{
nullptr ,
DVMObject < T > : : FormatClassName ( ) ,
& DVMObject < T > : : Super : : RegistrationInfo ,
nullptr ,
nullptr ,
DVMObject < T > : : InPlaceConstructor ,
nullptr ,
sizeof ( DVMObject < T > ) ,
DVMObject < T > : : MetaClassNum
} ;
template < class T > _DECLARE_TI ( DVMObject < T > )
VMEXPORT_NATIVES_START ( DObject , void )
VMEXPORT_NATIVES_FUNC ( Destroy )
VMEXPORT_NATIVES_END ( DObject )
VMEXPORT_NATIVES_START ( DThinker , DObject )
VMEXPORT_NATIVES_FUNC ( Tick )
2016-11-11 23:57:21 +00:00
VMEXPORT_NATIVES_FUNC ( PostBeginPlay )
2016-11-21 13:59:17 +00:00
VMEXPORT_NATIVES_END ( DThinker )
VMEXPORT_NATIVES_START ( AActor , DThinker )
VMEXPORT_NATIVES_FUNC ( BeginPlay )
VMEXPORT_NATIVES_FUNC ( Activate )
VMEXPORT_NATIVES_FUNC ( Deactivate )
2016-11-23 20:26:59 +00:00
VMEXPORT_NATIVES_FUNC ( DoSpecialDamage )
2016-11-24 12:45:43 +00:00
VMEXPORT_NATIVES_FUNC ( UseInventory )
2016-11-21 13:59:17 +00:00
VMEXPORT_NATIVES_END ( AActor )
2016-11-11 23:33:40 +00:00
2016-11-12 08:33:43 +00:00
/*
2016-11-11 23:33:40 +00:00
VMEXPORT_NATIVES_START ( AActor , DThinker )
VMEXPORT_NATIVES_END ( AActor )
2016-11-22 20:16:13 +00:00
*/