int VlcProc::onEqBandsChange( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldVal, vlc_value_t newVal, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; // Post a set equalizer bands command CmdSetEqBands *pCmd = new CmdSetEqBands( pThis->getIntf(), pThis->m_varEqBands, newVal.psz_string ); AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); return VLC_SUCCESS; }
int VlcProc::onEqPreampChange( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldVal, vlc_value_t newVal, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; EqualizerPreamp *pVarPreamp = (EqualizerPreamp*)(pThis->m_cVarEqPreamp.get()); // Post a set preamp command CmdSetEqPreamp *pCmd = new CmdSetEqPreamp( pThis->getIntf(), *pVarPreamp, (newVal.f_float + 20.0) / 40.0 ); AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); return VLC_SUCCESS; }
void Dialogs::showPlaylistSaveCB( intf_dialog_args_t *pArg ) { intf_thread_t *pIntf = (intf_thread_t *)pArg->p_arg; if( pArg->i_results && pArg->psz_results[0] ) { // Create a Playlist Save command CmdPlaylistSave *pCmd = new CmdPlaylistSave( pIntf, pArg->psz_results[0] ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( pIntf ); pQueue->push( CmdGenericPtr( pCmd ) ); } }
int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldVal, vlc_value_t newVal, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; int i_id = newVal.i_int; CmdPlaytreeDelete *pCmdTree = new CmdPlaytreeDelete( pThis->getIntf(), i_id); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmdTree ), false ); return VLC_SUCCESS; }
int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldVal, vlc_value_t newVal, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; playlist_add_t *p_add = static_cast<playlist_add_t*>(newVal.p_address); CmdPlaytreeAppend *pCmdTree = new CmdPlaytreeAppend( pThis->getIntf(), p_add ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmdTree ), false ); return VLC_SUCCESS; }
int VoutManager::controlWindow( struct vout_window_t *pWnd, int query, va_list args ) { intf_thread_t *pIntf = (intf_thread_t *)pWnd->p_private; VoutManager *pThis = pIntf->p_sys->p_voutManager; vout_thread_t* pVout = pWnd->vout; switch( query ) { case VOUT_SET_SIZE: { unsigned int i_width = va_arg( args, unsigned int ); unsigned int i_height = va_arg( args, unsigned int ); if( i_width && i_height ) { pThis->lockVout(); vector<SavedVout>::iterator it; for( it = pThis->m_SavedVoutVec.begin(); it != pThis->m_SavedVoutVec.end(); it++ ) { if( (*it).pVout == pVout ) { // Post a vout resize command CmdResizeVout *pCmd = new CmdResizeVout( pThis->getIntf(), (*it).pVoutWindow, (int)i_width, (int)i_height ); AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); break; } } pThis->unlockVout(); } } default: msg_Dbg( pWnd, "control query not supported" ); break; } return VLC_SUCCESS; }
int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldval, vlc_value_t newval, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; input_item_t *p_item = static_cast<input_item_t*>(newval.p_address); // Create a playtree notify command CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(), p_item ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmdTree ), true ); return VLC_SUCCESS; }
void VlcProc::on_intf_show_changed( vlc_object_t* p_obj, vlc_value_t newVal ) { (void)p_obj; (void)newVal; bool b_fullscreen = getFullscreenVar().get(); if( !b_fullscreen ) { if( newVal.b_bool ) { // Create a raise all command CmdRaiseAll *pCmd = new CmdRaiseAll( getIntf(), getIntf()->p_sys->p_theme->getWindowManager() ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); } } else { VoutManager* pVoutManager = VoutManager::instance( getIntf() ); FscWindow *pWin = pVoutManager->getFscWindow(); if( pWin ) { bool b_visible = pWin->getVisibleVar().get(); AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); if( !b_visible ) { CmdShowWindow* pCmd = new CmdShowWindow( getIntf(), getIntf()->p_sys->p_theme->getWindowManager(), *pWin ); pQueue->push( CmdGenericPtr( pCmd ) ); } else { CmdHideWindow* pCmd = new CmdHideWindow( getIntf(), getIntf()->p_sys->p_theme->getWindowManager(), *pWin ); pQueue->push( CmdGenericPtr( pCmd ) ); } } } }
int VlcProc::onGenericCallback( vlc_object_t *pObj, const char *pVariable, vlc_value_t oldVal, vlc_value_t newVal, void *pParam ) { VlcProc *pThis = (VlcProc*)pParam; AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); CmdGeneric *pCmd = NULL; #define ADD_CALLBACK_ENTRY( var, label ) \ { \ if( strcmp( pVariable, var ) == 0 ) \ pCmd = new Cmd_##label( pThis->getIntf(), pObj, newVal ); \ } ADD_CALLBACK_ENTRY( "item-current", item_current_changed ) ADD_CALLBACK_ENTRY( "volume-change", volume_changed ) ADD_CALLBACK_ENTRY( "intf-event", intf_event_changed ) ADD_CALLBACK_ENTRY( "bit-rate", bit_rate_changed ) ADD_CALLBACK_ENTRY( "sample-rate", sample_rate_changed ) ADD_CALLBACK_ENTRY( "can-record", can_record_changed ) ADD_CALLBACK_ENTRY( "random", random_changed ) ADD_CALLBACK_ENTRY( "loop", loop_changed ) ADD_CALLBACK_ENTRY( "repeat", repeat_changed ) ADD_CALLBACK_ENTRY( "audio-filter", audio_filter_changed ) ADD_CALLBACK_ENTRY( "intf-show", intf_show_changed ) #undef ADD_CALLBACK_ENTRY if( pCmd ) pQueue->push( CmdGenericPtr( pCmd ), false ); else msg_Err( pObj, "no Callback entry provided for %s", pVariable ); return VLC_SUCCESS; }
void CmdUpdateItem::execute() { playlist_t *pPlaylist = getIntf()->p_sys->p_playlist; if( pPlaylist == NULL ) return; input_thread_t *p_input = playlist_CurrentInput( pPlaylist ); if( !p_input ) return; // Get playlist item information input_item_t *pItem = input_GetItem( p_input ); char *pszName = input_item_GetName( pItem ); char *pszUri = input_item_GetURI( pItem ); string name = pszName; // XXX: This should be done in VLC core, not here... // Remove path information if any OSFactory *pFactory = OSFactory::instance( getIntf() ); string::size_type pos = name.rfind( pFactory->getDirSeparator() ); if( pos != string::npos ) { name = name.substr( pos + 1, name.size() - pos + 1 ); } UString srcName( getIntf(), name.c_str() ); UString srcURI( getIntf(), pszUri ); free( pszName ); free( pszUri ); // Create commands to update the stream variables CmdSetText *pCmd1 = new CmdSetText( getIntf(), m_rStreamName, srcName ); CmdSetText *pCmd2 = new CmdSetText( getIntf(), m_rStreamURI, srcURI ); // Push the commands in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); pQueue->push( CmdGenericPtr( pCmd1 ), false ); pQueue->push( CmdGenericPtr( pCmd2 ), false ); vlc_object_release( p_input ); }
TEST(AsyncQueue, TestEmptyQueueBlocksConsumeOneUntilPushed) { AsyncQueue<int> q; // run a separate thread to count how many items are consumed from the queue. std::atomic<int> calls = 0; std::thread t1([&] () { q.consumeOne([&calls] (int i) { calls++; }); }); std::this_thread::sleep_for(std::chrono::milliseconds(250)); ASSERT_EQ(0, calls); // push something onto the queue and wait for consumer t1 to complete. q.push(1); t1.join(); ASSERT_EQ(1, calls); ASSERT_EQ(0, q.size()); }
int ThemeRepository::changeSkin( vlc_object_t *pIntf, char const *pVariable, vlc_value_t oldval, vlc_value_t newval, void *pData ) { ThemeRepository *pThis = (ThemeRepository*)(pData); if( !strcmp( pVariable, "intf-skins-interactive" ) ) { CmdDlgChangeSkin cmd( pThis->getIntf() ); cmd.execute(); } else if( !strcmp( pVariable, "intf-skins" ) ) { // Try to load the new skin CmdChangeSkin *pCmd = new CmdChangeSkin( pThis->getIntf(), newval.psz_string ); AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); } return VLC_SUCCESS; }
TEST(AsyncQueue, TestConsumeNRemovesCorrectNumberOfElements) { AsyncQueue<int> q; q.push(1); q.push(2); q.push(3); ASSERT_EQ(3, q.size()); q.consumeN(2, [](int){}); ASSERT_EQ(1, q.size()); q.consumeN(1, [](int){}); ASSERT_EQ(0, q.size()); }
void CtrlResize::CmdResizeResize::execute() { EvtMotion *pEvtMotion = (EvtMotion*)m_pParent->m_pEvt; // Set the cursor m_pParent->changeCursor( m_pParent->m_direction ); int newWidth = m_pParent->m_width; newWidth += pEvtMotion->getXPos() - m_pParent->m_xPos; int newHeight = m_pParent->m_height; newHeight += pEvtMotion->getYPos() - m_pParent->m_yPos; // Create a resize command, instead of calling the window manager directly. // Thanks to this trick, the duplicate resizing commands will be trashed // in the asynchronous queue, thus making resizing faster CmdGeneric *pCmd = new CmdResize( m_pParent->getIntf(), m_pParent->m_rWindowManager, m_pParent->m_rLayout, newWidth, newHeight ); // Push the command in the asynchronous command queue AsyncQueue *pQueue = AsyncQueue::instance( getIntf() ); pQueue->push( CmdGenericPtr( pCmd ) ); }
TEST(AsyncQueue, TestQueueSize) { AsyncQueue<int> q; ASSERT_EQ(0, q.size()); q.push(1); ASSERT_EQ(1, q.size()); q.push(2); ASSERT_EQ(2, q.size()); }
TEST(AsyncQueue, TestConsumeNConsumesAfterEmptyQueue) { AsyncQueue<int> q; q.push(1); q.push(2); std::atomic<bool> threadDone = false; std::thread t1([&]() { q.consumeN(3, [](int){}); threadDone = true; }); std::this_thread::sleep_for(std::chrono::milliseconds(250)); ASSERT_EQ(0, q.size()); ASSERT_EQ(false, threadDone); q.push(1); std::this_thread::sleep_for(std::chrono::milliseconds(250)); ASSERT_EQ(0, q.size()); ASSERT_EQ(true, threadDone); t1.join(); }
//--------------------------------------------------------------------------- // Run: main loop //--------------------------------------------------------------------------- static void *Run( void * p_obj ) { int canc = vlc_savecancel(); intf_thread_t *p_intf = (intf_thread_t *)p_obj; bool b_error = false; char *skin_last = NULL; ThemeLoader *pLoader = NULL; OSLoop *loop = NULL; vlc_mutex_lock( &p_intf->p_sys->init_lock ); // Initialize singletons if( OSFactory::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize OSFactory" ); b_error = true; goto end; } if( AsyncQueue::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize AsyncQueue" ); b_error = true; goto end; } if( Interpreter::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate Interpreter" ); b_error = true; goto end; } if( VarManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate VarManager" ); b_error = true; goto end; } if( VlcProc::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize VLCProc" ); b_error = true; goto end; } if( VoutManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate VoutManager" ); b_error = true; goto end; } if( ArtManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate ArtManager" ); b_error = true; goto end; } if( ThemeRepository::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate ThemeRepository" ); b_error = true; goto end; } if( Dialogs::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instantiate qt4 dialogs provider" ); b_error = true; goto end; } // Load a theme skin_last = config_GetPsz( p_intf, "skins2-last" ); pLoader = new ThemeLoader( p_intf ); if( !skin_last || !pLoader->load( skin_last ) ) { // No skins (not even the default one). let's quit CmdQuit *pCmd = new CmdQuit( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); msg_Err( p_intf, "no skins found : exiting"); } delete pLoader; free( skin_last ); // Get the instance of OSLoop loop = OSFactory::instance( p_intf )->getOSLoop(); // Signal the main thread this thread is now ready p_intf->p_sys->b_error = false; p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); // Enter the main event loop loop->run(); // Destroy OSLoop OSFactory::instance( p_intf )->destroyOSLoop(); // save and delete the theme if( p_intf->p_sys->p_theme ) { p_intf->p_sys->p_theme->saveConfig(); delete p_intf->p_sys->p_theme; p_intf->p_sys->p_theme = NULL; msg_Dbg( p_intf, "current theme deleted" ); } // save config file config_SaveConfigFile( p_intf ); end: // Destroy "singleton" objects Dialogs::destroy( p_intf ); ThemeRepository::destroy( p_intf ); ArtManager::destroy( p_intf ); VoutManager::destroy( p_intf ); VlcProc::destroy( p_intf ); VarManager::destroy( p_intf ); Interpreter::destroy( p_intf ); AsyncQueue::destroy( p_intf ); OSFactory::destroy( p_intf ); if( b_error ) { p_intf->p_sys->b_error = true; p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); } vlc_restorecancel(canc); return NULL; }
//--------------------------------------------------------------------------- // Run: main loop //--------------------------------------------------------------------------- static void *Run( void * p_obj ) { int canc = vlc_savecancel(); intf_thread_t *p_intf = (intf_thread_t *)p_obj; bool b_error = false; char *skin_last = NULL; ThemeLoader *pLoader = NULL; OSLoop *loop = NULL; vlc_mutex_lock( &p_intf->p_sys->init_lock ); // Initialize singletons if( OSFactory::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize OSFactory" ); b_error = true; goto end; } if( AsyncQueue::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize AsyncQueue" ); b_error = true; goto end; } if( Interpreter::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instanciate Interpreter" ); b_error = true; goto end; } if( VarManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instanciate VarManager" ); b_error = true; goto end; } if( VlcProc::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot initialize VLCProc" ); b_error = true; goto end; } if( VoutManager::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instanciate VoutManager" ); b_error = true; goto end; } if( ThemeRepository::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instanciate ThemeRepository" ); b_error = true; goto end; } if( Dialogs::instance( p_intf ) == NULL ) { msg_Err( p_intf, "cannot instanciate qt4 dialogs provider" ); b_error = true; goto end; } // Load a theme skin_last = config_GetPsz( p_intf, "skins2-last" ); pLoader = new ThemeLoader( p_intf ); if( !skin_last || !*skin_last || !pLoader->load( skin_last ) ) { // Get the resource path and try to load the default skin OSFactory *pOSFactory = OSFactory::instance( p_intf ); const list<string> &resPath = pOSFactory->getResourcePath(); const string &sep = pOSFactory->getDirSeparator(); list<string>::const_iterator it; for( it = resPath.begin(); it != resPath.end(); it++ ) { string path = (*it) + sep + "default.vlt"; if( pLoader->load( path ) ) { // Theme loaded successfully break; } } if( it == resPath.end() ) { // Last chance: the user can select a new theme file if( Dialogs::instance( p_intf ) ) { CmdDlgChangeSkin *pCmd = new CmdDlgChangeSkin( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); } else { // No dialogs provider, just quit... CmdQuit *pCmd = new CmdQuit( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); msg_Err( p_intf, "cannot show the \"open skin\" dialog: exiting..."); } } } delete pLoader; free( skin_last ); // Get the instance of OSLoop loop = OSFactory::instance( p_intf )->getOSLoop(); // Signal the main thread this thread is now ready p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); // Enter the main event loop loop->run(); // Destroy OSLoop OSFactory::instance( p_intf )->destroyOSLoop(); // save and delete the theme if( p_intf->p_sys->p_theme ) { p_intf->p_sys->p_theme->saveConfig(); delete p_intf->p_sys->p_theme; p_intf->p_sys->p_theme = NULL; msg_Dbg( p_intf, "current theme deleted" ); } // save config file config_SaveConfigFile( p_intf, NULL ); end: // Destroy "singleton" objects Dialogs::destroy( p_intf ); ThemeRepository::destroy( p_intf ); VoutManager::destroy( p_intf ); VlcProc::destroy( p_intf ); VarManager::destroy( p_intf ); Interpreter::destroy( p_intf ); AsyncQueue::destroy( p_intf ); OSFactory::destroy( p_intf ); if( b_error ) { p_intf->p_sys->b_ready = true; vlc_cond_signal( &p_intf->p_sys->init_wait ); vlc_mutex_unlock( &p_intf->p_sys->init_lock ); libvlc_Quit( p_intf->p_libvlc ); } vlc_restorecancel(canc); return NULL; }
//--------------------------------------------------------------------------- // Run: main loop //--------------------------------------------------------------------------- static void Run( intf_thread_t *p_intf ) { // Load a theme ThemeLoader *pLoader = new ThemeLoader( p_intf ); char *skin_last = config_GetPsz( p_intf, "skins2-last" ); if( !skin_last || !*skin_last || !pLoader->load( skin_last ) ) { // Get the resource path and try to load the default skin OSFactory *pOSFactory = OSFactory::instance( p_intf ); const list<string> &resPath = pOSFactory->getResourcePath(); const string &sep = pOSFactory->getDirSeparator(); list<string>::const_iterator it; for( it = resPath.begin(); it != resPath.end(); it++ ) { string path = (*it) + sep + "default.vlt"; if( pLoader->load( path ) ) { // Theme loaded successfully break; } } if( it == resPath.end() ) { // Last chance: the user can select a new theme file if( Dialogs::instance( p_intf ) ) { CmdDlgChangeSkin *pCmd = new CmdDlgChangeSkin( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); } else { // No dialogs provider, just quit... CmdQuit *pCmd = new CmdQuit( p_intf ); AsyncQueue *pQueue = AsyncQueue::instance( p_intf ); pQueue->push( CmdGenericPtr( pCmd ) ); msg_Err( p_intf, "Cannot show the \"open skin\" dialog: exiting..."); } } } delete pLoader; if( skin_last ) { free( skin_last ); } // Get the instance of OSLoop OSLoop *loop = OSFactory::instance( p_intf )->getOSLoop(); // Check if we need to start playing if( p_intf->b_play ) { playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist ) { playlist_Play( p_playlist ); vlc_object_release( p_playlist ); } } // Enter the main event loop loop->run(); // Delete the theme and save the configuration of the windows if( p_intf->p_sys->p_theme ) { p_intf->p_sys->p_theme->saveConfig(); delete p_intf->p_sys->p_theme; p_intf->p_sys->p_theme = NULL; } }