From 85d80621508b287834d102032d7c442e586d321c Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 10 Aug 2024 12:14:52 -0500 Subject: [PATCH] support continuing after errors --- haxe_libraries/kiss-tools.hxml | 4 +- haxe_libraries/kiss.hxml | 6 +-- src/hollywoo/HollywooDSL.kiss | 36 +++++++++++---- src/hollywoo/Movie.kiss | 84 +++++++++++++++++----------------- 4 files changed, 74 insertions(+), 56 deletions(-) diff --git a/haxe_libraries/kiss-tools.hxml b/haxe_libraries/kiss-tools.hxml index fbd19ef..7426078 100644 --- a/haxe_libraries/kiss-tools.hxml +++ b/haxe_libraries/kiss-tools.hxml @@ -1,4 +1,4 @@ -# @install: lix --silent download "gh://github.com/kiss-lang/kiss-tools#93ad23d10bd1e6446113f7fa1b1ec9595ed03d7d" into kiss-tools/0.0.0/github/93ad23d10bd1e6446113f7fa1b1ec9595ed03d7d +# @install: lix --silent download "gh://github.com/kiss-lang/kiss-tools#4148f3268fb0768d3febe26a3c2f1898a5a086aa" into kiss-tools/0.0.0/github/4148f3268fb0768d3febe26a3c2f1898a5a086aa -lib kiss --cp ${HAXE_LIBCACHE}/kiss-tools/0.0.0/github/93ad23d10bd1e6446113f7fa1b1ec9595ed03d7d/src/ +-cp ${HAXE_LIBCACHE}/kiss-tools/0.0.0/github/4148f3268fb0768d3febe26a3c2f1898a5a086aa/src/ -D kiss-tools=0.0.0 \ No newline at end of file diff --git a/haxe_libraries/kiss.hxml b/haxe_libraries/kiss.hxml index 1fe3d78..e49638b 100644 --- a/haxe_libraries/kiss.hxml +++ b/haxe_libraries/kiss.hxml @@ -1,12 +1,12 @@ -# @install: lix --silent download "gh://github.com/kiss-lang/kiss#a2aaca9f7ed54ba7d8b09f510dd3a1962ce0af5a" into kiss/0.0.1/github/a2aaca9f7ed54ba7d8b09f510dd3a1962ce0af5a -# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/github/a2aaca9f7ed54ba7d8b09f510dd3a1962ce0af5a" +# @install: lix --silent download "gh://github.com/kiss-lang/kiss#f2cff4803e6723409c12d8896510d9e59191a1c5" into kiss/0.0.1/github/f2cff4803e6723409c12d8896510d9e59191a1c5 +# @run: haxelib run-dir kiss "${HAXE_LIBCACHE}/kiss/0.0.1/github/f2cff4803e6723409c12d8896510d9e59191a1c5" -lib haxe-strings -lib hscript -lib tink_json -lib tink_macro -lib tink_syntaxhub -lib uuid --cp ${HAXE_LIBCACHE}/kiss/0.0.1/github/a2aaca9f7ed54ba7d8b09f510dd3a1962ce0af5a/src +-cp ${HAXE_LIBCACHE}/kiss/0.0.1/github/f2cff4803e6723409c12d8896510d9e59191a1c5/src -D kiss=0.0.1 -w -WUnusedPattern --macro kiss.KissFrontend.use() \ No newline at end of file diff --git a/src/hollywoo/HollywooDSL.kiss b/src/hollywoo/HollywooDSL.kiss index 4f30128..fe8e36e 100644 --- a/src/hollywoo/HollywooDSL.kiss +++ b/src/hollywoo/HollywooDSL.kiss @@ -75,8 +75,16 @@ (never otherwise))) (set isLoading true) + (localFunction :Void done [] + (.start (director.shortcutHandler)) + (director.hideTitleCard)) + (localFunction :Void cont [] + (set didLoading true) + (set isLoading false) + (print "Had to load ${loadedObjects}/${loadCalls} objects newly") + (cc)) (director.showTitleCard ["LOADING"] - (makeCC + (makeCC ->:Void {(done)(cont)} (let [loadVoiceTrack _loadVoiceTrack addVoiceTrack _addVoiceTrack noVoiceTracks _noVoiceTracks @@ -93,14 +101,10 @@ addSound _addSound] (director.doLoading ,preloadFuncs scavenged - (makeCC - (set didLoading true) - (set isLoading false) - (print "Had to load ${loadedObjects}/${loadCalls} objects newly") - (cc)) - (makeCC - (.start (director.shortcutHandler)) - (director.hideTitleCard))))))) + (makeCC null + (cont)) + (makeCC null + (done))))))) (prop &mut cleanupDone false) @:keep @@ -130,6 +134,20 @@ (checkPlayMode ->:Void (doPreload cc)))) (defReaderMacro &eof "" [stream] `(#when (StringTools.contains kissFile className) + (prop &mut ccAllErrors false) + (preload + (set onError ->[e quit cc] { + (when ccAllErrors (cc)(return)) + (director.chooseString + "Error ${e}. Continue?" + ["Yes" "Yes to all" "Quit"] + ->choice + (case choice + ("Yes" (cc)) + ("Yes to all" (set ccAllErrors true)(cc)) + ("No" (quit)) + (never otherwise))) + })) // Prepare the interpreter for this movie's cached instructions (preload diff --git a/src/hollywoo/Movie.kiss b/src/hollywoo/Movie.kiss index 431ab3e..7e20295 100644 --- a/src/hollywoo/Movie.kiss +++ b/src/hollywoo/Movie.kiss @@ -1,5 +1,5 @@ -(defMacro makeCC [&body b] - `->:Void [] (runWithErrorChecking ->:Void {,@b})) +(defMacro makeCC [errorCC &body b] + `->:Void [] (runWithErrorChecking ->:Void {,@b} ,errorCC)) (function dynamicArray [&rest :Array elements] elements) @@ -141,7 +141,7 @@ (return)) (localVar &mut :kiss_tools.TimerWithPause.WrappedTimer cutoffTimer null) (processIntercut skipping actorName - (makeCC + (makeCC cc (let [inputDelayKey (inputKey) isSilentType ?(whenLet [(Custom type _ _) dialogType] @@ -168,10 +168,10 @@ { (set cutoffTimer (TimerWithPause.delay - (makeCC + (makeCC cc (director._hideDialog) (cc)) (* voCutoffPercent (- end start)))) - (makeCC null) + (makeCC null null) } cc)) // TODO when "VO for silent dialogue" is enabled play supertext vo @@ -400,13 +400,13 @@ (let [currentScene (dictGet scenes sceneKey)] (director.hideLighting) (director.hideSet currentScene.set currentScene.camera - (makeCC + (makeCC cc // hide current scene characters (_ccForEach currentScene.characters ->[:Character c :Continuation cc] (director.hideCharacter c currentScene.camera cc) - (makeCC + (makeCC cc // hide current scene props, etc. (_ccForEach currentScene.props @@ -445,13 +445,13 @@ // Show current scene background (director.showSet scene.set scene.time scene.perspective appearance camera - (makeCC + (makeCC cc // Show current scene characters (_ccForEach (object iterator ->(scene.characters.keys)) ->[:String key :Continuation cc] (director.showCharacter (dictGet scene.characters key) (appearanceFlag shownCharacters key) camera cc) - (makeCC + (makeCC cc // show current scene props, etc. (_ccForEach scene.propOrder @@ -778,7 +778,7 @@ (ifLet [key (propOrder.shift) prop (dictGet scene.props key)] (director.hideProp prop.prop scene.camera - (makeCC + (makeCC nextProp (when (scene.propPositionKeys.exists key) (set prop.position (resolvePosition (dictGet scene.propPositionKeys key) null))) (director.showProp prop.prop prop.position ReAppearance scene.camera nextProp))) @@ -791,7 +791,7 @@ (let [key (characterIterator.next) character (dictGet scene.characters key)] (director.hideCharacter character scene.camera - (makeCC + (makeCC nextCharacter (when (scene.actorPositionKeys.exists key) (set character.stagePosition (resolvePosition (dictGet scene.actorPositionKeys key) null))) (director.showCharacter character ReAppearance scene.camera nextCharacter)))) @@ -959,7 +959,7 @@ sound (dictGet sounds name)] (director.showCaption desc id) (delay skipping (min MAX_CAPTION_DURATION (director.getSoundLength sound)) - (makeCC + (makeCC null (director.hideCaption id))) true))) (method :Int miscInt [:String key &opt :Int defaultVal :Int->Void onChange] @@ -1132,26 +1132,26 @@ (changeSongVolume skipping volumeMod cc)) (true (set playingSceneMusic songKey) - (stopSong skipping (makeCC null)) - (loopSong skipping songKey (makeCC null) volumeMod) + (stopSong skipping (makeCC null null)) + (loopSong skipping songKey (makeCC null null) volumeMod) (cc)))) (hollywooMethod setScene [:Bool skipping :String name :Continuation cc] (hideCustomDialog - (makeCC + (makeCC cc (_hideCurrentScene - (makeCC + (makeCC cc (let [name (FuzzyMapTools.bestMatch scenes name)] (set sceneKey name) (ifLet [songKey (dictGet sceneMusic name)] // Keep the song going if it's the same as current. Otherwise, take over! (unless (= playingSceneMusic songKey) (set playingSceneMusic songKey) - (stopSong skipping (makeCC null)) - (loopSong skipping songKey (makeCC null) (dictGet sceneMusicVolume name))) + (stopSong skipping (makeCC null null)) + (loopSong skipping songKey (makeCC null null) (dictGet sceneMusicVolume name))) (when playingSceneMusic (set playingSceneMusic null) - (stopSong skipping (makeCC null)))) + (stopSong skipping (makeCC null null)))) (unless (positionsInScene.exists sceneKey) (dictSet positionsInScene sceneKey [])) (_showScene @@ -1170,19 +1170,19 @@ actorPositionKeys (actorPositionKeys.copy) propPositionKeys (propPositionKeys.copy)] (clearCharacters - (makeCC + (makeCC cc (clearProps - (makeCC + (makeCC cc (setScene skipping name - (makeCC + (makeCC cc (_ccForEachIterator (characters.keyValueIterator) ->[character cc] (addCharacter character.key character.value.stagePosition character.value.stageFacing cc) - (makeCC + (makeCC cc (_ccForEach propOrder ->[propKey cc] (addProp propKey .position (props.get propKey) cc) - (makeCC + (makeCC cc (doFor =>actor posKey actorPositionKeys (dictSet .actorPositionKeys (_currentScene) actor posKey)) (doFor =>prop posKey propPositionKeys @@ -1228,11 +1228,11 @@ inputDelayKey (inputKey)] (localVar &mut currentSound "") (localVar endCC - (makeCC + (makeCC cc (stopWaitForInput inputDelayKey) (whileLet [soundKey (names.shift)] // This just adds the sounds to the history: - (playSound true soundKey (makeCC null) volumeMod false true)) + (playSound true soundKey (makeCC null null) volumeMod false true)) (when currentSound (stopSound skipping currentSound cc)) (cc))) @@ -1264,7 +1264,7 @@ [ (:Void playAgain [] (playSound false name - (makeCC + (makeCC null (when (loopingSoundPlays.exists name) (playAgain))) volumeMod @@ -1326,7 +1326,7 @@ position (resolvePosition position (Actor actorName)) character (object stagePosition position stageFacing facing actor (dictGet actors actorName))] (autoZProcess position - (makeCC + (makeCC cc (dictSet .characters (_currentScene) actorName character) (_updateLighting) (director.showCharacter @@ -1343,7 +1343,7 @@ (hollywooMethod clearCharacters [:Continuation cc] (doFor =>name c .characters (_currentScene) - (director.hideCharacter c .camera (_currentScene) (makeCC null)) + (director.hideCharacter c .camera (_currentScene) (makeCC null null)) (.remove .characters (_currentScene) name)) (_updateLighting) (cc)) @@ -1351,7 +1351,7 @@ // INSTANTLY move a character: (hollywooMethod moveCharacter [actorName :Dynamic newPosition :StageFacing newFacing :Continuation cc] (removeCharacter actorName - (makeCC + (makeCC cc (addCharacter actorName newPosition newFacing cc)))) // INSTANTLY swap characters @@ -1365,11 +1365,11 @@ bsp b.stagePosition bsf b.stageFacing] (removeCharacter actorNameA - (makeCC + (makeCC cc (removeCharacter actorNameB - (makeCC + (makeCC cc (addCharacter actorNameA bsp bsf - (makeCC + (makeCC cc (addCharacter actorNameB asp asf cc))))))))) // Strobe and continue the script: @@ -1429,7 +1429,7 @@ (let [inputDelayKey (inputKey) cc ->{(stopWaitForInput inputDelayKey)(director.hideTitleCard)(cc)}] (director.showTitleCard lines - (makeCC + (makeCC cc // Allow skipping (startWaitForInput cc inputDelayKey) (delay skipping time cc true))))) @@ -1456,17 +1456,17 @@ (hollywooMethod normalSpeech [:Bool skipping actorName wryly text :Continuation cc] (processIntercut skipping actorName - (makeCC + (makeCC cc (let [character (dictGet .characters (_currentScene) actorName) actor character.actor] (director.showExpression actor wryly) (showDialog skipping actorName (OnScreen character) wryly text cc))))) (hollywooMethod interruptedSpeech [:Bool skipping actorName wryly :String text :Continuation cc] - (overridePlayMode Watch (makeCC null)) + (overridePlayMode Watch (makeCC null null)) // naively guess that the interruption should happen X% of the way through the spoken // line, where X = the position of the last / in the text - (let [wrappedCC (makeCC (restorePlayMode cc)) + (let [wrappedCC (makeCC cc (restorePlayMode cc)) slashIndex (text.lastIndexOf "/")] (when (= -1 slashIndex) (throw "interruptedSpeech requires a / in the text to indicate the cutoff point!")) (let [slashPercent (/ slashIndex text.length) @@ -1476,7 +1476,7 @@ text (StringTools.replace text " " " ") text (StringTools.replace text " " " ")] (processIntercut skipping actorName - (makeCC + (makeCC cc (let [character (dictGet .characters (_currentScene) actorName) actor character.actor] (director.showExpression actor wryly) @@ -1492,7 +1492,7 @@ (hollywooMethod onPhoneSpeech [:Bool skipping actorName wryly text :Continuation cc] (processIntercut skipping actorName - (makeCC + (makeCC cc (showDialog skipping actorName (ifLet [charOnScreen (try (dictGet .characters (_currentScene) actorName) (catch [e] null))] { (director.showExpression charOnScreen.actor wryly) @@ -1502,7 +1502,7 @@ (hollywooMethod customSpeech [:Bool skipping type actorName wryly args text :Continuation cc] (processIntercut skipping actorName - (makeCC + (makeCC cc (showDialog skipping actorName (Custom type (dictGet .characters (_currentScene) actorName) args) wryly text cc)))) (hollywooMethod timedCutToBlack [:Bool skipping :Dynamic seconds :Continuation cc] @@ -1607,11 +1607,11 @@ (when skipping (cc) (return)) - (playSong skipping songKey (makeCC null) volumeMod) + (playSong skipping songKey (makeCC null null) volumeMod) (rollCredits skipping creditsTSV - (makeCC + (makeCC cc (stopSong skipping cc)) (director.getSongLength (dictGet songs songKey))))