- Revamped threading logic in music_player

This commit is contained in:
noisymime 2008-03-28 01:10:49 +00:00
parent cd455a6fab
commit 7f729ff69d
5 changed files with 51 additions and 45 deletions

View File

@ -1,10 +1,18 @@
import time
import thread
import clutter
import gobject
from ui_elements.image_row import ImageRow
from ui_elements.image_frame import ImageFrame
class MusicObjectRow(ImageRow):
#Setup signals
__gsignals__ = {
"load-complete": (
gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, []),
"load-begin": (
gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, [])
}
def __init__(self, glossMgr, width, height, columns, music_player):
ImageRow.__init__(self, glossMgr, width, height, columns)
@ -22,6 +30,7 @@ class MusicObjectRow(ImageRow):
#External timeline can be set by other objects as a form of 'lock'. If external timeline is running, thread will be paused
self.external_timeline = None
self.emit("load-begin")
for i in range(start, end):
object = self.objectLibrary[i]
print "loading: " + object.name
@ -54,20 +63,17 @@ class MusicObjectRow(ImageRow):
self.add_texture_group(tmpImage)
self.emit("load-complete")
return False
#print "Finished threads"
#Just a callback function to call 'load_image_range()' in a new thread
def load_image_range_cb(self, timeline):
thread.start_new_thread(self.load_image_range, (self.num_columns, len(self.objectLibrary)-1, True))
#A simple callback funtion to set the image of an artist/album after it has completed a download
def set_image_cb(self, data, music_object, tmpImage):
#if self.glossMgr.debug:
print "Image for music_object '%s' downloaded" % (music_object.name)
pixbuf = music_object.get_image()
if not pixbuf is None:
clutter.threads_init()
clutter.threads_enter()
tmpImage.set_pixbuf(pixbuf)
clutter.threads_leave()

View File

@ -2,7 +2,7 @@ import pygtk
import gtk
import gobject
import os
import thread
import threading
from modules.music_player.music_objects.music_object import MusicObject
class artist(MusicObject):
@ -56,18 +56,19 @@ class artist(MusicObject):
else:
#We send a request off to LastFM to grab an image.
#This will emit the "image-found" signal when and if it was successful
thread.start_new_thread(self.get_image_from_lastFM, (None,))
#gobject.idle_add(self.get_image_from_lastFM)
thread = threading.Thread(target=self.get_image_from_lastFM)
thread.start()
#thread.start_new_thread(self.get_image_from_lastFM, (None,))
#pixbuf = self.get_image_from_lastFM()
return self.PENDING_DOWNLOAD
def get_image_from_lastFM(self, thread_data):
def get_image_from_lastFM(self):
pixbuf = self.music_player.lastFM.get_artist_image(self.name)
if not pixbuf is None:
self.save_image(pixbuf)
return pixbuf
else:
#We have failed to find an image
return None
return False
#Saves an image (pixbuf) to file and updates the Myth db
def save_image(self, pixbuf):

View File

@ -2,7 +2,7 @@ import pygtk
import gobject
import gtk
import clutter
import thread
import threading
from modules.music_player.backends.myth_music import Backend
from modules.music_player.lastFM_interface import lastFM_interface
from modules.music_player.music_object_row import MusicObjectRow
@ -42,7 +42,6 @@ class Module:
self.is_playing = False
#self.load_albums()
self.artists = self.backend.get_artists()
self.timeout_id = 0
#thread.start_new_thread(self.load_artists, ())
@ -85,11 +84,11 @@ class Module:
if (event.keyval == clutter.keysyms.Left) or (event.keyval == clutter.keysyms.Right):
#First check if there's any current timeouts and if there is, clear it
#if not self.timeout_id == 0: gobject.source_remove(self.timeout_id)
self.artistImageRow.sleep = True
self.artistImageRow.input_queue.input(event)
#self.artistImageRow.input_queue.connect("queue-flushed", self.start_delay, self.load_albums, None)
self.queue_id = self.artistImageRow.input_queue.connect("queue-flushed", self.load_albums)
self.artistImageRow.sleep = True
self.artistImageRow.sleep = False
elif (event.keyval == clutter.keysyms.Down):
@ -98,6 +97,7 @@ class Module:
elif self.current_context == self.CONTEXT_LIST1:
if (event.keyval == clutter.keysyms.Up):
self.artistImageRow.external_timeline = self.list1.timeline
#If we're at the top of the list already, we change focus bar to the image_row
if self.list1.selected == 0:
self.list1.select_none_elegant()
@ -123,16 +123,20 @@ class Module:
#Loads albums into List1
def load_albums(self, queue):
self.artistImageRow.input_queue.disconnect(self.queue_id)
if self.artistImageRow.input_queue.handler_is_connected(self.queue_id): self.artistImageRow.input_queue.disconnect(self.queue_id)
#Just a little test code
artist = self.artistImageRow.get_current_object()
thread.start_new_thread(self.backend.get_albums_by_artistID, (artist.artistID,))
#gobject.idle_add(self.backend.get_albums_by_artistID, artist.artistID)
thread = threading.Thread(target=self.backend.get_albums_by_artistID, args=(artist.artistID,))
thread.start()
#thread.start_new_thread(self.backend.get_albums_by_artistID, (artist.artistID,))
self.conn_id = self.backend.connect("query-complete", self.update_for_albums, artist)
def update_for_albums(self, data, artist = None):
self.backend.disconnect(self.conn_id)
if artist is None: self.artistImageRow.get_current_object()
if not artist == self.artistImageRow.get_current_object(): return
if self.backend.handler_is_connected(self.conn_id): self.backend.disconnect(self.conn_id)
albums = self.backend.get_albums_by_artistID(artist.artistID)
clutter.threads_enter()
@ -149,7 +153,15 @@ class Module:
clutter.threads_leave()
def begin(self, glossMgr):
#self.display("blah", glossMgr)
#return
self.artistImageRow.objectLibrary = self.artists
#thread.start_new_thread(self.artistImageRow.load_image_range, (0, len(self.artists)-1, True))
gobject.idle_add(self.artistImageRow.load_image_range, 0, len(self.artists)-1, True)
self.artistImageRow.connect("load-complete", self.display, glossMgr)
def display(self, data, glossMgr):
#Create a backdrop for the player. In this case we just use the same background as the menus
self.backdrop = glossMgr.get_themeMgr().get_texture("background", None, None)
self.backdrop.set_size(self.stage.get_width(), self.stage.get_height())
@ -163,8 +175,8 @@ class Module:
self.backdrop_behaviour.apply(self.backdrop)
#Load in the initial images:
self.artistImageRow.objectLibrary = self.artists
self.artistImageRow.load_image_range(0, self.num_columns)
#self.artistImageRow.objectLibrary = self.artists
#self.artistImageRow.load_image_range(0, self.num_columns)
self.stage.add(self.artistImageRow)
self.artistImageRow.set_opacity(0)
@ -178,34 +190,18 @@ class Module:
self.stage.add(self.list1)
self.list2 = LabelList(5)
self.list2.set_position( (self.stage.get_width()/2 + self.list1.get_width()), 350)
self.list2.set_position( (600), 350)
self.stage.add(self.list2)
"""
self.tmpLabel = clutter.Label()
self.tmpLabel.set_color(clutter.color_parse('White'))
self.tmpLabel.set_position(0, 350)
self.tmpLabel.set_text("Test")
self.tmpLabel.show()
self.stage.add(self.tmpLabel)
"""
#The preview img
self.main_img = ImageFrame(None, 300, True) #clutter.Texture()
self.main_img.set_position(30, 400)
self.main_img.set_position(50, 300)
self.main_img.set_rotation(clutter.Y_AXIS, 45, self.main_img.get_width(), 0, 0)
self.main_img.show()
self.stage.add(self.main_img)
self.timeline_backdrop.start()
#Load the rest of the images
#thread.start_new_thread(self.load_image_range, (self.num_columns, len(self.artists)-1))
self.artistImageRow.sleep = True
self.timeline_backdrop.connect("completed", self.artistImageRow.load_image_range_cb)
#self.load_image_range(self.num_columns, len(self.artists)-1)
def stop(self):
pass

View File

@ -72,7 +72,7 @@ class mythDB():
self.cursor.execute(sql)
data = self.cursor.fetchall()
if not data == ():
return data[1][1]
return data[0][1]
else:
return None

View File

@ -178,6 +178,9 @@ class ImageRow(clutter.Group):
def select_first(self):
#Sanity check
if len(self.textureLibrary) == 0: return
self.timeline = clutter.Timeline(self.frames, self.fps)
self.input_queue.set_timeline(self.timeline)