2021-05-10 22:48:41 +00:00
# include "EventHandler.h"
2021-05-10 23:54:48 +00:00
2021-05-11 05:46:53 +00:00
# include "../plugin-macros.generated.h"
2021-05-14 02:11:19 +00:00
std : : string GetCalldataString ( const calldata_t * data , const char * name )
{
2021-05-14 08:13:27 +00:00
const char * value = calldata_string ( data , name ) ;
if ( ! value )
return " " ;
2021-05-14 02:11:19 +00:00
return value ;
}
2021-05-10 23:54:48 +00:00
EventHandler : : EventHandler ( WebSocketServerPtr webSocketServer ) :
2021-05-14 08:13:27 +00:00
_webSocketServer ( webSocketServer ) ,
_obsLoaded ( false )
2021-05-10 23:54:48 +00:00
{
2021-05-11 05:46:53 +00:00
blog ( LOG_INFO , " [EventHandler::EventHandler] Setting up event handlers... " ) ;
2021-05-10 23:54:48 +00:00
_cpuUsageInfo = os_cpu_usage_info_start ( ) ;
2021-05-14 08:13:27 +00:00
obs_frontend_add_event_callback ( OnFrontendEvent , this ) ;
2021-05-11 05:46:53 +00:00
signal_handler_t * coreSignalHandler = obs_get_signal_handler ( ) ;
if ( coreSignalHandler ) {
2021-05-14 02:11:19 +00:00
signal_handler_connect ( coreSignalHandler , " source_create " , SourceCreatedMultiHandler , this ) ;
2021-05-14 08:13:27 +00:00
signal_handler_connect ( coreSignalHandler , " source_destroy " , SourceDestroyedMultiHandler , this ) ;
2021-05-14 02:11:19 +00:00
signal_handler_connect ( coreSignalHandler , " source_remove " , SourceRemovedMultiHandler , this ) ;
2021-05-14 08:13:27 +00:00
signal_handler_connect ( coreSignalHandler , " source_rename " , SourceRenamedMultiHandler , this ) ;
} else {
blog ( LOG_ERROR , " [EventHandler::EventHandler] Unable to get libobs signal handler! " ) ;
2021-05-11 05:46:53 +00:00
}
blog ( LOG_INFO , " [EventHandler::EventHandler] Finished. " ) ;
2021-05-10 23:54:48 +00:00
}
EventHandler : : ~ EventHandler ( )
{
2021-05-11 05:46:53 +00:00
blog ( LOG_INFO , " [EventHandler::~EventHandler] Removing event handlers... " ) ;
2021-05-10 23:54:48 +00:00
os_cpu_usage_info_destroy ( _cpuUsageInfo ) ;
2021-05-14 08:13:27 +00:00
obs_frontend_remove_event_callback ( OnFrontendEvent , this ) ;
2021-05-11 05:46:53 +00:00
signal_handler_t * coreSignalHandler = obs_get_signal_handler ( ) ;
if ( coreSignalHandler ) {
2021-05-14 08:13:27 +00:00
signal_handler_disconnect ( coreSignalHandler , " source_create " , SourceCreatedMultiHandler , this ) ;
signal_handler_disconnect ( coreSignalHandler , " source_destroy " , SourceDestroyedMultiHandler , this ) ;
2021-05-14 02:11:19 +00:00
signal_handler_disconnect ( coreSignalHandler , " source_remove " , SourceRemovedMultiHandler , this ) ;
2021-05-14 08:13:27 +00:00
signal_handler_disconnect ( coreSignalHandler , " source_rename " , SourceRenamedMultiHandler , this ) ;
} else {
blog ( LOG_ERROR , " [EventHandler::~EventHandler] Unable to get libobs signal handler! " ) ;
2021-05-11 05:46:53 +00:00
}
blog ( LOG_INFO , " [EventHandler::~EventHandler] Finished. " ) ;
2021-05-10 23:54:48 +00:00
}
2021-05-14 08:13:27 +00:00
void EventHandler : : ConnectSourceSignals ( obs_source_t * source ) // These signals are only reliably connected to inputs.
2021-05-11 05:46:53 +00:00
{
if ( ! source | | obs_source_removed ( source ) )
return ;
DisconnectSourceSignals ( source ) ;
signal_handler_t * sh = obs_source_get_signal_handler ( source ) ;
2021-05-14 02:11:19 +00:00
2021-05-14 08:13:27 +00:00
// Inputs
signal_handler_connect ( sh , " activate " , HandleInputActiveStateChanged , this ) ;
signal_handler_connect ( sh , " deactivate " , HandleInputActiveStateChanged , this ) ;
signal_handler_connect ( sh , " show " , HandleInputShowStateChanged , this ) ;
signal_handler_connect ( sh , " hide " , HandleInputShowStateChanged , this ) ;
signal_handler_connect ( sh , " mute " , HandleInputMuteStateChanged , this ) ;
signal_handler_connect ( sh , " volume " , HandleInputVolumeChanged , this ) ;
signal_handler_connect ( sh , " audio_sync " , HandleInputAudioSyncOffsetChanged , this ) ;
signal_handler_connect ( sh , " audio_mixers " , HandleInputAudioTracksChanged , this ) ;
2021-05-11 05:46:53 +00:00
}
void EventHandler : : DisconnectSourceSignals ( obs_source_t * source )
{
if ( ! source )
return ;
signal_handler_t * sh = obs_source_get_signal_handler ( source ) ;
2021-05-14 02:11:19 +00:00
2021-05-14 08:13:27 +00:00
// Inputs
signal_handler_disconnect ( sh , " activate " , HandleInputActiveStateChanged , this ) ;
signal_handler_disconnect ( sh , " deactivate " , HandleInputActiveStateChanged , this ) ;
signal_handler_disconnect ( sh , " show " , HandleInputShowStateChanged , this ) ;
signal_handler_disconnect ( sh , " hide " , HandleInputShowStateChanged , this ) ;
signal_handler_disconnect ( sh , " mute " , HandleInputMuteStateChanged , this ) ;
signal_handler_disconnect ( sh , " volume " , HandleInputVolumeChanged , this ) ;
signal_handler_disconnect ( sh , " audio_sync " , HandleInputAudioSyncOffsetChanged , this ) ;
signal_handler_disconnect ( sh , " audio_mixers " , HandleInputAudioTracksChanged , this ) ;
2021-05-11 05:46:53 +00:00
}
2021-05-14 08:13:27 +00:00
void EventHandler : : OnFrontendEvent ( enum obs_frontend_event event , void * private_data )
{
2021-05-11 00:34:40 +00:00
auto eventHandler = reinterpret_cast < EventHandler * > ( private_data ) ;
2021-05-14 08:13:27 +00:00
if ( ! eventHandler - > _obsLoaded . load ( ) ) {
if ( event = = OBS_FRONTEND_EVENT_FINISHED_LOADING ) {
blog ( LOG_INFO , " [EventHandler::OnFrontendEvent] OBS has finished loading. Connecting final handlers and enabling events... " ) ;
// Connect source signals and enable events only after OBS has fully loaded (to reduce extra logging).
eventHandler - > _obsLoaded . store ( true ) ;
// In the case that plugins become hotloadable, this will have to go back into `EventHandler::EventHandler()`
obs_enum_sources ( [ ] ( void * param , obs_source_t * source ) {
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
eventHandler - > ConnectSourceSignals ( source ) ;
return true ;
} , private_data ) ;
blog ( LOG_INFO , " [EventHandler::OnFrontendEvent] Finished. " ) ;
} else {
return ;
}
}
2021-05-11 00:34:40 +00:00
switch ( event ) {
// General
case OBS_FRONTEND_EVENT_EXIT :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleExitStarted ( ) ;
2021-05-14 08:13:27 +00:00
blog ( LOG_INFO , " [EventHandler::OnFrontendEvent] OBS is unloading. Disabling events... " ) ;
// Disconnect source signals and disable events when OBS starts unloading (to reduce extra logging).
eventHandler - > _obsLoaded . store ( false ) ;
// In the case that plugins become hotloadable, this will have to go back into `EventHandler::~EventHandler()`
obs_enum_sources ( [ ] ( void * param , obs_source_t * source ) {
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
eventHandler - > DisconnectSourceSignals ( source ) ;
return true ;
} , private_data ) ;
blog ( LOG_INFO , " [EventHandler::OnFrontendEvent] Finished. " ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleStudioModeStateChanged ( true ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleStudioModeStateChanged ( false ) ;
2021-05-11 00:34:40 +00:00
break ;
// Config
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleCurrentSceneCollectionChanged ( ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_SCENE_COLLECTION_LIST_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleSceneCollectionListChanged ( ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_PROFILE_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleCurrentProfileChanged ( ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_PROFILE_LIST_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleProfileListChanged ( ) ;
2021-05-11 00:34:40 +00:00
break ;
// Scenes
case OBS_FRONTEND_EVENT_SCENE_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleCurrentSceneChanged ( ) ;
2021-05-11 00:34:40 +00:00
break ;
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleCurrentPreviewSceneChanged ( ) ;
break ;
case OBS_FRONTEND_EVENT_SCENE_LIST_CHANGED :
eventHandler - > HandleSceneListReindexed ( ) ;
2021-05-11 00:34:40 +00:00
break ;
// Transitions
case OBS_FRONTEND_EVENT_TRANSITION_CHANGED :
break ;
case OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED :
break ;
case OBS_FRONTEND_EVENT_TRANSITION_DURATION_CHANGED :
break ;
// Outputs
case OBS_FRONTEND_EVENT_STREAMING_STARTING :
break ;
case OBS_FRONTEND_EVENT_STREAMING_STARTED :
break ;
case OBS_FRONTEND_EVENT_STREAMING_STOPPING :
break ;
case OBS_FRONTEND_EVENT_STREAMING_STOPPED :
break ;
case OBS_FRONTEND_EVENT_RECORDING_STARTING :
break ;
case OBS_FRONTEND_EVENT_RECORDING_STARTED :
break ;
case OBS_FRONTEND_EVENT_RECORDING_STOPPING :
break ;
case OBS_FRONTEND_EVENT_RECORDING_STOPPED :
break ;
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTING :
break ;
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STARTED :
break ;
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPING :
break ;
case OBS_FRONTEND_EVENT_REPLAY_BUFFER_STOPPED :
break ;
case OBS_FRONTEND_EVENT_VIRTUALCAM_STARTED :
break ;
case OBS_FRONTEND_EVENT_VIRTUALCAM_STOPPED :
break ;
default :
break ;
}
2021-05-10 23:54:48 +00:00
}
2021-05-14 02:11:19 +00:00
void EventHandler : : SourceCreatedMultiHandler ( void * param , calldata_t * data )
{
2021-05-14 08:13:27 +00:00
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
if ( ! eventHandler - > _obsLoaded . load ( ) )
return ;
2021-05-14 02:11:19 +00:00
OBSSource source = GetCalldataPointer < obs_source_t > ( data , " source " ) ;
if ( ! source )
return ;
2021-05-14 08:13:27 +00:00
// Connect all signals from the source
eventHandler - > ConnectSourceSignals ( source ) ;
switch ( obs_source_get_type ( source ) ) {
2021-05-14 02:11:19 +00:00
case OBS_SOURCE_TYPE_INPUT :
2021-05-14 08:13:27 +00:00
eventHandler - > HandleInputCreated ( source ) ;
break ;
case OBS_SOURCE_TYPE_FILTER :
break ;
case OBS_SOURCE_TYPE_TRANSITION :
break ;
case OBS_SOURCE_TYPE_SCENE :
2021-05-14 02:11:19 +00:00
eventHandler - > HandleSceneCreated ( source ) ;
break ;
2021-05-14 08:13:27 +00:00
default :
break ;
}
}
void EventHandler : : SourceDestroyedMultiHandler ( void * param , calldata_t * data )
{
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
if ( ! eventHandler - > _obsLoaded . load ( ) )
return ;
// We can't use any smart types because releasing the source will cause infinite recursion
obs_source_t * source = GetCalldataPointer < obs_source_t > ( data , " source " ) ;
if ( ! source )
return ;
// Disconnect all signals from the source
eventHandler - > DisconnectSourceSignals ( source ) ;
switch ( obs_source_get_type ( source ) ) {
case OBS_SOURCE_TYPE_INPUT :
eventHandler - > HandleInputRemoved ( source ) ; // We have to call `InputRemoved` with source_destroy because source_removed is not called when a source is *only* destroyed
break ;
2021-05-14 02:11:19 +00:00
case OBS_SOURCE_TYPE_FILTER :
break ;
case OBS_SOURCE_TYPE_TRANSITION :
break ;
case OBS_SOURCE_TYPE_SCENE :
break ;
default :
break ;
}
}
void EventHandler : : SourceRemovedMultiHandler ( void * param , calldata_t * data )
{
2021-05-14 08:13:27 +00:00
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
if ( ! eventHandler - > _obsLoaded . load ( ) )
return ;
2021-05-14 02:11:19 +00:00
OBSSource source = GetCalldataPointer < obs_source_t > ( data , " source " ) ;
if ( ! source )
return ;
2021-05-14 08:13:27 +00:00
switch ( obs_source_get_type ( source ) ) {
2021-05-14 02:11:19 +00:00
case OBS_SOURCE_TYPE_INPUT :
break ;
case OBS_SOURCE_TYPE_FILTER :
break ;
case OBS_SOURCE_TYPE_TRANSITION :
break ;
case OBS_SOURCE_TYPE_SCENE :
2021-05-14 08:13:27 +00:00
eventHandler - > HandleSceneRemoved ( source ) ;
2021-05-14 02:11:19 +00:00
break ;
default :
break ;
}
}
void EventHandler : : SourceRenamedMultiHandler ( void * param , calldata_t * data )
{
2021-05-14 08:13:27 +00:00
auto eventHandler = reinterpret_cast < EventHandler * > ( param ) ;
if ( ! eventHandler - > _obsLoaded . load ( ) )
return ;
2021-05-14 02:11:19 +00:00
OBSSource source = GetCalldataPointer < obs_source_t > ( data , " source " ) ;
if ( ! source )
return ;
2021-05-14 08:13:27 +00:00
std : : string oldSourceName = GetCalldataString ( data , " prev_name " ) ;
2021-05-14 02:11:19 +00:00
std : : string sourceName = GetCalldataString ( data , " new_name " ) ;
if ( oldSourceName . empty ( ) | | sourceName . empty ( ) )
return ;
2021-05-14 08:13:27 +00:00
switch ( obs_source_get_type ( source ) ) {
2021-05-14 02:11:19 +00:00
case OBS_SOURCE_TYPE_INPUT :
2021-05-14 08:13:27 +00:00
eventHandler - > HandleInputNameChanged ( source , oldSourceName , sourceName ) ;
2021-05-14 02:11:19 +00:00
break ;
case OBS_SOURCE_TYPE_FILTER :
break ;
case OBS_SOURCE_TYPE_TRANSITION :
break ;
case OBS_SOURCE_TYPE_SCENE :
2021-05-14 08:13:27 +00:00
eventHandler - > HandleSceneNameChanged ( source , oldSourceName , sourceName ) ;
2021-05-14 02:11:19 +00:00
break ;
default :
break ;
}
}