示例#1
0
文件: playlist.c 项目: chrippa/xmms2
/**
 * Insert an entry at a given position in the playlist without
 * validating it.
 *
 * @internal
 */
void
xmms_playlist_insert_entry (xmms_playlist_t *playlist, const gchar *plname,
                            guint32 pos, xmms_medialib_entry_t file,
                            xmms_error_t *err)
{
    xmms_medialib_session_t *session;
    xmmsv_t *dict;
    gint currpos;
    gint len;
    xmmsv_coll_t *plcoll;
    gboolean valid;

    g_mutex_lock (playlist->mutex);

    do {
        session = xmms_medialib_session_begin_ro (playlist->medialib);
        valid = xmms_medialib_check_id (session, file);
    } while (!xmms_medialib_session_commit (session));

    if (!valid) {
        g_mutex_unlock (playlist->mutex);
        xmms_error_set (err, XMMS_ERROR_NOENT,
                        "That is not a valid medialib id!");
        return;
    }


    plcoll = xmms_playlist_get_coll (playlist, plname, err);
    if (plcoll == NULL) {
        /* FIXME: happens ? */
        g_mutex_unlock (playlist->mutex);
        return;
    }

    len = xmms_playlist_coll_get_size (plcoll);
    if (pos > len) {
        xmms_error_set (err, XMMS_ERROR_GENERIC,
                        "Could not insert entry outside of playlist!");
        g_mutex_unlock (playlist->mutex);
        return;
    }
    xmmsv_coll_idlist_insert (plcoll, pos, file);

    /** propagate the MID ! */
    dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_INSERT, file, plname);
    xmmsv_dict_set_int (dict, "position", pos);
    xmms_playlist_changed_msg_send (playlist, dict);

    /** update position once client is familiar with the new item. */
    currpos = xmms_playlist_coll_get_currpos (plcoll);
    if (pos <= currpos) {
        currpos++;
        xmms_collection_set_int_attr (plcoll, "position", currpos);
        XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);
    }

    g_mutex_unlock (playlist->mutex);
}
示例#2
0
文件: playlist.c 项目: dsheeler/xmms2
static gboolean
xmms_playlist_advance_do (xmms_playlist_t *playlist)
{
	gint size, currpos;
	gboolean ret = TRUE;
	xmmsv_coll_t *plcoll;
	const gchar *jumplist;
	xmms_error_t err;
	xmms_playlist_t *buffer = playlist;
	guint newpos;

	xmms_error_reset (&err);

	plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, NULL);
	if (plcoll == NULL) {
		ret = FALSE;
	} else if ((size = xmms_playlist_coll_get_size (plcoll)) == 0) {
		if (xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {
			xmms_playlist_client_load (buffer, jumplist, &err);
			if (xmms_error_isok (&err)) {
				ret = xmms_playlist_advance_do (playlist);
			} else {
				ret = FALSE;
			}
		} else {
			ret = FALSE;
		}
	} else if (!playlist->repeat_one) {
		currpos = xmms_playlist_coll_get_currpos (plcoll);
		currpos++;

		if (currpos == size && !playlist->repeat_all &&
		    xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {

			xmms_collection_set_int_attr (plcoll, "position", -1);
			XMMS_PLAYLIST_CURRPOS_MSG (-1, XMMS_ACTIVE_PLAYLIST);

			xmms_playlist_client_load (buffer, jumplist, &err);
			if (xmms_error_isok (&err)) {
				ret = xmms_playlist_advance_do (playlist);
			} else {
				ret = FALSE;
			}
		} else {
			newpos = currpos%size;
			xmms_collection_set_int_attr (plcoll, "position", newpos);
			XMMS_PLAYLIST_CURRPOS_MSG (newpos, XMMS_ACTIVE_PLAYLIST);
			ret = (currpos != size) || playlist->repeat_all;
		}
	}

	return ret;
}
示例#3
0
文件: playlist.c 项目: dsheeler/xmms2
static gint
xmms_playlist_set_current_position_do (xmms_playlist_t *playlist, guint32 pos,
                                       xmms_error_t *err)
{
	gint size;
	xmms_medialib_entry_t mid;
	xmmsv_coll_t *plcoll;
	const gchar *jumplist;

	g_return_val_if_fail (playlist, FALSE);

	plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err);
	if (plcoll == NULL) {
		return 0;
	}

	size = xmms_playlist_coll_get_size (plcoll);

	if (pos == size &&
	    xmmsv_coll_attribute_get (plcoll, "jumplist", &jumplist)) {

		xmms_collection_set_int_attr (plcoll, "position", 0);
		XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST);

		xmms_playlist_client_load (playlist, jumplist, err);
		if (xmms_error_iserror (err)) {
			return 0;
		}

		plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, err);
		if (plcoll == NULL) {
			return 0;
		}
	} else if (pos < size) {
		XMMS_DBG ("newpos! %d", pos);
		xmms_collection_set_int_attr (plcoll, "position", pos);
		XMMS_PLAYLIST_CURRPOS_MSG (pos, XMMS_ACTIVE_PLAYLIST);
	} else {
		xmms_error_set (err, XMMS_ERROR_INVAL,
		                "Can't set pos outside the current playlist!");
		return 0;
	}

	xmmsv_coll_idlist_get_index (plcoll, pos, &mid);

	return mid;
}
示例#4
0
文件: playlist.c 项目: dsheeler/xmms2
/**
 * Shuffle the playlist.
 *
 */
static void
xmms_playlist_client_shuffle (xmms_playlist_t *playlist, const gchar *plname,
                              xmms_error_t *err)
{
	guint j,i;
	gint len, currpos;
	xmmsv_coll_t *plcoll;

	g_return_if_fail (playlist);

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, plname, err);
	if (plcoll == NULL) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "no such playlist");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	currpos = xmms_playlist_coll_get_currpos (plcoll);
	len = xmms_playlist_coll_get_size (plcoll);
	if (len > 1) {
		/* put current at top and exclude from shuffling */
		if (currpos != -1) {
			swap_entries (plcoll, 0, currpos);
			currpos = 0;
			xmms_collection_set_int_attr (plcoll, "position", currpos);
		}

		/* knuth <3 */
		for (i = currpos + 1; i < len; i++) {
			j = g_random_int_range (i, len);

			if (i != j) {
				swap_entries (plcoll, i, j);
			}
		}

	}

	XMMS_PLAYLIST_CHANGED_MSG (XMMS_PLAYLIST_CHANGED_SHUFFLE, 0, plname);
	XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);

	g_mutex_unlock (playlist->mutex);
}
示例#5
0
文件: playlist.c 项目: dsheeler/xmms2
/**
 * Add an entry to the playlist without locking the mutex.
 */
void
xmms_playlist_add_entry_unlocked (xmms_playlist_t *playlist,
                                  const gchar *plname,
                                  xmmsv_coll_t *plcoll,
                                  xmms_medialib_entry_t file,
                                  xmms_error_t *err)
{
	gint prev_size;
	xmmsv_t *dict;

	prev_size = xmms_playlist_coll_get_size (plcoll);
	xmmsv_coll_idlist_append (plcoll, file);

	/** propagate the MID ! */
	dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_ADD, file, plname);
	xmmsv_dict_set_int (dict, "position", prev_size);
	xmms_playlist_changed_msg_send (playlist, dict);
}
示例#6
0
文件: playlist.c 项目: dsheeler/xmms2
static void
xmms_playlist_update_partyshuffle (xmms_playlist_t *playlist,
                                   const gchar *plname, xmmsv_coll_t *coll)
{
	gint history, upcoming, currpos, size;
	xmmsv_coll_t *src;
	xmmsv_t *tmp;

	XMMS_DBG ("PLAYLIST: Update partyshuffle.");

	if (!xmms_collection_get_int_attr (coll, "history", &history)) {
		history = 0;
	}

	if (!xmms_collection_get_int_attr (coll, "upcoming", &upcoming)) {
		upcoming = XMMS_DEFAULT_PARTYSHUFFLE_UPCOMING;
	}

	currpos = xmms_playlist_coll_get_currpos (coll);
	while (currpos > history) {
		/* Removing entries is fast enough to be processed at once. */
		xmms_playlist_remove_unlocked (playlist, plname, coll, 0, NULL);
		currpos = xmms_playlist_coll_get_currpos (coll);
	}

	g_return_if_fail(xmmsv_list_get (xmmsv_coll_operands_get (coll), 0, &tmp));
	g_return_if_fail(xmmsv_get_coll (tmp, &src));

	/* Since getting random media can be slow on huge medialibs, we refill only
	 * one entry at a time. This let other threads a chance to get the lock on
	 * the playlist object as soon as possible. */
	size = xmms_playlist_coll_get_size (coll);
	if (size < currpos + 1 + upcoming) {
		xmms_medialib_entry_t randentry;
		randentry = xmms_collection_get_random_media (playlist->colldag, src);
		if (randentry > 0) {
			xmms_playlist_add_entry_unlocked (playlist, plname, coll, randentry, NULL);
		}
	}
}
示例#7
0
文件: playlist.c 项目: dsheeler/xmms2
/**
 * Retrieve the currently active xmms_medialib_entry_t.
 *
 */
xmms_medialib_entry_t
xmms_playlist_current_entry (xmms_playlist_t *playlist)
{
	gint size, currpos;
	xmmsv_coll_t *plcoll;
	xmms_medialib_entry_t ent = 0;

	g_return_val_if_fail (playlist, 0);

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, XMMS_ACTIVE_PLAYLIST, NULL);
	if (plcoll == NULL) {
		/* FIXME: What happens? */
		g_mutex_unlock (playlist->mutex);
		return 0;
	}

	currpos = xmms_playlist_coll_get_currpos (plcoll);
	size = xmms_playlist_coll_get_size (plcoll);

	if (currpos == -1 && (size > 0)) {
		currpos = 0;
		xmms_collection_set_int_attr (plcoll, "position", currpos);
		XMMS_PLAYLIST_CURRPOS_MSG (0, XMMS_ACTIVE_PLAYLIST);
	}

	if (currpos < size) {
		xmmsv_coll_idlist_get_index (plcoll, currpos, &ent);
	} else {
		ent = 0;
	}

	g_mutex_unlock (playlist->mutex);

	return ent;
}
示例#8
0
文件: playlist.c 项目: dsheeler/xmms2
/**
 * Move an entry in playlist
 *
 */
static void
xmms_playlist_client_move_entry (xmms_playlist_t *playlist,
                                 const gchar *plname, gint32 pos,
                                 gint32 newpos, xmms_error_t *err)
{
	xmmsv_t *dict;
	xmms_medialib_entry_t id;
	gint currpos, size;
	gint64 ipos, inewpos;
	xmmsv_coll_t *plcoll;

	g_return_if_fail (playlist);

	XMMS_DBG ("Moving %d, to %d", pos, newpos);

	g_mutex_lock (playlist->mutex);

	plcoll = xmms_playlist_get_coll (playlist, plname, err);
	if (plcoll == NULL) {
		/* FIXME: happens ? */
		g_mutex_unlock (playlist->mutex);
		return;
	}

	currpos = xmms_playlist_coll_get_currpos (plcoll);
	size = xmms_playlist_coll_get_size (plcoll);

	if (size == 0 || newpos > (size - 1)) {
		xmms_error_set (err, XMMS_ERROR_NOENT,
		                "Cannot move entry outside playlist");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	if (!xmmsv_coll_idlist_move (plcoll, pos, newpos)) {
		xmms_error_set (err, XMMS_ERROR_NOENT, "Entry was not in list!");
		g_mutex_unlock (playlist->mutex);
		return;
	}

	/* Update the current position pointer */
	ipos = pos;
	inewpos = newpos;
	if (inewpos <= currpos && ipos > currpos)
		currpos++;
	else if (inewpos >= currpos && ipos < currpos)
		currpos--;
	else if (ipos == currpos)
		currpos = inewpos;

	xmms_collection_set_int_attr (plcoll, "position", currpos);

	xmmsv_coll_idlist_get_index (plcoll, newpos, &id);

	dict = xmms_playlist_changed_msg_new (playlist, XMMS_PLAYLIST_CHANGED_MOVE, id, plname);
	xmmsv_dict_set_int (dict, "position", pos);
	xmmsv_dict_set_int (dict, "newposition", newpos);
	xmms_playlist_changed_msg_send (playlist, dict);

	XMMS_PLAYLIST_CURRPOS_MSG (currpos, plname);

	g_mutex_unlock (playlist->mutex);

	return;

}