2017-01-22 00:33:53 +00:00
# include "events.h"
# include "virtual.h"
# include "r_utility.h"
2017-01-22 07:36:39 +00:00
# include "g_levellocals.h"
2017-01-22 07:58:48 +00:00
# include "gi.h"
2017-01-22 07:36:39 +00:00
# include "v_text.h"
2017-01-22 00:33:53 +00:00
2017-01-22 06:56:57 +00:00
DStaticEventHandler * E_FirstEventHandler = nullptr ;
2017-01-22 00:33:53 +00:00
2017-01-22 06:56:57 +00:00
bool E_RegisterHandler ( DStaticEventHandler * handler )
2017-01-22 00:33:53 +00:00
{
if ( handler = = nullptr | | handler - > ObjectFlags & OF_EuthanizeMe )
2017-01-22 06:56:57 +00:00
return false ;
if ( E_CheckHandler ( handler ) )
return false ;
2017-01-22 00:33:53 +00:00
// link into normal list
handler - > prev = nullptr ;
2017-01-22 00:56:15 +00:00
handler - > next = E_FirstEventHandler ;
2017-01-22 00:33:53 +00:00
if ( handler - > next )
handler - > next - > prev = handler ;
2017-01-22 00:56:15 +00:00
E_FirstEventHandler = handler ;
2017-01-22 07:39:33 +00:00
if ( handler - > IsStatic ( ) & & ! handler - > isMapScope ) handler - > ObjectFlags | = OF_Fixed ;
2017-01-22 06:56:57 +00:00
return true ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 06:56:57 +00:00
bool E_UnregisterHandler ( DStaticEventHandler * handler )
2017-01-22 00:33:53 +00:00
{
if ( handler = = nullptr | | handler - > ObjectFlags & OF_EuthanizeMe )
2017-01-22 06:56:57 +00:00
return false ;
if ( ! E_CheckHandler ( handler ) )
return false ;
2017-01-22 00:33:53 +00:00
// link out of normal list
if ( handler - > prev )
handler - > prev - > next = handler - > next ;
if ( handler - > next )
handler - > next - > prev = handler - > prev ;
2017-01-22 00:56:15 +00:00
if ( handler = = E_FirstEventHandler )
E_FirstEventHandler = handler - > next ;
2017-01-22 07:39:33 +00:00
if ( handler - > IsStatic ( ) & & ! handler - > isMapScope )
2017-01-22 06:58:59 +00:00
{
handler - > ObjectFlags | = OF_YesReallyDelete ;
delete handler ;
}
2017-01-22 06:56:57 +00:00
return true ;
}
bool E_CheckHandler ( DStaticEventHandler * handler )
{
for ( DStaticEventHandler * lhandler = E_FirstEventHandler ; lhandler ; lhandler = lhandler - > next )
if ( handler = = lhandler ) return true ;
return false ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 07:36:39 +00:00
bool E_IsStaticType ( PClass * type )
{
return ( ! type - > IsDescendantOf ( RUNTIME_CLASS ( DEventHandler ) ) & &
! type - > IsDescendantOf ( RUNTIME_CLASS ( DRenderEventHandler ) ) ) ;
}
2017-01-22 07:58:48 +00:00
static void E_InitStaticHandler ( PClass * type , FString typestring , bool map )
{
if ( type = = nullptr )
{
Printf ( " %cGWarning: unknown event handler class %s in MAPINFO! " , TEXTCOLOR_ESCAPE , typestring . GetChars ( ) ) ;
return ;
}
if ( ! E_IsStaticType ( type ) )
{
Printf ( " %cGWarning: invalid event handler class %s in MAPINFO! \n MAPINFO event handlers should inherit Static* directly! " , TEXTCOLOR_ESCAPE , typestring . GetChars ( ) ) ;
return ;
}
// check if type already exists, don't add twice.
bool typeExists = false ;
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
{
if ( handler - > IsA ( type ) )
{
typeExists = true ;
break ;
}
}
if ( typeExists ) return ;
DStaticEventHandler * handler = ( DStaticEventHandler * ) type - > CreateNew ( ) ;
handler - > isMapScope = map ;
E_RegisterHandler ( handler ) ;
}
2017-01-22 07:36:39 +00:00
void E_InitStaticHandlers ( bool map )
{
// remove existing
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
{
if ( handler - > IsStatic ( ) & & handler - > isMapScope = = map )
handler - > Destroy ( ) ;
}
// add new
if ( map )
{
for ( unsigned int i = 0 ; i < level . info - > EventHandlers . Size ( ) ; i + + )
{
FString typestring = level . info - > EventHandlers [ i ] ;
PClass * type = PClass : : FindClass ( typestring ) ;
2017-01-22 07:58:48 +00:00
E_InitStaticHandler ( type , typestring , true ) ;
2017-01-22 07:36:39 +00:00
}
}
else
{
2017-01-22 07:58:48 +00:00
for ( unsigned int i = 0 ; i < gameinfo . EventHandlers . Size ( ) ; i + + )
{
FString typestring = gameinfo . EventHandlers [ i ] ;
PClass * type = PClass : : FindClass ( typestring ) ;
E_InitStaticHandler ( type , typestring , false ) ;
}
2017-01-22 07:36:39 +00:00
}
}
2017-01-22 00:33:53 +00:00
void E_MapLoaded ( )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:33:53 +00:00
handler - > MapLoaded ( ) ;
}
void E_MapUnloading ( )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:33:53 +00:00
handler - > MapUnloading ( ) ;
}
void E_RenderFrame ( )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:33:53 +00:00
handler - > RenderFrame ( ) ;
}
void E_RenderCamera ( )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:33:53 +00:00
handler - > RenderCamera ( ) ;
}
2017-01-22 05:04:35 +00:00
void E_RenderBeforeThing ( AActor * thing )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 05:04:35 +00:00
handler - > RenderBeforeThing ( thing ) ;
}
void E_RenderAfterThing ( AActor * thing )
{
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 05:04:35 +00:00
handler - > RenderAfterThing ( thing ) ;
}
2017-01-22 00:33:53 +00:00
// declarations
2017-01-22 06:56:57 +00:00
IMPLEMENT_CLASS ( DStaticEventHandler , false , false ) ;
IMPLEMENT_CLASS ( DStaticRenderEventHandler , false , false ) ;
2017-01-22 00:33:53 +00:00
IMPLEMENT_CLASS ( DEventHandler , false , false ) ;
IMPLEMENT_CLASS ( DRenderEventHandler , false , false ) ;
2017-01-22 06:56:57 +00:00
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , ViewPos ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , ViewAngle ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , ViewPitch ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , ViewRoll ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , FracTic ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , Camera ) ;
DEFINE_FIELD_X ( StaticRenderEventHandler , DStaticRenderEventHandler , CurrentThing ) ;
2017-01-22 00:33:53 +00:00
DEFINE_ACTION_FUNCTION ( DEventHandler , Create )
{
PARAM_PROLOGUE ;
2017-01-22 06:56:57 +00:00
PARAM_CLASS ( t , DStaticEventHandler ) ;
// check if type inherits dynamic handlers
2017-01-22 07:36:39 +00:00
if ( E_IsStaticType ( t ) )
2017-01-22 06:56:57 +00:00
{
// disallow static types creation with Create()
ACTION_RETURN_OBJECT ( nullptr ) ;
}
2017-01-22 00:33:53 +00:00
// generate a new object of this type.
ACTION_RETURN_OBJECT ( t - > CreateNew ( ) ) ;
}
2017-01-22 00:56:15 +00:00
DEFINE_ACTION_FUNCTION ( DEventHandler , CreateOnce )
{
PARAM_PROLOGUE ;
2017-01-22 06:56:57 +00:00
PARAM_CLASS ( t , DStaticEventHandler ) ;
// check if type inherits dynamic handlers
2017-01-22 07:36:39 +00:00
if ( E_IsStaticType ( t ) )
2017-01-22 06:56:57 +00:00
{
// disallow static types creation with Create()
ACTION_RETURN_OBJECT ( nullptr ) ;
}
2017-01-22 00:56:15 +00:00
// check if there are already registered handlers of this type.
2017-01-22 06:56:57 +00:00
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:56:15 +00:00
if ( handler - > GetClass ( ) = = t ) // check precise class
ACTION_RETURN_OBJECT ( nullptr ) ;
// generate a new object of this type.
ACTION_RETURN_OBJECT ( t - > CreateNew ( ) ) ;
}
DEFINE_ACTION_FUNCTION ( DEventHandler , Find )
{
PARAM_PROLOGUE ;
2017-01-22 06:56:57 +00:00
PARAM_CLASS ( t , DStaticEventHandler ) ;
for ( DStaticEventHandler * handler = E_FirstEventHandler ; handler ; handler = handler - > next )
2017-01-22 00:56:15 +00:00
if ( handler - > GetClass ( ) = = t ) // check precise class
ACTION_RETURN_OBJECT ( handler ) ;
ACTION_RETURN_OBJECT ( nullptr ) ;
}
2017-01-22 00:33:53 +00:00
DEFINE_ACTION_FUNCTION ( DEventHandler , Register )
{
PARAM_PROLOGUE ;
2017-01-22 06:56:57 +00:00
PARAM_OBJECT ( handler , DStaticEventHandler ) ;
if ( handler - > IsStatic ( ) ) ACTION_RETURN_BOOL ( false ) ;
ACTION_RETURN_BOOL ( E_RegisterHandler ( handler ) ) ;
2017-01-22 00:33:53 +00:00
}
DEFINE_ACTION_FUNCTION ( DEventHandler , Unregister )
{
PARAM_PROLOGUE ;
2017-01-22 06:56:57 +00:00
PARAM_OBJECT ( handler , DStaticEventHandler ) ;
if ( handler - > IsStatic ( ) ) ACTION_RETURN_BOOL ( false ) ;
ACTION_RETURN_BOOL ( E_UnregisterHandler ( handler ) ) ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 05:04:35 +00:00
# define DEFINE_EVENT_HANDLER(cls, funcname, args) DEFINE_ACTION_FUNCTION(cls, funcname) \
2017-01-22 04:23:44 +00:00
{ \
PARAM_SELF_PROLOGUE ( cls ) ; \
return 0 ; \
} \
2017-01-22 05:04:35 +00:00
void cls : : funcname ( args ) \
2017-01-22 04:23:44 +00:00
{ \
IFVIRTUAL ( cls , funcname ) \
{ \
if ( func = = cls # # _ # # funcname # # _VMPtr ) \
return ; \
VMValue params [ 1 ] = { ( cls * ) this } ; \
GlobalVMStack . Call ( func , params , 1 , nullptr , 0 , nullptr ) ; \
} \
}
2017-01-22 06:56:57 +00:00
DEFINE_EVENT_HANDLER ( DStaticEventHandler , MapLoaded , )
DEFINE_EVENT_HANDLER ( DStaticEventHandler , MapUnloading , )
DEFINE_EVENT_HANDLER ( DStaticEventHandler , RenderFrame , )
DEFINE_EVENT_HANDLER ( DStaticEventHandler , RenderCamera , )
DEFINE_EVENT_HANDLER ( DStaticEventHandler , RenderBeforeThing , AActor * )
DEFINE_EVENT_HANDLER ( DStaticEventHandler , RenderAfterThing , AActor * )
2017-01-22 00:33:53 +00:00
//
2017-01-22 06:56:57 +00:00
void DStaticEventHandler : : OnDestroy ( )
2017-01-22 00:33:53 +00:00
{
E_UnregisterHandler ( this ) ;
DObject : : OnDestroy ( ) ;
}
2017-01-22 06:56:57 +00:00
void DStaticRenderEventHandler : : Setup ( )
2017-01-22 00:33:53 +00:00
{
ViewPos = : : ViewPos ;
ViewAngle = : : ViewAngle ;
ViewPitch = : : ViewPitch ;
ViewRoll = : : ViewRoll ;
FracTic = : : r_TicFracF ;
2017-01-22 05:04:35 +00:00
Camera = : : camera ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 06:56:57 +00:00
void DStaticRenderEventHandler : : RenderFrame ( )
2017-01-22 00:33:53 +00:00
{
Setup ( ) ;
2017-01-22 06:56:57 +00:00
DStaticEventHandler : : RenderFrame ( ) ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 06:56:57 +00:00
void DStaticRenderEventHandler : : RenderCamera ( )
2017-01-22 00:33:53 +00:00
{
Setup ( ) ;
2017-01-22 06:56:57 +00:00
DStaticEventHandler : : RenderCamera ( ) ;
2017-01-22 00:33:53 +00:00
}
2017-01-22 05:04:35 +00:00
2017-01-22 06:56:57 +00:00
void DStaticRenderEventHandler : : RenderBeforeThing ( AActor * thing )
2017-01-22 05:04:35 +00:00
{
CurrentThing = thing ;
2017-01-22 06:56:57 +00:00
DStaticEventHandler : : RenderBeforeThing ( thing ) ;
2017-01-22 05:04:35 +00:00
}
2017-01-22 06:56:57 +00:00
void DStaticRenderEventHandler : : RenderAfterThing ( AActor * thing )
2017-01-22 05:04:35 +00:00
{
CurrentThing = thing ;
2017-01-22 06:56:57 +00:00
DStaticEventHandler : : RenderAfterThing ( thing ) ;
2017-01-22 05:04:35 +00:00
}