[Tkabber-dev] r55 - trunk/plugins/now_playing

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Wed Sep 26 04:14:30 MSD 2007


Author: kostix
Date: 2007-09-26 04:14:29 +0400 (Wed, 26 Sep 2007)
New Revision: 55

Modified:
   trunk/plugins/now_playing/mpd.tcl
Log:
now_playing/mpd.tcl: implemented asynchronous reading of MPDs output, pretty eclectic at the moment but works.



Modified: trunk/plugins/now_playing/mpd.tcl
===================================================================
--- trunk/plugins/now_playing/mpd.tcl	2007-09-25 22:47:15 UTC (rev 54)
+++ trunk/plugins/now_playing/mpd.tcl	2007-09-26 00:14:29 UTC (rev 55)
@@ -155,7 +155,7 @@
 
 	# TODO provide for login, if needed...
 
-	fconfigure $sock -buffering line -translation lf -encoding utf-8
+	fconfigure $sock -blocking no -buffering line -translation lf -encoding utf-8
 
 	laststate set unknown
 	array set mpd {
@@ -163,10 +163,13 @@
 		songid   -1
 	}
 
-	poll using [mycmd mpd_yield $sock]
+#	poll using [mycmd mpd_yield $sock]
+	mpd_yield $sock
 }
 
 proc now_playing::mpd_cleanup {} {
+	debugmsg tune [info level 0]
+
 	variable mpd
 
 	if {[array exists mpd]} {
@@ -176,58 +179,91 @@
 }
 
 proc now_playing::mpd_yield sock {
+	debugmsg tune [info level 0]
+
+	puts $sock status
+
+	variable $sock
+	upvar 0 $sock transient
+
+	array set transient {
+		state    unknown
+		playlist -1
+		songid   -1
+	}
+
+	fileevent $sock readable [mycmd mpd_yield_status $sock]
+}
+
+proc now_playing::mpd_schedule_next_yield sock {
 	variable options
-	variable lasttime
+	variable repollid
 
+	set repollid [after [expr $options(check_timeout) * 1000] \
+		[mycmd mpd_yield $sock]]
+}
+
+proc now_playing::mpd_yield_status sock {
 	debugmsg tune [info level 0]
 
-	puts $sock status
+	if {[gets $sock line] < 0} {
+		# EOF => mpd closed
+		# TODO ideally, we should schedule connection retries here
+		# instead of just giving up
+		monitoring off
+		return
+	}
 
-	set state    unknown
-	set playlist -1
-	set songid   -1
+	variable $sock
+	upvar 0 $sock {}
 
-	while 1 {
-		if {[gets $sock line] < 0} {
-			# EOF => mpd closed
-			# TODO ideally, we should schedule connection retries here
-			# instead of just giving up
-			monitoring off
-			return
+	switch -glob -- $line {
+		state:*    {
+			set (state)    [mpd_getval $line state]
 		}
-		switch -glob -- $line {
-			state:*    {
-				set state    [mpd_getval $line state]
+		playlist:* {
+			set (playlist) [mpd_getval $line playlist]
+		}
+		songid:*   {
+			set (songid)   [mpd_getval $line songid]
+		}
+		OK         {
+			switch -- [mpd_process_status $sock] {
+				stop {
+					mpd_schedule_next_yield $sock
+				}
+				proceed {
+					puts $sock currentsong
+					fileevent $sock readable [mycmd mpd_yield_songinfo $sock]
+				}
 			}
-			playlist:* {
-				set playlist [mpd_getval $line playlist]
-			}
-			songid:*   {
-				set songid   [mpd_getval $line songid]
-			}
-			OK         break
 		}
 	}
+}
 
-	debugmsg tune "state: $state\n\
-		playlist: $playlist\n\
-		songid: $songid"
+proc now_playing::mpd_process_status sock {
+	debugmsg tune [info level 0]
 
-	switch -- $state {
+	variable options
+	variable lasttime
+	variable $sock
+	upvar 0 $sock {}
+
+	switch -- $(state) {
 		stop  -
 		pause {
-			if {[laststate is inactive]} return
+			if {[laststate is inactive]} { return stop }
 			set newstate inactive
 		}
 		play {
 			if {[laststate is active]} {
 				variable mpd
 
-				if {$mpd(playlist) == $playlist
-				&& $mpd(songid)    == $songid} return
+				if {$mpd(playlist) == $(playlist)
+				&& $mpd(songid)    == $(songid)} { return stop }
 
-				set mpd(playlist) $playlist
-				set mpd(songid)   $songid
+				set mpd(playlist) $(playlist)
+				set mpd(songid)   $(songid)
 			}
 			set newstate active
 		}
@@ -237,80 +273,94 @@
 		}
 	}
 
-	if {[clock seconds] - $lasttime < $options(update_threshold)} return
+	debugmsg tune "state: $(state)\n\
+		playlist: $(playlist)\n\
+		songid: $(songid)"
 
+	if {[clock seconds] - $lasttime < $options(update_threshold)} { return stop }
+
+	laststate set $newstate
+
 	switch -- $newstate {
 		inactive {
 			variable connections
 			foreach connid $connections {
 				::plugins::tune::unpublish $connid
 			}
+			return stop
 		}
 		active {
-			mpd_get_songinfo $sock info
-			mpd_publish_songinfo info
+			return proceed
 		}
 	}
-
-	laststate set $newstate
-	set lasttime [clock seconds]
-	return
 }
 
-proc now_playing::mpd_get_songinfo {sock vinfo} {
-	upvar 1 $vinfo info
+proc now_playing::mpd_yield_songinfo sock {
+	debugmsg tune [info level 0]
 
-	puts $sock currentsong
+	if {[gets $sock line] < 0} {
+		# EOF => mpd closed
+		# TODO ideally, we should schedule connection retries here
+		# instead of just giving up
+		monitoring off
+		return
+	}
 
-	while 1 {
-		if {[gets $sock line] < 0} {
-			# EOF => mpd closed
-			# TODO ideally, we should schedule connection retries here
-			# instead of just giving up
-			monitoring off
-			return
+	variable $sock
+	upvar 0 $sock {}
+
+	switch -glob -- $line {
+		Artist:* {
+			set (artist) [mpd_getval $line Artist]
 		}
-		switch -glob -- $line {
-			Artist:* {
-				set info(artist) [mpd_getval $line Artist]
-			}
-			Title:*  {
-				set info(title)  [mpd_getval $line Title]
-			}
-			Track:*  {
-				set info(track)  [mpd_getval $line Track]
-			}
-			Time:*   {
-				set info(length) [mpd_getval $line Time]
-			}
-			Album:*  {
-				set info(source) [mpd_getval $line Album]
-			}
-			OK       break
+		Title:*  {
+			set (title)  [mpd_getval $line Title]
 		}
+		Track:*  {
+			set (track)  [mpd_getval $line Track]
+		}
+		Time:*   {
+			set (length) [mpd_getval $line Time]
+		}
+		Album:*  {
+			set (source) [mpd_getval $line Album]
+		}
+		OK       {
+			mpd_process_songinfo $sock
+		}
 	}
 }
 
-proc now_playing::mpd_getval {s key} {
-	set val [string trim [string range $s [string length $key:] end]]
-	puts "[info level 0] -> $val"
-	set val
-}
+proc now_playing::mpd_process_songinfo sock {
+	debugmsg tune [info level 0]
 
-proc now_playing::mpd_publish_songinfo vinfo {
+	variable lasttime
 	variable connections
-	upvar 1 $vinfo info
+	variable $sock
+	upvar 0 $sock transient
 
 	set opts [list]
-	foreach {key val} [array get info] {
+	foreach {key val} [array get transient] {
 		lappend opts -$key $val
 	}
 
 	foreach connid $connections {
 		eval [list ::plugins::tune::publish $connid] $opts
 	}
+
+	set lasttime [clock seconds]
+
+	# TODO must somehow clear track info here
+
+	mpd_schedule_next_yield $sock
 }
 
+proc now_playing::mpd_getval {s key} {
+	set val [string trim [string range $s [string length $key:] end]]
+	puts "[info level 0] -> $val"
+	set val
+}
+
 #### Action:
 
 now_playing::mpd_init



More information about the Tkabber-dev mailing list