Skip to content

Commit

Permalink
Add "medium ignored" assets (exist on screen)
Browse files Browse the repository at this point in the history
  • Loading branch information
dtcooper committed Aug 15, 2023
1 parent e490dfd commit af6979b
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 43 deletions.
6 changes: 3 additions & 3 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"svelte-dev": "SVELTE_DEVTOOLS=1 npm run dev",
"dev:electron": "npm-run-all dev:electron:wait dev:electron:run",
"dev:electron:wait": "wait-on -l dist/app.css dist/app.js dist/main.js http://localhost:3000/",
"dev:electron:run": "run-script-os",
"dev:electron:run": "ELECTRON_DISABLE_SECURITY_WARNINGS=true run-script-os",
"dev:electron:run:linux": "./scripts/debian/start-tomato.sh",
"dev:electron:run:windows": "ELECTRON_DISABLE_SECURITY_WARNINGS=true ELECTRON_ENABLE_LOGGING=true electron-forge start $DEV_EXTRA_FORGE_FLAGS",
"dev:electron:run:default": "ELECTRON_DISABLE_SECURITY_WARNINGS=true electron-forge start $DEV_EXTRA_FORGE_FLAGS",
"dev:electron:run:windows": "ELECTRON_ENABLE_LOGGING=true electron-forge start $DEV_EXTRA_FORGE_FLAGS",
"dev:electron:run:default": "electron-forge start $DEV_EXTRA_FORGE_FLAGS",
"make": "NODE_ENV=production npm-run-all clean build make:forge",
"package": "NODE_ENV=production npm-run-all clean build package:forge",
"make:forge": "electron-forge make",
Expand Down
4 changes: 2 additions & 2 deletions client/src/main/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import autorenew from "@iconify/icons-mdi/autorenew"
import cogOutline from "@iconify/icons-mdi/cog-outline"
import fullscreenExit from "@iconify/icons-mdi/fullscreen-exit"
import fullscreenIcon from '@iconify/icons-mdi/fullscreen'
import fullscreenIcon from "@iconify/icons-mdi/fullscreen"
import { conn } from "../stores/connection"
import { config, userConfig, isFullscreen, setFullscreen } from "../stores/config"
import { syncProgress } from "../stores/db"
Expand All @@ -26,7 +26,7 @@
{#if $config.UI_MODES.includes(0) && $userConfig.uiMode >= 1}
<button class="btn btn-accent" on:click={() => ($userConfig.uiMode = 0)}>← Back to simple view</button>
{/if}
<div class="tooltip tooltip-bottom" data-tip={`${$isFullscreen ? 'Exit' : 'Enter'} fullscreen mode`}>
<div class="tooltip tooltip-bottom" data-tip={`${$isFullscreen ? "Exit" : "Enter"} fullscreen mode`}>
<button class="btn btn-circle btn-ghost" on:click={() => setFullscreen(!$isFullscreen)}>
<Icon icon={$isFullscreen ? fullscreenExit : fullscreenIcon} class="h-8 w-8" />
</button>
Expand Down
32 changes: 17 additions & 15 deletions client/src/main/Player.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,21 @@
document.getElementById("playlist").scroll({ top: 0, behavior: "smooth" })
}
window.durationOfItems = () => {
return items.reduce((s, item) => s + item.remaining, 0)
const generateStopsetHelper = (likelyPlayTime, generatedId) => {
return $db.generateStopset(
likelyPlayTime,
// Medium ignored assets (everything at exists on the screen right now in items list)
new Set(
items
.filter((i) => i.type === "stopset")
.map((s) => s.items.map((a) => a.id))
.flat(1)
),
$config.END_DATE_PRIORITY_WEIGHT_MULTIPLIER,
processItem,
updateUI,
generatedId
)
}
const addStopset = () => {
Expand All @@ -50,12 +63,7 @@
const secondsUntilPlay = items.reduce((s, item) => s + item.remaining, 0)
const likelyPlayTime = dayjs().add(secondsUntilPlay, "seconds")
let generatedStopset = $db.generateStopset(
likelyPlayTime,
$config.END_DATE_PRIORITY_WEIGHT_MULTIPLIER,
processItem,
updateUI
)
let generatedStopset = generateStopsetHelper(likelyPlayTime)
if (generatedStopset) {
// Always add a stopset AND THEN a wait interval
Expand Down Expand Up @@ -91,13 +99,7 @@
// swap it out, maintaining generatedId so UI doesn't trigger a transition
const secondsUntilPlay = items.slice(0, nextStopset).reduce((s, item) => s + item.remaining, 0)
const likelyPlayTime = dayjs().add(secondsUntilPlay, "seconds")
let generatedStopset = $db.generateStopset(
likelyPlayTime,
$config.END_DATE_PRIORITY_WEIGHT_MULTIPLIER,
processItem,
updateUI,
items[nextStopset].generatedId
)
let generatedStopset = generateStopsetHelper(likelyPlayTime, items[nextStopset].generatedId)
if (generatedStopset) {
items[nextStopset].done(true) // Mark swap out one as done
items[nextStopset] = generatedStopset
Expand Down
64 changes: 42 additions & 22 deletions client/src/stores/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,30 +175,44 @@ class Rotator extends HydratableObject {
this.color = colors.find((c) => c.name === color)
}

getAsset(softIgnoreIds = new Set(), hardIgnoreIds = new Set(), startTime, endDateMultiplier) {
getAsset(
softIgnoreIds = new Set(),
mediumIgnoreIds = new Set(),
hardIgnoreIds = new Set(),
startTime,
endDateMultiplier
) {
// soft ignored = played within a recent amount of time
// medium ignored = exists on screen already
// hard ignored = exists within the stopset being generated
const activeAssets = filterItemsByActive(this.assets, startTime)
const hardIgnoredAssets = activeAssets.filter((a) => !hardIgnoreIds.has(a.id))
const softIgnoredAssets = hardIgnoredAssets.filter((a) => !softIgnoreIds.has(a.id))

const tries = [softIgnoredAssets, hardIgnoredAssets]
const mediumIgnoredAssets = hardIgnoredAssets.filter((a) => !mediumIgnoreIds.has(a.id))
const softIgnoredAssets = mediumIgnoredAssets.filter((a) => !softIgnoreIds.has(a.id))

const tries = [
["soft ignored", softIgnoredAssets],
["medium ignored", mediumIgnoredAssets],
["hard ignored", hardIgnoredAssets]
]
if (get(config).ALLOW_REPEATS_IN_STOPSET) {
tries.push(activeAssets)
// ignore hard ignored
tries.push(["all active", activeAssets])
}

let asset = pickRandomItemByWeight(softIgnoredAssets, endDateMultiplier, startTime)
if (!asset) {
console.log(`Failed to get an asset form soft ignores [rotator = ${this.name}]`)
asset = pickRandomItemByWeight(hardIgnoredAssets, endDateMultiplier, startTime)
if (!asset) {
console.log(`Failed to pick an asset from hard ignores [rotator = ${this.name}]`)
if (get(config).ALLOW_REPEATS_IN_STOPSET) {
asset = pickRandomItemByWeight(activeAssets, endDateMultiplier, startTime)
}
let asset = null
let assetListName = ""

for (const [name, assets] of tries) {
asset = pickRandomItemByWeight(assets, endDateMultiplier, startTime)
if (asset) {
assetListName = name
break
}
}

if (asset) {
console.log(`Picked asset ${asset.id} [rotator = ${this.name}]`)
console.log(`Picked asset ${asset.id} from ${assetListName} asset list: ${asset.name} [rotator = ${this.name}]`)
} else {
console.warn(`Failed to pick an asset entirely! [rotator = ${this.name}]`)
}
Expand All @@ -214,7 +228,7 @@ class RotatorsMap extends Map {
}

class Stopset extends AssetStopsetHydratableObject {
generate(startTime, endDateMultiplier, doneCallback, updateCallback, generatedId) {
generate(startTime, mediumIgnoreIds, endDateMultiplier, doneCallback, updateCallback, generatedId) {
const hardIgnoreIds = new Set()
let softIgnoreIds = undefined

Expand All @@ -230,12 +244,9 @@ class Stopset extends AssetStopsetHydratableObject {

const items = []
for (const rotator of this.rotators) {
const asset = rotator.getAsset(softIgnoreIds, hardIgnoreIds, startTime, endDateMultiplier)
const asset = rotator.getAsset(softIgnoreIds, mediumIgnoreIds, hardIgnoreIds, startTime, endDateMultiplier)
if (asset) {
hardIgnoreIds.add(asset.id)
/// XXX should this be marked by player code only?
/// Except then the next stopset may include it, so maybe this _is_ the spot for marking
DB.markPlayed(asset)
startTime = startTime.add(asset.duration, "seconds")
}
items.push({ rotator, asset })
Expand Down Expand Up @@ -317,12 +328,19 @@ class DB {
}
}

generateStopset(startTime, endDateMultiplier, doneCallback, updateCallback, generatedId) {
generateStopset(startTime, mediumIgnoreIds, endDateMultiplier, doneCallback, updateCallback, generatedId) {
let generated = null
for (let i = 0; i < 3; i++) {
const stopset = pickRandomItemByWeight(filterItemsByActive(this.stopsets, startTime))
if (stopset) {
generated = stopset.generate(startTime, endDateMultiplier, doneCallback, updateCallback, generatedId)
generated = stopset.generate(
startTime,
mediumIgnoreIds,
endDateMultiplier,
doneCallback,
updateCallback,
generatedId
)
if (generated.items.some((item) => item.playable)) {
return generated
}
Expand Down Expand Up @@ -421,4 +439,6 @@ export const clearSoftIgnoredAssets = () => {
window.localStorage.removeItem("soft-ignored-ids")
}

export const markPlayed = (asset) => DB.markPlayed(asset)

setInterval(() => DB.cleanup(), 45 * 60 * 60) // Clean up every 45 minutes
4 changes: 3 additions & 1 deletion client/src/stores/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { derived, get, writable } from "svelte/store"
import { prettyDuration } from "../utils"
import { log } from "./client-logs"
import { config } from "./config"
import { markPlayed } from "./db"

export const speaker = persisted("speaker", null)
export const speakers = writable([])
Expand Down Expand Up @@ -163,7 +164,8 @@ class PlayableAsset extends GeneratedStopsetAssetBase {
}

play() {
console.log(`Playing ${this.name}`)
console.log(`Playing ${this.id}: ${this.name}`)
markPlayed(this)

if (this.error) {
this.done()
Expand Down

0 comments on commit af6979b

Please sign in to comment.