PDA

View Full Version : NR Crashes using RegisterVariableWatch



Jlee
December 16th, 2009, 04:42 AM
I've tried all sorts troubleshooting this problem but just couldn't find a solution so I hope someone can help me.

What I'm trying to do is put some code in my Lua file that will monitor the number of tracks in the JRMC playing now list and, if the last track is playing and there is less than 30 seconds to go (i.e. the playlist is about to run out) NR automatically adds a track by playing a backup playlist.

Realising that I would need to watch the MP.TrackPosition (number of seconds played through current track) variable I thought that might not be good performance-wise to monitor that constantly (though I actually haven't noticed much of a problem) so I thought it would be better to only instigate the watch of the track position when the last track is actually playing. So at all other times I would just watch MP.Track & MP.PlaylistPosition to get a clue as to whether the track has changed and then evaluate whether last track is now playing - if it is I instigate the watch of MP.TrackPosition, then add a track to the playing now list when there's 30 secs to go, then kill the watch of MP.TrackPosition.

When I do this NR crashes. I think the problem is that when the track is added this changes MP.PlaylistLength, which in turn calls the function that decides whether to reinstigate the watch on MP.TrackPosition. Of course it shoudn't because it's not now playing the last track. No matter what I try if I put the RegisterVariableWatch in my NextSong() function NR always crashes when the PlayBackup() function adds a track.

Here's a sample of my lua code so I hope someone can help.

Here's what it does... The watch of both MP.Track and MP.PlaylistPosition calls NextSong(). A small piece of code at the start of NextSong() decides whether to watch MP.TrackPosition, which in turn calls PlayBackup() which decides whether to add the track. If the track is added the watch of MP.TrackPosition is killed and NextSong() is invoked again as a result of adding the track. NR crashes at this point.


--##################### Start of OnCCFLoad #####################--
--This executes actions when NR first starts up.
function OnCCFLoad()
print("OnCCFLOadActions")

OnGirderReady(function () NetRemote.ExecuteAction(-1,0,1,"NR.StartUp") end)--Executes a bunch of actions in Girder at startup

--Resgister variables to watch:
--NetRemote.RegisterVariableWatch('variable to watch',function to run when variable changes)
NetRemote.RegisterVariableWatch('MP.Lyrics', lyricsFunc)
NetRemote.RegisterVariableWatch('MP.PlaylistLength ', playlistLengthFunc)
NetRemote.RegisterVariableWatch('MP.Track', NextSong)
NetRemote.RegisterVariableWatch('MP.Year', mpYearFunc)
NetRemote.RegisterVariableWatch('MP.Album Year', mpAlbumYearFunc)
NetRemote.RegisterVariableWatch('MP.PlaylistPositi on',NextSong);
NetRemote.RegisterVariableWatch('MP.GACCovers.Requ estInProgress',WatchGACCovers);
NetRemote.RegisterVariableWatch('MP.GACAlbum.Reque stInProgress',WatchGACAlbum);
NetRemote.RegisterVariableWatch('MP.GACText.Reques tInProgress',WatchGACText);
NetRemote.RegisterVariableWatch('MP.GACTracks.Requ estInProgress',WatchGACTracks);
NetRemote.RegisterVariableWatch('MP.GACHits.Reques tInProgress',WatchGACHits);
NetRemote.RegisterVariableWatch('MP.GACHits1.Reque stInProgress',WatchGACHits1);
NetRemote.RegisterVariableWatch('MP.LinkActive',MP LinkActiveFunc);

print("end of OnCCFLoad actions")
end;
--##################### End of OnCCFLoad #####################--


--##################### Start of Media Player GAC Code #####################--
--Previous track GAC
pgac1 = GAC:new{var='PGAC1',includeSubItemCount=0,imageSiz e='M', fields='Album,Artist',count=1, useGP=1 };
pgac1:SetClearOnChange(1)
pgac1:SetScheme('Playing Now');

--Next track GAC
pgac2 = GAC:new{var='PGAC2',includeSubItemCount=0,imageSiz e='M', fields='Album,Artist',count=1, useGP=1 };
pgac2:SetClearOnChange(1)
pgac2:SetScheme('Playing Now');

--Coming next GAC
pgac3 = GAC:new{var='PGAC3',includeSubItemCount=0,imageSiz e='M', fields='Album,Artist',count=5, useGP=1, FullPage=0 };
pgac3:SetClearOnChange(1)
pgac3:SetScheme('Playing Now');



--Updates Next / previous track GACs when tracks change
function NextSong()
print("Next song called")
local cp = tonumber(NetRemote.GetVariable("MP.PlaylistPosition"))
local total = tonumber(NetRemote.GetVariable("MP.PlaylistLength"))

if cp == total then
mywatcher = NetRemote.RegisterVariableWatch('MP.TrackPosition' ,PlayBackup);
else
NetRemote.UnregisterVariableWatch(mywatcher)
end;

if total == nil then total = cp end
if cp then
if cp > 1 then
pgac1:SetStart(cp-2)
pgac1:Request()
else
pgac1:ClearDisplay()
end
if cp < total then
pgac2:SetStart(cp)
pgac2:Request()
pgac3:SetStart(cp+1)
pgac3:Request()
else
NetRemote.SetVariable("MP.PGAC2.Items", nil)
pgac2:ClearDisplay()
NetRemote.SetVariable("MP.PGAC3.Items", nil)
pgac3:ClearDisplay()

end
--plgacl:SetStart(cp-1)
--plgacl:Request()
end
local v = NetRemote.GetVariable('ShowVis')
if v== '1' then
NetRemote.ExecuteAction(-1,0,1,"ForceVis")
end;
end;

RegisterPanelWatch("MC", "Main", function(a,b,c) NextSong() end)

function PlayBackup()
if NetRemote.GetVariable("MP.PlaylistLength") == NetRemote.GetVariable("MP.PlaylistPosition") then

local tl = NetRemote.GetVariable("MP.TrackLength")
tl = (tonumber(string.sub(tl,0,string.len(tl)-3)) *60) + tonumber(string.sub(tl,4,string.len(tl)))
local tp = NetRemote.GetVariable("MP.TrackPosition")
tp = (tonumber(string.sub(tp,0,string.len(tp)-3)) *60) + tonumber(string.sub(tp,4,string.len(tp)))
if tl - tp < 30 then
print("Back up track being added...")
NetRemote.ExecuteAction(-10,2,255,'LX ADD "Media Library\\Audio\\NetRemote\\Backup Playlist" -1',1);
NetRemote.UnregisterVariableWatch(mywatcher)
end;
end;
end;

--##################### End #####################--

Rob H
December 16th, 2009, 10:18 AM
Hmm... that's interesting.

I would probably recommend checking that myWatcher is actually assigned before calling UnregisterVariableWatch and then explicitly setting it to nil after the call. That's most likely what's causing the problem.

Either that or only create myWatcher once and use myWatcher:Enable() and myWatcher:Disable() to turn it on and off.

I'll try to reproduce the error though, as it obviously shouldn't cause a crash.

Jlee
December 16th, 2009, 12:38 PM
Thanks Rob. I couldn't get it to work by setting mywatcher to nil after unregistering (assume it's just mywatcher == nil). However, disabling and enabling works great. Thanks for your help.