saving variable.

A lot of this is making more sense to me as i do it but this using a variable in another function has me stuck.
i have this:

curr_photo = photolist[onscreenphoto]

which used in a slideshow loop like this : curr_photo.GetTitle()

Retrieves the current slide’s title. Ok fine, so I’m displaying that over the slide for a few seconds.

now I want to use this curr_photo.GetTitle() in the info dialog (*) that a user can pop up over any slide. The problem is that the info dialog is a different function and doesnt know from curr_photo.GetTitle(). trying it returns this from the debugger which seems to mean that variable is not available to that function.

'Dot' Operator attempted with invalid BrightScript Component or interface reference. (runtime error &hec) in ...g:/source/mediarsstoolkit.brs(305)

305: 	infomenu.setTitle([curr_photo.GetTitle()])

curr_photo &h0000 <uninitialized> val:Uninitialized

The documentation wiki makes a lot of sense once you achieve a certain level of understanding which i dont have in this instance. Can someone point me to where this is explained? I have been able to make functions and call them, How can i save that variable somewhere so it can be used somewhere else?

thanks

There are two ways to share a variable between two functions. The preferred way is to have the first function pass the variable as a parameter to the second function. You can also store the variable in the global AA but this can get messy if you have many variables to share.

–Mark

“RokuMarkn” wrote:
There are two ways to share a variable between two functions. The preferred way is to have the first function pass the variable as a parameter to the second function. You can also store the variable in the global AA but this can get messy if you have many variables to share.

–Mark

Thank you Mark. That makes sense to me. The problem is trying to find somewhere that explains how to do this. If you search the Wiki for “variable as a parameter” or “stored in variables” or “function pass” you get search results that point you to the Brightscript language reference which just says that yes, functions exist and can be stored in variables and passed to functions. So how? Can you point to an SDK example of where this is happening? I have made functions and used them so I’ve gotten that far at least.

thanks

Well, there are many examples of passing parameters in the SDK examples. Basically you declare the variables within the parentheses in your function definition, and then you put the variable you want to pass in parentheses when you call the function.


function First()
    ....
    curr_photo = photolist[onscreenphoto]
    ....
    DisplayDialog(curr_photo)
    ....
end function

function DisplayDialog(photo as Object)
    title = photo.GetTitle()
    ....
end function

Note that the variable name doesn’t need to be the same in the calling function as the called function, but it can be the same if you want.

–Mark

I really appreciate your help, so far its not taking.

I’m using two functions I know you are familiar with, here are the relevant parts. I believe the first function is set up as you explained - the variable is defined (curr_photo) and then used.

Sub DisplaySlideShow(slideshow, photolist)

.........
    		else if msg.isPlaybackPosition() then
    		onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
			print "slideshow display: " + Stri(msg.GetIndex())

.........
canvas = CreateObject( "roImageCanvas" )
    					fontReg = CreateObject("roFontRegistry")
						fontReg.Register("pkg:/fonts/caps.otf")
						font = fontReg.Get("caps",28,50,true)

    bgRect = {
        Color: "#00000000",
        TargetRect: { x: 55, y: 10, w: 280, h: 50 }
    }
    text = {
        Text: curr_photo.GetTitle(),
        TextAttrs:{Color:"#960404", Font:font,
        HAlign:"Left", VAlign:"VCenter", Direction:"LeftToRight"}

		TargetRect: bgRect.TargetRect
    }
 	canvas.SetLayer( 0, [ bgRect, text ] )
 				
    canvas.Show()
    Sleep( 2500 )
    canvas.Close()

End Sub

Now here is where i lose it, The function that is receiving the passed variable you have as

function DisplayDialog(photo as Object)
    title = photo.GetTitle()
    ....
end function
  1. the var I’m looking for is curr_photo not photo. photo.GetTitle() returns the wrong result as you fixed here:http://forums.roku.com/viewtopic.php?f=34&t=55984 (which is how i got curr_photo in the first place)

2.I’m trying to pass this variable to an existing function you will also recognize:

Function DisplayInfomenu(infotype)

	
	infomenu = createobject("romessagedialog")
	infomenu.setmessageport(createobject("romessageport"))
	infomenu.enableoverlay(true)

	if (infotype = 0)
		infomenu.setTitle(curr_photo.GetTitle) ' This is how I think this should be. wont work till i solve the var/pass thing.
		infomenu.setTitle("Title Here") ' The normal way
                infomenu.settext("bla blah")
		infomenu.addbutton(3,"Music")
		infomenu.addbutton(13,"Next")
	'	infomenu.addbutton(4,"Done")
		infomenu.setfocusedmenuitem(1)		' 2nd button


Trying to match your example DisplayInfomenu(infotype) already has a parameter so:
DisplayInfomenu(photo as Object, infotype)
DisplayInfomenu(infotype, photo as Object)
DisplayInfomenu([photo as Object, infotype])

All error

Also trying to add
title= photo.GetTitle() or
title = curr_photo.GetTitle
to the beginning of that function throw dot operator errors.

I was able to figure out where the curr_photo thing went when you wrote it in the other thread, but this is not as simple.

Ok did this all day and got nowhere.
If i understand correctly in your example:

DisplayDialog(curr_photo)

or in my case

DisplayInfomenu(curr_photo)

goes at the end of the first sub and is the line that is passing the variable curr_photo to the function DisplayInfoMenu()

I am stuck at the syntax for the parameters of the function DisplayInfoMenu(infotype, ???) Already has infotype, how do i fit “photo as object” in.

Also no matter what i did (tried a hundred ways) curr_photo always showed as uninitialized in the debugger.

thanks

If you have two parameters, they are separated by a comma in the call and also separated by a comma in the function definition.


function DisplayInfoMenu(infotype as Object, curr_photo as Object)
    title = curr_photo.GetTitle()
end function

function DisplaySlideShow()
   DisplayInfoMenu(infotype, curr_photo)
end function

I’ve changed the name of the parameter to curr_photo because it was confusing you, but it doesn’t matter. Each function has its own set of variables. Even if some have the same name as variables in other functions, they are different variables. So the curr_photo (or photo) in DisplayInfoMenu is a different variable than any variable in DisplaySlideShow, except for the fact that you passed two of the variables.

I’ve also added types to the parameters (“as Object”) even though you weren’t using a type previously. It’s not necessary, but it’s good practice that can help you catch errors earlier.

–Mark

Thank you Mark for bringing some progress to an otherwise frustrating day. I’m close to being able to say success instead of progress.
What you are saying is clear and I am getting a much better understanding. Ironically, I’m back at the same results you fixed before - returning the last item in the array instead of the current one, but this time i can see why.
Here is the slideshow sub - curr_photo is defined, then used (returning correct results) in the canvas, then passed on at the end.

Sub DisplaySlideShow(slideshow, photolist)

.......................	

	else if msg.isPlaybackPosition() then
    		onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
			print "slideshow display: " + Stri(msg.GetIndex())
			
	canvas = CreateObject( "roImageCanvas" )
    					fontReg = CreateObject("roFontRegistry")
						fontReg.Register("pkg:/fonts/caps.otf")
						font = fontReg.Get("caps",28,50,true)

    bgRect = {
        Color: "#00000000",
        TargetRect: { x: 55, y: 10, w: 280, h: 50 }
    }
    text = {
        Text: curr_photo.GetTitle(),
        TextAttrs:{Color:"#960404", Font:font,
        HAlign:"Left", VAlign:"VCenter", Direction:"LeftToRight"}

		TargetRect: bgRect.TargetRect
    }
 	canvas.SetLayer( 0, [ bgRect, text ] )
 				
    canvas.Show()
    Sleep( 2500 )
    canvas.Close()
    
     else if msg.isRemoteKeyPressed()
               if msg.GetIndex() = 10
                DisplayInfoMenu(6, photo) ' Problem Line Here?
                end if
    
..........................

	DisplayInfomenu(infotype, curr_photo)

End Sub

Here is the Infomenu function:


  Function DisplayInfomenu(infotype as Object, curr_photo as Object)
	infomenu = createobject("romessagedialog")
	infomenu.setmessageport(createobject("romessageport"))
	infomenu.enableoverlay(true)
	if (infotype = 6)
	infomenu.setTitle(curr_photo.GetTitle())
................
	

This works, showing a Title in the info dialog - however it returns the last item in the array, not the current one, not too surprising since the variable used below is photo not curr_photo

else if msg.isRemoteKeyPressed()
               if msg.GetIndex() = 10
                DisplayInfoMenu(6, photo) ' Problem Line Here?
                end if

what seems strange is that if I change it to what it should be:

DisplayInfoMenu(6, curr_photo)

I get a type mismatch on the first line of the infomenu function

311: end function
Type Mismatch. (runtime error &h18) in ...g:/source/mediarsstoolkit.brs(261)

261:   Function DisplayInfomenu(infotype as Object, curr_photo as Object)

..........................

infotype &h0010 bsc:roInt, refcnt=1
curr_photo &h0000 <uninitialized> val:Uninitialized
global   &h0020 rotINTERFACE:ifGlobal
m        &h0010 bsc:roAssociativeArray, refcnt=4

with curr_photo showing as uninitialized.
I smell some sort of syntax fix but I’m stumped right now. Thanks to you I got somewhere today and will try again in the morning. I really appreciate the chance to learn.

Well, that could happen if you press a button and get an isRemoteKeyPressed event before the slide show delivers the first isPlaybackPosition event, since that’s the only place that curr_photo gets initialized. If you don’t see how that could be happening, I would add a print statement where you set curr_photo and see if it’s being executed.

–Mark

“RokuMarkn” wrote:
Well, that could happen if you press a button and get an isRemoteKeyPressed event before the slide show delivers the first isPlaybackPosition event, since that’s the only place that curr_photo gets initialized. If you don’t see how that could be happening, I would add a print statement where you set curr_photo and see if it’s being executed.

–Mark
That makes sense except that the IsRemotekeyPressed is after where its initialized and after where its used (canvas). I added (same as previous) two lines to the RemoteKey block and now It works with curr_photo except it pulls the 11th item in the array. I feel like I’m getting closer.The fact that the canvas uses the curr_photo correctly seems to indicate it is being executed, and that does happen before the RemoteKeyPressed.

onscreenphoto = msg.GetIndex()
curr_photo = photolist[onscreenphoto]

else if msg.isPlaybackPosition() then
    		onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
			print "slideshow display: " + Stri(msg.GetIndex())
			
		
    				
    canvas = CreateObject( "roImageCanvas" )
    					fontReg = CreateObject("roFontRegistry")
						fontReg.Register("pkg:/fonts/caps.otf")
						font = fontReg.Get("caps",28,50,true)

    bgRect = {
        Color: "#00000000",
        TargetRect: { x: 55, y: 10, w: 280, h: 50 }
    }
    text = {
        Text: curr_photo.GetTitle(),
        TextAttrs:{Color:"#960404", Font:font,
        HAlign:"Left", VAlign:"VCenter", Direction:"LeftToRight"}

		TargetRect: bgRect.TargetRect
    }
 	canvas.SetLayer( 0, [ bgRect, text ] )
 				
    canvas.Show()
    Sleep( 2500 )
    canvas.Close()
    
     else if msg.isRemoteKeyPressed()
   			onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
               if msg.GetIndex() = 10
                DisplayInfomenu(6, curr_photo)
                end if

Added print curr_photo to the block where its initialized and get this back for each slide while the canvas shows the proper title.

gettitle:<bsTypedValue: Function>
http: <Component: roUrlTransfer>
xml: <Component: roXMLElement>
geturl: <bsTypedValue: Function>

also same result adding print cur_photo to the RemoteKey pressed block

thanks

 else if msg.isRemoteKeyPressed()
   		onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
    		  if msg.GetIndex() = 10
                DisplayInfomenu(6, curr_photo)
                end if

It seems clear that the problem is in this block onscreenphoto is getting the index from isRemoteKeyPressed not isPlaybackPosition which is what i need. If i take out the onscreenphoto = msg.GetIndex() line it goes back to the Typemismatch error so how to get the isButtonPressed index in the RemoteKey block?
Not clear why onscreenphoto (and curr_photo) needs to be re-defined in this block.

thanks

Take out both the assignment to onscreenphoto and curr_photo under isRemoteKeyPressed. Those are set under isPlaybackPosition and should not be changed in isRemoteKeyPressed.

–Mark

“RokuMarkn” wrote:
Take out both the assignment to onscreenphoto and curr_photo under isRemoteKeyPressed. Those are set under isPlaybackPosition and should not be changed in isRemoteKeyPressed.

–Mark
Thank you Mark. OK wrong thing to do - However, that takes me back to where i started this morning with this:

Type Mismatch. (runtime error &h18) in ...g:/source/mediarsstoolkit.brs(270)
270:   Function DisplayInfomenu(infotype As Object, curr_photo As Object)

The isRemoteKeyPressed block seems to be not recognizing that curr_photo is previously defined ? Or another reason for the Type Mismatch?

thanks

I think I introduced this bug because I thought that infotype was an AA. It looks like it’s an integer? If so, change the function definition to


Function DisplayInfomenu(infotype As Integer, curr_photo As Object)

–Mark

“RokuMarkn” wrote:
I think I introduced this bug because I thought that infotype was an AA. It looks like it’s an integer? If so, change the function definition to


Function DisplayInfomenu(infotype As Integer, curr_photo As Object)

–Mark
Sorry to say that wasn’t it. BTW I tried changing both and each type to Integer last night (only other type that seemed posible) - Same Type Mismatch Here is the function itself:

Function DisplayInfomenu(infotype As Object, curr_photo As Object)
	infomenu = createobject("romessagedialog")
	infomenu.setmessageport(createobject("romessageport"))
	infomenu.enableoverlay(true)
	if (infotype = 6)
	infomenu.setTitle(curr_photo.GetTitle())
	infomenu.settext(   "                       Assembled Photography Slideshow" + chr(10) + + chr(10) + "Right Arrow to skip forward, Left Arrow to skip backwards, Play/Pause to stop or resume. Up Arrow to return to Home Page." )
		infomenu.addbutton(3,"Music")
		infomenu.addbutton(4,"Done")
		infomenu.setfocusedmenuitem(1)		' 2nd button
		else
		infomenu.setTitle("TEMP TITLE")
		infomenu.settext("TEMP TEXT")
		infomenu.addbutton(4,"done")
		infomenu.setfocusedmenuitem(1)		' 2nd button
	endif
	infomenu.show()
	while true
		msg = wait(0,infomenu.getmessageport())
		if msg.isscreenclosed() return 0
		if msg.isButtonInfo() return 0   ' Info pressed again, dismiss the info overlay
		if msg.isbuttonpressed()
			button = msg.getindex()
			print "Info Button ";button;" pressed"
			if button = 4
				return button
			endif
		if msg.isbuttonpressed()
			button = msg.getindex()
			print "Info Button ";button;" pressed"
			if button = 3
			AudioPlay()
			return 0
			end if
			 end if
			endif
		end while

end function

but yes it does seem like infotype is an integer.
thanks

EDIT i tried removing the infotype parameter completely from this function and its references and still got a type mismatch on just curr_photo.

The function you quoted in your last post still has both defined as Object. Please try it the way I wrote it, with infotype as Integer and curr_photo as Object.

–Mark

“RokuMarkn” wrote:
The function you quoted in your last post still has both defined as Object. Please try it the way I wrote it, with infotype as Integer and curr_photo as Object.

–Mark
Ok sorry if I was confusing, I did try it as you wrote it, I did still get the type mismatch error, and just tried it again and got the error again.
current function:

Function DisplayInfomenu(infotype As Integer, curr_photo As Object)
	infomenu = createobject("romessagedialog")
	infomenu.setmessageport(createobject("romessageport"))
	infomenu.enableoverlay(true)
	if (infotype = 6)
	infomenu.setTitle(curr_photo.GetTitle())
	infomenu.settext(   "                       Assembled Photography Slideshow" + chr(10) + + chr(10) + "Right Arrow to skip forward, Left Arrow to skip backwards, Play/Pause to stop or resume. Up Arrow to return to Home Page." )
		infomenu.addbutton(3,"Music")
		infomenu.addbutton(4,"Done")
		infomenu.setfocusedmenuitem(1)		' 2nd button
		else
		infomenu.setTitle("TEMP TITLE")
		infomenu.settext("TEMP TEXT")
		infomenu.addbutton(4,"done")
		infomenu.setfocusedmenuitem(1)		' 2nd button
	endif
	infomenu.show()
	while true
		msg = wait(0,infomenu.getmessageport())
		if msg.isscreenclosed() return 0
		if msg.isButtonInfo() return 0   ' Info pressed again, dismiss the info overlay
		if msg.isbuttonpressed()
			button = msg.getindex()
			print "Info Button ";button;" pressed"
			if button = 4
				return button
			endif
		if msg.isbuttonpressed()
			button = msg.getindex()
			print "Info Button ";button;" pressed"
			if button = 3
			AudioPlay()
			return 0
			end if
			 end if
			endif
		end while

end function

Current error:

Type Mismatch. (runtime error &h18) in ...g:/source/mediarsstoolkit.brs(268)

268:   Function DisplayInfomenu(infotype As Integer, curr_photo As Object)
Backtrace:
Function displayinfomenu(infotype As Integer, curr_photo As <uninitialized>) As 
   file/line: /tmp/plugin/LDCAAAmLxswl...g:/source/mediarsstoolkit.brs(269)
Function displayslideshow(slideshow As , photolist As ) As 
   file/line: /tmp/plugin/LDCAAAmLxswl...g:/source/mediarsstoolkit.brs(228)
Function displayredzplace() As 
   file/line: /tmp/plugin/LDCAAAmLxswl...g:/source/mediarsstoolkit.brs(68)
Function uitkdopostermenu(posterdata As , screen As , onselect_callback As ) As Integer
   file/line: /tmp/plugin/LDCAAAmLxswl/pkg:/source/uitoolkit.brs(96)
Function main() As 
   file/line: /tmp/plugin/LDCAAAmLxswl/pkg:/source/main.brs(60)

Local Variables:
infotype &h0002 Integer val:6
curr_photo &h0000 <uninitialized> val:Uninitialized
global   &h0020 rotINTERFACE:ifGlobal
m        &h0010 bsc:roAssociativeArray, refcnt=4
infomenu &h0000 <uninitialized> val:Uninitialized
msg      &h0000 <uninitialized> val:Uninitialized
button   &h0000 <uninitialized> val:Uninitialized

Thanks

Can you post the calling function?
–Mark

“RokuMarkn” wrote:
Can you post the calling function?
–Mark

OK here it is. The call is about 100 lines down, after the canvas.

Sub DisplaySlideShow(slideshow, photolist)

screenFacade = CreateObject("roPosterScreen")
screenFacade.show()
screenFacade.showMessage("Loading...")

print "in DisplaySlideShow"
    'using SetContentList()

contentArray = CreateObject("roArray", photolist.Count(), true)
	for each photo in photolist
		print "---- new DisplaySlideShow photolist loop ----"
		url = photo.GetURL()
		if url<>invalid then
        	aa = CreateObject("roAssociativeArray")
			aa.Url = url
			contentArray.Push(aa)
			print "PRELOAD TITLE: ";photo.GetTitle()
		
		end if
	next
    slideshow.SetContentList(contentArray)
 

    'this is an alternate technique for adding content using AddContent():
	'aa = CreateObject("roAssociativeArray")
	'for each photo in photolist
		'print "---- new DisplaySlideShow photolist loop ----"
		'url = photo.GetURL()
		'if url<>invalid then
		'	aa.Url = url
		'	slideshow.AddContent(aa)
		'	print "PRELOAD TITLE: ";photo.GetTitle()
		'end if
	'next

    btn_more_from_author = 0
    btn_similar          = 1
    btn_bookmark         = 2
    btn_hide             = 13
    
   
	

	screenFacade.close()
waitformsg:
	msg = wait(0, m.port)

	print "DisplaySlideShow: class of msg: ";type(msg); " type:";msg.gettype()
	'for each x in msg:print x;"=";msg[x]:next
	if msg <> invalid then							'invalid is timed-out
		if type(msg) = "roSlideShowEvent" then
    		if msg.isScreenClosed() then
	    		return
    		else if msg.isButtonPressed() then
                print "Menu button pressed: " + Stri(msg.GetIndex())
                'example button usage during pause:
                'if msg.GetIndex() = btn_hide slideshow.ClearButtons()
                
               
                
    		else if msg.isPlaybackPosition() then
    		onscreenphoto = msg.GetIndex()
    		curr_photo = photolist[onscreenphoto]
    		print "slideshow display: " + Stri(msg.GetIndex())
    		
			
		
    				
    canvas = CreateObject( "roImageCanvas" )
    					fontReg = CreateObject("roFontRegistry")
						fontReg.Register("pkg:/fonts/caps.otf")
						font = fontReg.Get("caps",28,50,true)

    bgRect = {
        Color: "#00000000",
        TargetRect: { x: 55, y: 10, w: 280, h: 50 }
    }
    text = {
        Text: curr_photo.GetTitle(),
        TextAttrs:{Color:"#960404", Font:font,
        HAlign:"Left", VAlign:"VCenter", Direction:"LeftToRight"}

		TargetRect: bgRect.TargetRect
    }
 	canvas.SetLayer( 0, [ bgRect, text ] )
 				
    canvas.Show()
    Sleep( 2500 )
    canvas.Close()
    

    
     else if msg.isRemoteKeyPressed()
  			if msg.GetIndex() = 10
                DisplayInfomenu(6, curr_photo)
                end if
                endif
    
     else if msg.isRemoteKeyPressed() then
    			print "Button pressed: " + Stri(msg.GetIndex())
    		else if msg.isRequestSucceeded() then
	    		print "preload succeeded: " + Stri(msg.GetIndex())
    		elseif msg.isRequestFailed() then
    			print "preload failed: " + Stri(msg.GetIndex())
    		elseif msg.isRequestInterrupted() then
    			print "preload interrupted" + Stri(msg.GetIndex())
    		elseif msg.isPaused() then
                print "paused"
                
		  'example button usage during pause:
                'buttons will only be shown in when the slideshow is paused
                'slideshow.AddButton(btn_more_from_author, "more photos from this author")
                'slideshow.AddButton(btn_similar, "similar")
                'slideshow.AddButton(btn_bookmark, curr_photo.GetTitle())
               'slideshow.AddButton(btn_hide, "hide buttons")
               elseif msg.isResumed() then
                print "resumed"
                'example button usage during pause:
               'slideshow.ClearButtons()
            end if
        end if
	
	
	goto waitformsg
	
DisplayInfomenu(infotype, curr_photo)

End Sub