mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
is the new musicplayer working?
This commit is contained in:
@@ -137,18 +137,6 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*ingame.musicStreamer.addMusicStartHook { music ->
|
|
||||||
setMusicName(music.name)
|
|
||||||
if (mode <= MODE_PLAYING)
|
|
||||||
transitionRequest = MODE_PLAYING
|
|
||||||
}
|
|
||||||
|
|
||||||
ingame.musicStreamer.addMusicStopHook { music ->
|
|
||||||
setIntermission()
|
|
||||||
if (mode <= MODE_PLAYING)
|
|
||||||
transitionRequest = MODE_IDLE
|
|
||||||
}*/
|
|
||||||
|
|
||||||
setPlaylistDisplayVars(playlist)
|
setPlaylistDisplayVars(playlist)
|
||||||
|
|
||||||
return playlist
|
return playlist
|
||||||
@@ -447,18 +435,6 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
if (index < currentPlaylist.musicList.size) {
|
if (index < currentPlaylist.musicList.size) {
|
||||||
// if selected song != currently playing
|
// if selected song != currently playing
|
||||||
if (App.audioMixer.musicTrack.currentTrack == null || currentPlaylist.musicList[index] != App.audioMixer.musicTrack.currentTrack) {
|
if (App.audioMixer.musicTrack.currentTrack == null || currentPlaylist.musicList[index] != App.audioMixer.musicTrack.currentTrack) {
|
||||||
// FIXME the olde way -- must be replaced with one that utilises MusicService
|
|
||||||
// rebuild playlist
|
|
||||||
//ingame.backgroundMusicPlayer.queueIndexFromPlaylist(index)
|
|
||||||
// fade out
|
|
||||||
/*App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
|
||||||
if (!shouldPlayerBeDisabled) {
|
|
||||||
ingame.backgroundMusicPlayer.startMusic(this) // required for "intermittent" mode
|
|
||||||
iHitTheStopButton = false
|
|
||||||
stopRequested = false
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
MusicService.playNthSongInPlaylist(index) {
|
MusicService.playNthSongInPlaylist(index) {
|
||||||
iHitTheStopButton = false
|
iHitTheStopButton = false
|
||||||
stopRequested = false
|
stopRequested = false
|
||||||
@@ -476,22 +452,9 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
// if selected album is not the same album currently playing, queue that album immediately
|
// if selected album is not the same album currently playing, queue that album immediately
|
||||||
// (navigating into the selected album involves too much complication :p)
|
// (navigating into the selected album involves too much complication :p)
|
||||||
if (MusicService.currentPlaylist?.source != albumsList[index].canonicalPath) {
|
if (MusicService.currentPlaylist?.source != albumsList[index].canonicalPath) {
|
||||||
// FIXME the olde way -- must be replaced with one that utilises MusicService
|
|
||||||
// fade out
|
|
||||||
/*App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
|
||||||
loadNewAlbum(albumsList[index])
|
|
||||||
if (!shouldPlayerBeDisabled) {
|
|
||||||
ingame.backgroundMusicPlayer.startMusic(this) // required for "intermittent" mode
|
|
||||||
iHitTheStopButton = false
|
|
||||||
stopRequested = false
|
|
||||||
}
|
|
||||||
resetPlaylistScroll(App.audioMixer.musicTrack.nextTrack as? MusicContainer)
|
|
||||||
}*/
|
|
||||||
|
|
||||||
val playlist = loadNewAlbum(albumsList[index])
|
val playlist = loadNewAlbum(albumsList[index])
|
||||||
MusicService.putNewPlaylist(playlist) {
|
MusicService.putNewPlaylistAndResumePlayback(playlist) {
|
||||||
resetPlaylistScroll(App.audioMixer.musicTrack.nextTrack as? MusicContainer)
|
resetPlaylistScroll(App.audioMixer.musicTrack.nextTrack as? MusicContainer)
|
||||||
MusicService.resumePlaylistPlayback({}, {})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -505,8 +468,27 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
// printdbg(this, "mode = $mode; req = $transitionRequest")
|
// printdbg(this, "mode = $mode; req = $transitionRequest")
|
||||||
|
|
||||||
|
|
||||||
|
// update music name disp
|
||||||
|
val musicTrack = App.audioMixer.musicTrack
|
||||||
|
val musicTrackPlaying = musicTrack.isPlaying
|
||||||
|
val musicNow = musicTrack.currentTrack
|
||||||
|
//// music changed, do something
|
||||||
|
if ((oldMusicTrackPlaying && !musicTrack.isPlaying) || (oldSong != null && musicNow == null)) {
|
||||||
|
setIntermission()
|
||||||
|
if (mode <= MODE_PLAYING && !transitionOngoing) transitionRequest = MODE_IDLE
|
||||||
|
}
|
||||||
|
else if ((!oldMusicTrackPlaying && musicTrack.isPlaying && musicNow != null) || (oldSong == null && musicNow != null) || (musicNow != oldSong && musicNow != null)) {
|
||||||
|
setMusicName(musicNow.name)
|
||||||
|
if (mode <= MODE_PLAYING && !transitionOngoing) transitionRequest = MODE_PLAYING
|
||||||
|
}
|
||||||
|
oldSong = musicNow
|
||||||
|
oldMusicTrackPlaying = musicTrackPlaying
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var oldSong: AudioBank? = null
|
||||||
|
private var oldMusicTrackPlaying = false
|
||||||
|
|
||||||
private var iHitTheStopButton = false
|
private var iHitTheStopButton = false
|
||||||
private var stopRequested = false
|
private var stopRequested = false
|
||||||
|
|
||||||
@@ -536,18 +518,6 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private fun getPrevSongFromPlaylist(): MusicContainer? {
|
|
||||||
val list = songsInGovernor.slice(songsInGovernor.indices) // make copy of the list
|
|
||||||
val nowPlaying = App.audioMixer.musicTrack.currentTrack ?: return null
|
|
||||||
|
|
||||||
// find current index
|
|
||||||
val currentIndex = list.indexOfFirst { it == nowPlaying }
|
|
||||||
if (currentIndex < 0) return null
|
|
||||||
|
|
||||||
val prevIndex = (currentIndex - 1).fmod(list.size)
|
|
||||||
return list[prevIndex]
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// private fun smoothstep(x: Float) = (x*x*(3f-2f*x)).coerceIn(0f, 1f)
|
// private fun smoothstep(x: Float) = (x*x*(3f-2f*x)).coerceIn(0f, 1f)
|
||||||
// private fun smootherstep(x: Float) = (x*x*x*(x*(6f*x-15f)+10f)).coerceIn(0f, 1f)
|
// private fun smootherstep(x: Float) = (x*x*x*(x*(6f*x-15f)+10f)).coerceIn(0f, 1f)
|
||||||
|
|
||||||
@@ -710,7 +680,7 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
// debug codes
|
// debug codes
|
||||||
//// transaction state
|
//// transaction state
|
||||||
if (MusicService.transactionLocked) {
|
/*if (MusicService.transactionLocked) {
|
||||||
batch.color = Color.RED
|
batch.color = Color.RED
|
||||||
Toolkit.drawTextCentered(batch, App.fontSmallNumbers, "LOCKED", Toolkit.drawWidth, 0, _posY.toInt() + height + 5)
|
Toolkit.drawTextCentered(batch, App.fontSmallNumbers, "LOCKED", Toolkit.drawWidth, 0, _posY.toInt() + height + 5)
|
||||||
}
|
}
|
||||||
@@ -736,6 +706,7 @@ class MusicPlayerControl(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
batch.color = Color.LIGHT_GRAY
|
batch.color = Color.LIGHT_GRAY
|
||||||
App.fontSmallNumbers.draw(batch, "Playlist InternalIndices", 10f, App.scr.hf - 30f)
|
App.fontSmallNumbers.draw(batch, "Playlist InternalIndices", 10f, App.scr.hf - 30f)
|
||||||
App.fontSmallNumbers.draw(batch, "..", 10f, App.scr.hf - 16f)
|
App.fontSmallNumbers.draw(batch, "..", 10f, App.scr.hf - 16f)
|
||||||
|
*/
|
||||||
// end of debug codes
|
// end of debug codes
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ playback cannot change its sampling rate mid-stream.
|
|||||||
The audio engine cannot resample an audio file with sampling rate greater than 48000 Hz, nor is capable
|
The audio engine cannot resample an audio file with sampling rate greater than 48000 Hz, nor is capable
|
||||||
of reading anything that is not in 16-bit bit-depth.
|
of reading anything that is not in 16-bit bit-depth.
|
||||||
|
|
||||||
|
## Ogg Album Art Incompatibility
|
||||||
|
|
||||||
|
Ogg files with album arts are not reliably recognised. Remove them using the following FFmpeg command:
|
||||||
|
|
||||||
|
ffmpeg -i inputfile.ogg -map a -c copy outputfile.ogg
|
||||||
|
|
||||||
## tl;dr
|
## tl;dr
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -67,7 +67,7 @@ object MusicService : TransactionListener() {
|
|||||||
currentPlaybackState.set(STATE_PLAYING)
|
currentPlaybackState.set(STATE_PLAYING)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getRandomMusicInterval() = 20f + Math.random().toFloat() * 4f // longer gap (20s to 24s)
|
fun getRandomMusicInterval() = 16f + Math.random().toFloat() * 4f // longer gap (16s to 20s)
|
||||||
|
|
||||||
private fun enterIntermissionAndWaitForPlaylist() {
|
private fun enterIntermissionAndWaitForPlaylist() {
|
||||||
val djmode = currentPlaylist?.diskJockeyingMode ?: "intermittent"
|
val djmode = currentPlaylist?.diskJockeyingMode ?: "intermittent"
|
||||||
@@ -85,7 +85,7 @@ object MusicService : TransactionListener() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onMusicFinishing(audio: AudioBank) {
|
fun onMusicFinishing(audio: AudioBank) {
|
||||||
printdbg(this, "onMusicFinishing ${audio.name}")
|
// printdbg(this, "onMusicFinishing ${audio.name}")
|
||||||
enterIntermissionAndWaitForPlaylist()
|
enterIntermissionAndWaitForPlaylist()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,19 +108,19 @@ object MusicService : TransactionListener() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(state: TransactionState) {
|
override fun onSuccess(state: TransactionState) {
|
||||||
printdbg(this, "FIREPLAY started music (${nextMusic.name})")
|
// printdbg(this, "FIREPLAY started music (${nextMusic.name})")
|
||||||
enterSTATE_PLAYING()
|
currentPlaybackState.set(STATE_PLAYING) // force PLAYING
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(e: Throwable, state: TransactionState) {
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
printdbg(this, "FIREPLAY resume OK but startMusic failed, entering intermission")
|
// printdbg(this, "FIREPLAY resume OK but startMusic failed, entering intermission")
|
||||||
enterIntermissionAndWaitForPlaylist() // will try again
|
enterIntermissionAndWaitForPlaylist() // will try again
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/* onFailure: (Throwable) -> Unit */
|
/* onFailure: (Throwable) -> Unit */
|
||||||
{
|
{
|
||||||
printdbg(this, "FIREPLAY resume failed, entering intermission")
|
// printdbg(this, "FIREPLAY resume failed, entering intermission")
|
||||||
enterIntermissionAndWaitForPlaylist() // will try again
|
enterIntermissionAndWaitForPlaylist() // will try again
|
||||||
},
|
},
|
||||||
// onFinally: () -> Unit
|
// onFinally: () -> Unit
|
||||||
@@ -130,7 +130,7 @@ object MusicService : TransactionListener() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printdbg(this, "FIREPLAY no-op: playTransaction is ongoing")
|
// printdbg(this, "FIREPLAY no-op: playTransaction is ongoing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
STATE_PLAYING -> {
|
STATE_PLAYING -> {
|
||||||
@@ -140,7 +140,9 @@ object MusicService : TransactionListener() {
|
|||||||
waitAkku += delta
|
waitAkku += delta
|
||||||
|
|
||||||
if (waitAkku >= waitTime && currentPlaylist != null) {
|
if (waitAkku >= waitTime && currentPlaylist != null) {
|
||||||
enterSTATE_FIREPLAY()
|
// force FIREPLAY
|
||||||
|
waitAkku = 0f
|
||||||
|
currentPlaybackState.set(STATE_FIREPLAY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,8 +242,99 @@ object MusicService : TransactionListener() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts the given playlist to this object if the transaction successes. If the given playlist is same as the
|
||||||
|
* current playlist, the transaction will successfully finish immediately; otherwise the given playlist will
|
||||||
|
* be reset as soon as the transaction starts. Note that the resetting behaviour is NOT atomic. (the given
|
||||||
|
* playlist will stay in reset state even if the transaction fails)
|
||||||
|
*
|
||||||
|
* When the transaction was successful, the old playlist gets disposed of, then the songFinishedHook of
|
||||||
|
* the songs in the new playlist will be overwritten, before `onSuccess` is called.
|
||||||
|
*
|
||||||
|
* The old playlist will be disposed of if and only if the transaction was successful.
|
||||||
|
*
|
||||||
|
* @param playlist An instance of a [TerrarumMusicPlaylist] to be changed into
|
||||||
|
* @param onSuccess What to do after the transaction
|
||||||
|
*/
|
||||||
|
private fun createTransactionPlaylistChangeAndPlayImmediately(playlist: TerrarumMusicPlaylist, onSuccess: () -> Unit): Transaction {
|
||||||
|
return object : Transaction {
|
||||||
|
var oldPlaylist: TerrarumMusicPlaylist? = null
|
||||||
|
var oldState = currentPlaybackState.get()
|
||||||
|
var oldAkku = waitAkku
|
||||||
|
var oldTime = waitTime
|
||||||
|
|
||||||
|
override fun start(state: TransactionState) {
|
||||||
|
oldPlaylist = state["currentPlaylist"] as TerrarumMusicPlaylist?
|
||||||
|
if (oldPlaylist == playlist) return
|
||||||
|
|
||||||
|
playlist.reset()
|
||||||
|
|
||||||
|
// request fadeout
|
||||||
|
if (App.audioMixer.musicTrack.isPlaying) {
|
||||||
|
var fadedOut = false
|
||||||
|
|
||||||
|
App.audioMixer.requestFadeOut(App.audioMixer.musicTrack) {
|
||||||
|
// put new playlist
|
||||||
|
state["currentPlaylist"] = playlist
|
||||||
|
|
||||||
|
fadedOut = true
|
||||||
|
}
|
||||||
|
|
||||||
|
waitUntil { fadedOut }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// put new playlist
|
||||||
|
state["currentPlaylist"] = playlist
|
||||||
|
}
|
||||||
|
|
||||||
|
oldState = currentPlaybackState.get()
|
||||||
|
oldAkku = waitAkku
|
||||||
|
oldTime = waitTime
|
||||||
|
|
||||||
|
enterSTATE_INTERMISSION(0f)
|
||||||
|
enterSTATE_FIREPLAY()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess(state: TransactionState) {
|
||||||
|
oldPlaylist?.dispose()
|
||||||
|
|
||||||
|
(state["currentPlaylist"] as TerrarumMusicPlaylist?)?.let {
|
||||||
|
// set songFinishedHook for every song
|
||||||
|
it.musicList.forEach {
|
||||||
|
it.songFinishedHook = {
|
||||||
|
onMusicFinishing(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set gaplessness of the Music track
|
||||||
|
App.audioMixer.musicTrack.let { track ->
|
||||||
|
track.doGaplessPlayback = (it.diskJockeyingMode == "continuous")
|
||||||
|
if (track.doGaplessPlayback) {
|
||||||
|
track.pullNextTrack = {
|
||||||
|
track.currentTrack = MusicService.currentPlaylist!!.queueNext()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
|
e.printStackTrace()
|
||||||
|
|
||||||
|
currentPlaybackState.set(oldState)
|
||||||
|
waitAkku = oldAkku
|
||||||
|
waitTime = oldTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createTransactionForNextMusicInPlaylist(onSuccess: () -> Unit): Transaction {
|
private fun createTransactionForNextMusicInPlaylist(onSuccess: () -> Unit): Transaction {
|
||||||
return object : Transaction {
|
return object : Transaction {
|
||||||
|
var oldState = currentPlaybackState.get()
|
||||||
|
var oldAkku = waitAkku
|
||||||
|
var oldTime = waitTime
|
||||||
|
|
||||||
override fun start(state: TransactionState) {
|
override fun start(state: TransactionState) {
|
||||||
var fadedOut = false
|
var fadedOut = false
|
||||||
var err: Throwable? = null
|
var err: Throwable? = null
|
||||||
@@ -259,21 +352,34 @@ object MusicService : TransactionListener() {
|
|||||||
|
|
||||||
waitUntil { fadedOut || err != null }
|
waitUntil { fadedOut || err != null }
|
||||||
if (err != null) throw err!!
|
if (err != null) throw err!!
|
||||||
|
|
||||||
|
oldState = currentPlaybackState.get()
|
||||||
|
oldAkku = waitAkku
|
||||||
|
oldTime = waitTime
|
||||||
|
|
||||||
|
enterSTATE_INTERMISSION(0f)
|
||||||
|
enterSTATE_FIREPLAY()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(state: TransactionState) {
|
override fun onSuccess(state: TransactionState) {
|
||||||
enterSTATE_INTERMISSION(0f)
|
|
||||||
enterSTATE_FIREPLAY()
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
override fun onFailure(e: Throwable, state: TransactionState) {
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
|
currentPlaybackState.set(oldState)
|
||||||
|
waitAkku = oldAkku
|
||||||
|
waitTime = oldTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTransactionForPrevMusicInPlaylist(onSuccess: () -> Unit): Transaction {
|
private fun createTransactionForPrevMusicInPlaylist(onSuccess: () -> Unit): Transaction {
|
||||||
return object : Transaction {
|
return object : Transaction {
|
||||||
|
var oldState = currentPlaybackState.get()
|
||||||
|
var oldAkku = waitAkku
|
||||||
|
var oldTime = waitTime
|
||||||
|
|
||||||
override fun start(state: TransactionState) {
|
override fun start(state: TransactionState) {
|
||||||
var fadedOut = false
|
var fadedOut = false
|
||||||
var err: Throwable? = null
|
var err: Throwable? = null
|
||||||
@@ -294,11 +400,16 @@ object MusicService : TransactionListener() {
|
|||||||
|
|
||||||
waitUntil { fadedOut || err != null }
|
waitUntil { fadedOut || err != null }
|
||||||
if (err != null) throw err!!
|
if (err != null) throw err!!
|
||||||
|
|
||||||
|
oldState = currentPlaybackState.get()
|
||||||
|
oldAkku = waitAkku
|
||||||
|
oldTime = waitTime
|
||||||
|
|
||||||
|
enterSTATE_INTERMISSION(0f)
|
||||||
|
enterSTATE_FIREPLAY()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(state: TransactionState) {
|
override fun onSuccess(state: TransactionState) {
|
||||||
enterSTATE_INTERMISSION(0f)
|
|
||||||
enterSTATE_FIREPLAY()
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
override fun onFailure(e: Throwable, state: TransactionState) {
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
@@ -306,12 +417,20 @@ object MusicService : TransactionListener() {
|
|||||||
(state["currentPlaylist"] as TerrarumMusicPlaylist).queueNext()
|
(state["currentPlaylist"] as TerrarumMusicPlaylist).queueNext()
|
||||||
|
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
|
currentPlaybackState.set(oldState)
|
||||||
|
waitAkku = oldAkku
|
||||||
|
waitTime = oldTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createTransactionForNthMusicInPlaylist(index: Int, onSuccess: () -> Unit): Transaction {
|
private fun createTransactionForNthMusicInPlaylist(index: Int, onSuccess: () -> Unit): Transaction {
|
||||||
return object : Transaction {
|
return object : Transaction {
|
||||||
|
var oldState = currentPlaybackState.get()
|
||||||
|
var oldAkku = waitAkku
|
||||||
|
var oldTime = waitTime
|
||||||
|
|
||||||
override fun start(state: TransactionState) {
|
override fun start(state: TransactionState) {
|
||||||
var fadedOut = false
|
var fadedOut = false
|
||||||
var err: Throwable? = null
|
var err: Throwable? = null
|
||||||
@@ -331,15 +450,24 @@ object MusicService : TransactionListener() {
|
|||||||
|
|
||||||
waitUntil { fadedOut || err != null }
|
waitUntil { fadedOut || err != null }
|
||||||
if (err != null) throw err!!
|
if (err != null) throw err!!
|
||||||
|
|
||||||
|
oldState = currentPlaybackState.get()
|
||||||
|
oldAkku = waitAkku
|
||||||
|
oldTime = waitTime
|
||||||
|
|
||||||
|
enterSTATE_INTERMISSION(0f)
|
||||||
|
enterSTATE_FIREPLAY()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSuccess(state: TransactionState) {
|
override fun onSuccess(state: TransactionState) {
|
||||||
enterSTATE_INTERMISSION(0f)
|
|
||||||
enterSTATE_FIREPLAY()
|
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
override fun onFailure(e: Throwable, state: TransactionState) {
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
|
currentPlaybackState.set(oldState)
|
||||||
|
waitAkku = oldAkku
|
||||||
|
waitTime = oldTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -369,6 +497,10 @@ object MusicService : TransactionListener() {
|
|||||||
|
|
||||||
private fun createTransactionForPlaylistResume(onSuccess: () -> Unit, onFailure: (Throwable) -> Unit): Transaction {
|
private fun createTransactionForPlaylistResume(onSuccess: () -> Unit, onFailure: (Throwable) -> Unit): Transaction {
|
||||||
return object : Transaction {
|
return object : Transaction {
|
||||||
|
var oldState = currentPlaybackState.get()
|
||||||
|
var oldAkku = waitAkku
|
||||||
|
var oldTime = waitTime
|
||||||
|
|
||||||
override fun start(state: TransactionState) {
|
override fun start(state: TransactionState) {
|
||||||
enterSTATE_FIREPLAY()
|
enterSTATE_FIREPLAY()
|
||||||
}
|
}
|
||||||
@@ -378,6 +510,11 @@ object MusicService : TransactionListener() {
|
|||||||
}
|
}
|
||||||
override fun onFailure(e: Throwable, state: TransactionState) {
|
override fun onFailure(e: Throwable, state: TransactionState) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
||||||
|
currentPlaybackState.set(oldState)
|
||||||
|
waitAkku = oldAkku
|
||||||
|
waitTime = oldTime
|
||||||
|
|
||||||
onFailure(e)
|
onFailure(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,6 +584,12 @@ object MusicService : TransactionListener() {
|
|||||||
else
|
else
|
||||||
runTransaction(createTransactionPlaylistChange(playlist, {}))
|
runTransaction(createTransactionPlaylistChange(playlist, {}))
|
||||||
}
|
}
|
||||||
|
fun putNewPlaylistAndResumePlayback(playlist: TerrarumMusicPlaylist, onSuccess: (() -> Unit)? = null) {
|
||||||
|
if (onSuccess != null)
|
||||||
|
runTransaction(createTransactionPlaylistChangeAndPlayImmediately(playlist, onSuccess))
|
||||||
|
else
|
||||||
|
runTransaction(createTransactionPlaylistChangeAndPlayImmediately(playlist, {}))
|
||||||
|
}
|
||||||
fun putNewPlaylist(playlist: TerrarumMusicPlaylist, onSuccess: () -> Unit, onFinally: () -> Unit) {
|
fun putNewPlaylist(playlist: TerrarumMusicPlaylist, onSuccess: () -> Unit, onFinally: () -> Unit) {
|
||||||
runTransaction(createTransactionPlaylistChange(playlist, onSuccess), onFinally)
|
runTransaction(createTransactionPlaylistChange(playlist, onSuccess), onFinally)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,11 +135,6 @@ class FixtureJukebox : Electric, PlaysMusic {
|
|||||||
|
|
||||||
discCurrentlyPlaying = index
|
discCurrentlyPlaying = index
|
||||||
|
|
||||||
// FIXME the olde way -- must be replaced with one that utilises MusicService
|
|
||||||
/*App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, DEFAULT_FADEOUT_LEN / 2f) {
|
|
||||||
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
|
||||||
}*/
|
|
||||||
|
|
||||||
MusicService.playMusicalFixture(
|
MusicService.playMusicalFixture(
|
||||||
/* action: () -> Unit */ {
|
/* action: () -> Unit */ {
|
||||||
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
||||||
|
|||||||
@@ -116,12 +116,6 @@ class FixtureMusicalTurntable : Electric, PlaysMusic {
|
|||||||
App.printdbg(this, "Stop music $title - $artist")
|
App.printdbg(this, "Stop music $title - $artist")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME the olde way -- must be replaced with one that utilises MusicService
|
|
||||||
/*App.audioMixer.requestFadeOut(App.audioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 2f) {
|
|
||||||
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
|
||||||
}*/
|
|
||||||
|
|
||||||
MusicService.playMusicalFixture(
|
MusicService.playMusicalFixture(
|
||||||
/* action: () -> Unit */ {
|
/* action: () -> Unit */ {
|
||||||
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
startAudio(musicNowPlaying!!) { loadEffector(it) }
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ abstract class TransactionListener {
|
|||||||
printdbg(this, "Accepting transaction $transaction")
|
printdbg(this, "Accepting transaction $transaction")
|
||||||
Thread {
|
Thread {
|
||||||
val state = getCurrentStatusForTransaction()
|
val state = getCurrentStatusForTransaction()
|
||||||
|
var wasSuccessful = false
|
||||||
val currentLock = transactionLockingClass.get()
|
val currentLock = transactionLockingClass.get()
|
||||||
if (currentLock == null) {
|
if (currentLock == null) {
|
||||||
acquireLock(transaction)
|
acquireLock(transaction)
|
||||||
@@ -63,23 +64,27 @@ abstract class TransactionListener {
|
|||||||
transaction.start(state)
|
transaction.start(state)
|
||||||
// if successful:
|
// if successful:
|
||||||
commitTransaction(state)
|
commitTransaction(state)
|
||||||
// notify the success
|
|
||||||
transaction.onSuccess(state)
|
wasSuccessful = true
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
// if failed, notify the failure
|
// if failed, notify the failure
|
||||||
System.err.println("Transaction failure: generic")
|
System.err.println("Transaction failure: generic (failed transaction: $transaction)")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
transaction.onFailure(e, state)
|
transaction.onFailure(e, state)
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
if (wasSuccessful) {
|
||||||
|
// notify the success
|
||||||
|
transaction.onSuccess(state)
|
||||||
|
}
|
||||||
releaseLock()
|
releaseLock()
|
||||||
onFinally()
|
onFinally()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
System.err.println("Transaction failure: locked")
|
System.err.println("Transaction failure: locked (failed transaction: $transaction)")
|
||||||
transaction.onFailure(LockedException(transaction, this, currentLock), state)
|
transaction.onFailure(LockedException(this, currentLock), state)
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
@@ -88,8 +93,8 @@ abstract class TransactionListener {
|
|||||||
protected abstract fun commitTransaction(state: TransactionState)
|
protected abstract fun commitTransaction(state: TransactionState)
|
||||||
}
|
}
|
||||||
|
|
||||||
class LockedException(offendingTransaction: Transaction, listener: TransactionListener, lockedBy: Transaction) :
|
class LockedException(listener: TransactionListener, lockedBy: Transaction) :
|
||||||
Exception("Transaction '$offendingTransaction' is rejected because the class '$listener' is locked by '$lockedBy'")
|
Exception("The class '$listener' is locked by '$lockedBy'")
|
||||||
|
|
||||||
@JvmInline value class TransactionState(val valueTable: HashMap<String, Any?>) {
|
@JvmInline value class TransactionState(val valueTable: HashMap<String, Any?>) {
|
||||||
operator fun get(key: String) = valueTable[key]
|
operator fun get(key: String) = valueTable[key]
|
||||||
|
|||||||
Reference in New Issue
Block a user