Rename GroupStack to SceneManager to make functionality more obvious

This commit is contained in:
JD Layman 2021-10-09 20:51:33 -05:00
parent 6eb283de1b
commit f5dbeb5205
8 changed files with 64 additions and 55 deletions

View File

@ -7,10 +7,10 @@ function onKeyEvent(key as string, press as boolean) as boolean
if not press then return false
if key = "back"
m.global.groupStack.callFunc("pop")
m.global.sceneManager.callFunc("popScene")
return true
else if key = "options"
group = m.global.groupStack.callFunc("peek")
group = m.global.sceneManager.callFunc("getActiveScene")
if group.optionsAvailable
group.lastFocus = group.focusedChild
panel = group.findNode("options")

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="JFScene" extends="Scene">
<children>
<Group id="content" />
<JFOverhang id="overhang" />
</children>
<interface>

View File

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="GroupStack" extends="ContentNode">
<interface>
<function name="push" />
<function name="pop" />
<function name="peek" />
<function name="resetTime" />
<field id="currentUser" type="string" onChange="updateUser" />
</interface>
<script type="text/brightscript" uri="GroupStack.brs" />
</component>

View File

@ -1,12 +1,13 @@
sub init()
m.groups = []
m.scene = m.top.getScene()
m.content = m.scene.findNode("content")
m.overhang = m.scene.findNode("overhang")
end sub
'
' Push a new group onto the stack, replacing the existing group on the screen
sub push(newGroup)
sub pushScene(newGroup)
currentGroup = m.groups.peek()
if currentGroup <> invalid
'Search through group and store off last focused item
@ -31,11 +32,10 @@ sub push(newGroup)
m.groups.push(newGroup)
' TODO: figure out a better way to do this without relying on indexing
if currentGroup <> invalid
m.scene.replaceChild(newGroup, 1)
m.content.replaceChild(newGroup, 0)
else
m.scene.appendChild(newGroup)
m.content.appendChild(newGroup)
end if
'observe info about new group, set overhang title, etc.
@ -56,7 +56,7 @@ end sub
'
' Remove the current group and load the last group from the stack
sub pop()
sub popScene()
group = m.groups.pop()
if group <> invalid
if group.isSubType("JFGroup")
@ -73,7 +73,6 @@ sub pop()
group = m.groups.peek()
if group <> invalid
registerOverhangData(group)
'm.scene.callFunc("registerOverhangData")
if group.subtype() = "Home"
currentTime = CreateObject("roDateTime").AsSeconds()
@ -85,7 +84,7 @@ sub pop()
group.visible = true
m.scene.replaceChild(group, 1)
m.content.replaceChild(group, 0)
' Restore focus
if group.lastFocus <> invalid
@ -103,11 +102,19 @@ end sub
'
' Return group at top of stack without removing
function peek() as object
function getActiveScene() as object
return m.groups.peek()
end function
'
' Clear all content from group stack
sub clearScenes()
m.content.removeChildrenIndex(m.content.getChildCount(), 0)
m.groups = []
end sub
'
' Register observers for overhang data
sub registerOverhangData(group)

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<component name="SceneManager" extends="ContentNode">
<interface>
<function name="pushScene" />
<function name="popScene" />
<function name="getActiveScene" />
<function name="clearScenes" />
<function name="resetTime" />
<field id="currentUser" type="string" onChange="updateUser" />
</interface>
<script type="text/brightscript" uri="SceneManager.brs" />
</component>

View File

@ -21,9 +21,9 @@ sub Main (args as dynamic) as void
playstateTask = CreateObject("roSGNode", "PlaystateTask")
playstateTask.id = "playstateTask"
groupStack = CreateObject("roSGNode", "GroupStack")
sceneManager = CreateObject("roSGNode", "SceneManager")
m.global.addFields({ app_loaded: false, playstateTask: playstateTask, groupStack: groupStack })
m.global.addFields({ app_loaded: false, playstateTask: playstateTask, sceneManager: sceneManager })
app_start:
' First thing to do is validate the ability to use the API
@ -35,11 +35,11 @@ sub Main (args as dynamic) as void
wipe_groups()
' load home page
groupStack.currentUser = m.user.Name
sceneManager.currentUser = m.user.Name
group = CreateHomeGroup()
group.userConfig = m.user.configuration
group.callFunc("loadLibraries")
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
m.scene.observeField("exit", m.port)
@ -57,7 +57,7 @@ sub Main (args as dynamic) as void
video = CreateVideoPlayerGroup(args.contentId)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
dialog.id = "OKDialog"
@ -81,7 +81,7 @@ sub Main (args as dynamic) as void
else if isNodeEvent(msg, "exit")
return
else if isNodeEvent(msg, "closeSidePanel")
group = groupStack.callFunc("peek")
group = sceneManager.callFunc("getActiveScene")
if group.lastFocus <> invalid
group.lastFocus.setFocus(true)
else
@ -94,7 +94,7 @@ sub Main (args as dynamic) as void
if itemNode.type = "Episode" or itemNode.type = "Movie" or itemNode.type = "Video"
video = CreateVideoPlayerGroup(itemNode.id)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
end if
end if
else if isNodeEvent(msg, "selectedItem")
@ -102,22 +102,22 @@ sub Main (args as dynamic) as void
selectedItem = msg.getData()
if selectedItem.type = "CollectionFolder" or selectedItem.type = "UserView" or selectedItem.type = "Folder" or selectedItem.type = "Channel" or selectedItem.type = "Boxset"
group = CreateItemGrid(selectedItem)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if selectedItem.type = "Episode"
' play episode
' todo: create an episode page to link here
video_id = selectedItem.id
video = CreateVideoPlayerGroup(video_id)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
end if
else if selectedItem.type = "Series"
group = CreateSeriesDetailsGroup(selectedItem.json)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if selectedItem.type = "Movie"
' open movie detail page
group = CreateMovieDetailsGroup(selectedItem)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if selectedItem.type = "TvChannel" or selectedItem.type = "Video"
' play channel feed
video_id = selectedItem.id
@ -131,7 +131,7 @@ sub Main (args as dynamic) as void
dialog.close = true
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
dialog.id = "OKDialog"
@ -149,12 +149,12 @@ sub Main (args as dynamic) as void
' If you select a movie from ANYWHERE, follow this flow
node = getMsgPicker(msg, "picker")
group = CreateMovieDetailsGroup(node)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if isNodeEvent(msg, "seriesSelected")
' If you select a TV Series from ANYWHERE, follow this flow
node = getMsgPicker(msg, "picker")
group = CreateSeriesDetailsGroup(node)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if isNodeEvent(msg, "seasonSelected")
' If you select a TV Season from ANYWHERE, follow this flow
ptr = msg.getData()
@ -162,14 +162,14 @@ sub Main (args as dynamic) as void
series = msg.getRoSGNode()
node = series.seasonData.items[ptr[1]]
group = CreateSeasonDetailsGroup(series.itemContent, node)
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if isNodeEvent(msg, "episodeSelected")
' If you select a TV Episode from ANYWHERE, follow this flow
node = getMsgPicker(msg, "picker")
video_id = node.id
video = CreateVideoPlayerGroup(video_id)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
end if
else if isNodeEvent(msg, "search_value")
query = msg.getRoSGNode().search_value
@ -195,11 +195,11 @@ sub Main (args as dynamic) as void
else
group = CreateMovieDetailsGroup(node)
end if
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
else if isNodeEvent(msg, "buttonSelected")
' If a button is selected, we have some determining to do
btn = getButton(msg)
group = groupStack.callFunc("peek")
group = sceneManager.callFunc("getActiveScene")
if btn <> invalid and btn.id = "play-button"
' Check is a specific Audio Stream was selected
audio_stream_idx = 1
@ -210,7 +210,7 @@ sub Main (args as dynamic) as void
video_id = group.id
video = CreateVideoPlayerGroup(video_id, audio_stream_idx)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
end if
else if btn <> invalid and btn.id = "watched-button"
movie = group.itemContent
@ -238,7 +238,7 @@ sub Main (args as dynamic) as void
end if
else if isNodeEvent(msg, "optionSelected")
button = msg.getRoSGNode()
group = groupStack.callFunc("peek")
group = sceneManager.callFunc("getActiveScene")
if button.id = "goto_search"
' Exit out of the side panel
panel = group.findNode("options")
@ -249,7 +249,7 @@ sub Main (args as dynamic) as void
group.setFocus(true)
end if
group = CreateSearchPage()
groupStack.callFunc("push", group)
sceneManager.callFunc("pushScene", group)
group.findNode("SearchBox").findNode("search-input").setFocus(true)
group.findNode("SearchBox").findNode("search-input").active = true
else if button.id = "change_server"
@ -286,16 +286,16 @@ sub Main (args as dynamic) as void
if node.state = "finished"
node.control = "stop"
if node.showID = invalid
groupStack.callFunc("pop")
sceneManager.callFunc("popScene")
else
autoPlayNextEpisode(node.id, node.showID)
end if
end if
else if type(msg) = "roDeviceInfoEvent"
event = msg.GetInfo()
group = groupStack.callFunc("peek")
group = sceneManager.callFunc("getActiveScene")
if event.exitedScreensaver = true
groupStack.callFunc("resetTime")
sceneManager.callFunc("resetTime")
if group.subtype() = "Home"
currentTime = CreateObject("roDateTime").AsSeconds()
group.timeLastRefresh = currentTime
@ -312,7 +312,7 @@ sub Main (args as dynamic) as void
if info.DoesExist("mediatype") and info.DoesExist("contentid")
video = CreateVideoPlayerGroup(info.contentId)
if video <> invalid
groupStack.callFunc("push", video)
sceneManager.callFunc("pushScene", video)
else
dialog = createObject("roSGNode", "Dialog")
dialog.id = "OKDialog"
@ -441,8 +441,8 @@ end sub
sub wipe_groups()
' The 1 remaining child should be the overhang
while m.scene.getChildCount() > 1
m.scene.removeChildIndex(1)
while m.scene.getChildCount() > 2
m.scene.removeChildIndex(2)
end while
end sub

View File

@ -221,19 +221,19 @@ sub autoPlayNextEpisode(videoID as string, showID as string)
if data <> invalid and data.Items.Count() = 2
' remove finished video node
m.global.groupStack.callFunc("pop")
m.global.sceneManager.callFunc("popScene")
' setup new video node
nextVideo = CreateVideoPlayerGroup(data.Items[1].Id)
if nextVideo <> invalid
m.global.groupStack.callFunc("push", nextVideo)
m.global.sceneManager.callFunc("pushScene", nextVideo)
else
m.global.groupStack.callFunc("pop")
m.global.sceneManager.callFunc("popScene")
end if
else
' can't play next episode
m.global.groupStack.callFunc("pop")
m.global.sceneManager.callFunc("popScene")
end if
else
m.global.groupStack.callFunc("pop")
m.global.sceneManager.callFunc("popScene")
end if
end sub

View File

@ -28,8 +28,8 @@ sub SignOut()
unset_setting("password")
end if
unset_setting("active_user")
m.global.groupStack.currentUser = ""
group = m.global.groupStack.peek()
m.global.sceneManager.currentUser = ""
group = m.global.sceneManager.callFunc("getActiveScene")
group.optionsAvailable = false
end sub