예제 #1
0
// init
int init()
{
    char filename[512];
    
    config_read();
    
    init_genrand(( unsigned )time( NULL ) );
    
    // get the name of the currently executing DLL (in case someone renames the .dll file)
    GetModuleFileName( plugin.hDllInstance, filename, sizeof( filename ) );
    h_Library = LoadLibrary( filename );
    
    lpWndProcOld = ( WNDPROC )SetWindowLong( plugin.hwndParent, GWL_WNDPROC, ( LONG )WndProc );
    
    master_built = 1;
    build_master();
    copy_master();
    
    return 0;
}
예제 #2
0
LRESULT CALLBACK WndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    // Build list when first playing a file
    if ( uMsg == WM_USER && lParam == IPC_PLAYING_FILE )
    {
        OutputDebugString( "IPC_PLAYING_FILE" );
        OutputDebugString(( char* )wParam );
        
        if ( !master_built )
        {
			OutputDebugString( "Play: Rebuilding track lists" );
            
            build_master();
            copy_master();
            
            master_built = 1;
        }
        
        // Restore playing status
        if ( is_pause )
        {
            OutputDebugString( "Pausing:" );
            SendMessage( hwnd, WM_COMMAND, WINAMP_PAUSE, 0 );
        }
        
        is_pause = 0;
    }
    
    // Mark the playlist as dirty upon any modification
    if ( uMsg == WM_USER && lParam == IPC_PLAYLIST_MODIFIED )
    {
        master_built = 0;
        
        // Clear the history
        history_clear();
    }
    
    
    if ( uMsg == WM_USER && lParam == IPC_GET_PREVIOUS_PLITEM )
    {
        // If plugin not enabled, let winamp do default action
        if ( !cfg_enabled )
            return -1;
            
        // If there is history, return that and rebuild the random list
        if ( history_size() > 0 )
        {
			// Get playing status
            status = SendMessage( hwnd, WM_WA_IPC, 0, IPC_ISPLAYING );

            // Pretend it is paused if anything but playing.
            is_pause = ( status != IS_PLAY );
            
            if ( is_pause )
                OutputDebugString( "Prev track: Is paused" );

			OutputDebugString( "Prev track: Rebuilding track lists" );

            copy_master();
            return history_pop();
        }
    }
    
    if ( uMsg == WM_USER && lParam == IPC_GET_NEXT_PLITEM )
    {
        // Playlist is dirty! Rebuild
        if ( !master_built )
        {
			OutputDebugString( "Next track: Rebuilding track lists" );
            
            build_master();
            copy_master();
            
            master_built = 1;
        }

		if(	atrack_size() == 0 )
		{
			/* Apparently Winamp crashes anyways if your playlist is all separators
			 * and you can't do anything to stop it. This is stupid. */

			OutputDebugString( "Next track: No playable tracks" );
			return -1;
		}

        index = SendMessage( plugin.hwndParent, WM_WA_IPC, 0, IPC_GETLISTPOS );
        
        // Check for any other plugin that wants to modify the next item
        // Especially JTFE
        ft_index = CallWindowProc( lpWndProcOld, hwnd, uMsg, wParam, lParam );
        
        if ( ft_index != -1 )
        {
            wsprintf( debug_string, "Next track: Fall through index: %d", ft_index );
            OutputDebugString( debug_string );
            
            if ( cfg_enabled )
            {
                history_add( index );
                copy_master();
            }
            
            return ft_index;
        }
        
        // If plugin is not enabled, let Winamp shuffle
        if ( !cfg_enabled )
        {
            return -1;
        }
        
        playlist_wnd = get_playlist_hwnd();
        
        pl_len = SendMessage( hwnd, WM_WA_IPC, 0, IPC_GETLISTLENGTH );
        
        file.fileindex = index; // This is zero indexed
        ret = SendMessage( playlist_wnd, WM_WA_IPC, IPC_PE_GETINDEXTITLE, ( LPARAM ) & file );
        
        // If it returns 0 then track information was received
        if ( !ret )
        {
            // Check the track type to determine our behavior
            
            int type = atrack_type( index );
            
            // Get playing status
            status = SendMessage( hwnd, WM_WA_IPC, 0, IPC_ISPLAYING );

            // Pretend it is paused if anything but playing. Don't include separators because they are always stopped.
            is_pause = ( status != IS_PLAY && type != IS_ALBUM_SEP && type != IS_RANDOM_SEP );
            
            if ( is_pause )
                OutputDebugString( "Next track: Is paused" );
                
            wsprintf( debug_string, "Next track: Track type: %d", type );
            OutputDebugString( debug_string );
            
            if ( ( type == IS_ALBUM || type == IS_ALBUM_SEP ) && index < pl_len - 1 )
            {
                /* Track is an album separator or is in an album. Do not shuffle. Return
                 * the next in the playlist */
                OutputDebugString( "In an album:" );
                wsprintf( debug_string, "Old index: %d", index );
                OutputDebugString( debug_string );
                
                if ( type == IS_ALBUM )
                    history_add( index );
                    
                return ( index + 1 ) % pl_len;
            }
            else
            {
                /* Track is a random separator, the end of an album, the last album separator,
				 * or in a random section.
                 * Select a random track from the remaining list */
                is_shuffle = SendMessage( hwnd, WM_WA_IPC, 0, IPC_GET_SHUFFLE );
                
                if ( is_shuffle )
                {
                    int rand_i;
                    
                    // Return random number in interval [0 atrack_size()]
                    OutputDebugString( "Next track: Not in an album / exiting an album" );
                    
                    wsprintf( debug_string, "Next track: Items remaining: %d", atrack_size() );
                    OutputDebugString( debug_string );
                    
                    // Select random entry and play the entry
                    rand_i = ( unsigned int )( atrack_size() * genrand_real2() );
                    next = rm_atrack( rand_i );
                    
                    wsprintf( debug_string, "Next track: Random selected: %d", next );
                    OutputDebugString( debug_string );
                    
                    // If the list of random tracks is empty, copy from the master list
                    if ( atrack_size() == 0 )
                    {
                        OutputDebugString( "Next track: Track list empty, rebuilding the list" );
                        copy_master();
                    }
                    
                    // Don't add separators to the history
                    if ( type == IS_ALBUM_LAST || type == IS_RANDOM )
                        history_add( index );
                        
                    return next;
                }
                else
                    return -1;
            }
        }
        return -1;
    }
    
    return CallWindowProc( lpWndProcOld, hwnd, uMsg, wParam, lParam );
}
예제 #3
0
bool redis_builder::build_cluster()
{
	if (masters_.empty())
	{
		printf("%s: no master available!\r\n", __FUNCTION__);
		return false;
	}

	size_t range = MAX_SLOTS / masters_.size();
	size_t begin = 0, end = MAX_SLOTS % masters_.size() + range -1;

	// build every master node, and connect all of its slaves.

	std::vector<acl::redis_node*>::iterator it;
	for (it = masters_.begin(); it != masters_.end(); ++it)
	{
		if (it != masters_.begin())
			printf("----------------------------------------\r\n");

		(*it)->add_slot_range(begin, end);
		if (build_master(**it) == false)
			return false;
		begin = end + 1;
		end = end + range;
	}

	it = masters_.begin();
	acl::redis_client client((*it)->get_addr());
	acl::redis master(&client);

	// let one master to connect all other master nodes

	printf("===================================================\r\n");
	printf("Meeting all masters and slaves ...\r\n");

	std::vector<acl::redis_node*> all_slaves;
	std::vector<acl::redis_node*>::const_iterator cit;

	for (++it; it != masters_.end(); ++it)
	{
		if (cluster_meet(master, **it) == false)
			return false;
		const std::vector<acl::redis_node*>* slaves = (*it)->get_slaves();
		for (cit = slaves->begin(); cit != slaves->end(); ++cit)
			all_slaves.push_back(*cit);
	}

	while (true)
	{
		int nwait = 0;
		for (cit = all_slaves.begin(); cit != all_slaves.end(); ++cit)
		{
			if ((*cit)->is_connected())
				continue;
			if (cluster_meeting(master, (*cit)->get_addr()) == false)
				nwait++;
			else
				(*cit)->set_connected(true);
		}
		if (nwait == 0)
			break;
		acl_doze(meet_wait_);
	}

	/////////////////////////////////////////////////////////////////////

	printf("===================================================\r\n");
	printf("All nodes of cluster:\r\n");

	const std::map<acl::string, acl::redis_node*>* nodes;
	if ((nodes = master.cluster_nodes())== NULL)
	{
		printf("%s: can't get cluster nodes, addr: %s\r\n",
			__FUNCTION__, client.get_stream()->get_peer(true));
		return false;
	}

	redis_status::show_nodes(nodes);
	return true;
}