refactor asset loading
This commit is contained in:
10
memory-fix.org
Normal file
10
memory-fix.org
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
* DONE for all asset types, make the Director define load*()
|
||||||
|
* DONE instead of requiring Cloneable<Set>, add Director.cloneSet()
|
||||||
|
* DONE in all newMethods take a path, not the object.
|
||||||
|
** DONE allow for alternative loading with the object directly, like how some props in HollywooFlixel are animated via ActorFlxSprite
|
||||||
|
** DONE if the assetpath doesn't start with assets/, call (assetPath "<typeDir>" "<path>")
|
||||||
|
** DONE make loading things at runtime a compiler error
|
||||||
|
* TODO in all new* methods, save the path that was loaded
|
||||||
|
* TODO in all with_ macros, mark those assets as dirty (needing to be reloaded)
|
||||||
|
* TODO Movie.scavenge before cleanup
|
||||||
|
* TODO in all new* methods, don't load the new thing if it exists already
|
@@ -26,7 +26,7 @@ typedef AutoZConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@:keepSub
|
@:keepSub
|
||||||
interface Director<Set:Cloneable<Set>, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource:Jsonable<LightSource>> {
|
interface Director<Set, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource:Jsonable<LightSource>> {
|
||||||
var movie(default, default):Movie<Set, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource>;
|
var movie(default, default):Movie<Set, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource>;
|
||||||
function autoZConfig():Option<AutoZConfig>;
|
function autoZConfig():Option<AutoZConfig>;
|
||||||
|
|
||||||
@@ -51,15 +51,19 @@ interface Director<Set:Cloneable<Set>, Actor, Sound, Song, Prop, VoiceTrack, Cam
|
|||||||
function defineStagePosition(camera:Camera, submit:StagePosition->Void, ?oldPosition:StagePosition):Void;
|
function defineStagePosition(camera:Camera, submit:StagePosition->Void, ?oldPosition:StagePosition):Void;
|
||||||
function defineLightSource(submit:LightSource->Void):Void;
|
function defineLightSource(submit:LightSource->Void):Void;
|
||||||
|
|
||||||
|
function loadSet(path:String):Set;
|
||||||
|
function cloneSet(set:Set):Set;
|
||||||
function showSet(set:Set, time:SceneTime, perspective:ScenePerspective, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
function showSet(set:Set, time:SceneTime, perspective:ScenePerspective, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
||||||
function hideSet(set:Set, camera: Camera, cc:Continuation):Void;
|
function hideSet(set:Set, camera: Camera, cc:Continuation):Void;
|
||||||
|
|
||||||
function showLighting(sceneTime:SceneTime, lightSources:Array<LightSource>, camera:Camera):Void;
|
function showLighting(sceneTime:SceneTime, lightSources:Array<LightSource>, camera:Camera):Void;
|
||||||
function hideLighting():Void;
|
function hideLighting():Void;
|
||||||
|
|
||||||
|
function loadActor(path:String):Actor;
|
||||||
function showCharacter(character:Character<Actor>, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
function showCharacter(character:Character<Actor>, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
||||||
function hideCharacter(character:Character<Actor>, camera:Camera, cc:Continuation):Void;
|
function hideCharacter(character:Character<Actor>, camera:Camera, cc:Continuation):Void;
|
||||||
|
|
||||||
|
function loadSound(path:String):Sound;
|
||||||
function playSound(sound:Sound, volumeMod:Float, ?cc:Continuation):Void;
|
function playSound(sound:Sound, volumeMod:Float, ?cc:Continuation):Void;
|
||||||
function getSoundLength(sound:Sound):Float;
|
function getSoundLength(sound:Sound):Float;
|
||||||
function stopSound(sound:Sound):Void;
|
function stopSound(sound:Sound):Void;
|
||||||
@@ -67,11 +71,13 @@ interface Director<Set:Cloneable<Set>, Actor, Sound, Song, Prop, VoiceTrack, Cam
|
|||||||
function showCaption(description:String, id:Int):Void;
|
function showCaption(description:String, id:Int):Void;
|
||||||
function hideCaption(id:Int):Void;
|
function hideCaption(id:Int):Void;
|
||||||
|
|
||||||
|
function loadSong(path:String):Song;
|
||||||
function playSong(song:Song, volumeMod:Float, loop:Bool, waitForEnd:Bool, cc:Continuation):Void;
|
function playSong(song:Song, volumeMod:Float, loop:Bool, waitForEnd:Bool, cc:Continuation):Void;
|
||||||
function getSongLength(song:Song):Float;
|
function getSongLength(song:Song):Float;
|
||||||
function changeSongVolume(volumeMod:Float, cc:Continuation):Void;
|
function changeSongVolume(volumeMod:Float, cc:Continuation):Void;
|
||||||
function stopSong():Void;
|
function stopSong():Void;
|
||||||
|
|
||||||
|
function loadVoiceTrack(path:String):VoiceTrack;
|
||||||
function playVoiceTrack(track:VoiceTrack, volumeMod:Float, start:Float, end:Float, cc:Continuation):Void;
|
function playVoiceTrack(track:VoiceTrack, volumeMod:Float, start:Float, end:Float, cc:Continuation):Void;
|
||||||
function stopVoiceTrack(track:VoiceTrack):Void;
|
function stopVoiceTrack(track:VoiceTrack):Void;
|
||||||
|
|
||||||
@@ -87,6 +93,7 @@ interface Director<Set:Cloneable<Set>, Actor, Sound, Song, Prop, VoiceTrack, Cam
|
|||||||
function showBlackScreen():Void;
|
function showBlackScreen():Void;
|
||||||
function hideBlackScreen():Void;
|
function hideBlackScreen():Void;
|
||||||
|
|
||||||
|
function loadProp(path:String):Prop;
|
||||||
function showProp(prop:Prop, position:StagePosition, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
function showProp(prop:Prop, position:StagePosition, appearance:Appearance, camera:Camera, cc:Continuation):Void;
|
||||||
function hideProp(prop:Prop, camera:Camera, cc:Continuation):Void;
|
function hideProp(prop:Prop, camera:Camera, cc:Continuation):Void;
|
||||||
|
|
||||||
|
@@ -73,15 +73,29 @@
|
|||||||
(director.showTitleCard ["LOADING"]
|
(director.showTitleCard ["LOADING"]
|
||||||
(makeCC
|
(makeCC
|
||||||
(set isLoading true)
|
(set isLoading true)
|
||||||
(director.doLoading ,preloadFuncs
|
(let [loadVoiceTrack _loadVoiceTrack
|
||||||
(makeCC
|
addVoiceTrack _addVoiceTrack
|
||||||
(set isLoading false)
|
noVoiceTracks _noVoiceTracks
|
||||||
(.start (director.shortcutHandler))
|
loadProp _loadProp
|
||||||
(director.hideTitleCard)
|
addProp _addProp
|
||||||
// When all loading is done, prompt to start obs recording automatically:
|
loadSong _loadSong
|
||||||
(#if debug
|
addSong _addSong
|
||||||
(promptToRecord cc)
|
loadActor _loadActor
|
||||||
(cc)))))))
|
addActor _addActor
|
||||||
|
loadSet _loadSet
|
||||||
|
addSet _addSet
|
||||||
|
newSceneFromSet _newSceneFromSet
|
||||||
|
loadSound _loadSound
|
||||||
|
addSound _addSound]
|
||||||
|
(director.doLoading ,preloadFuncs
|
||||||
|
(makeCC
|
||||||
|
(set isLoading false)
|
||||||
|
(.start (director.shortcutHandler))
|
||||||
|
(director.hideTitleCard)
|
||||||
|
// When all loading is done, prompt to start obs recording automatically:
|
||||||
|
(#if debug
|
||||||
|
(promptToRecord cc)
|
||||||
|
(cc))))))))
|
||||||
@:keep
|
@:keep
|
||||||
(method doCleanup []
|
(method doCleanup []
|
||||||
(director.cleanup)
|
(director.cleanup)
|
||||||
|
@@ -20,10 +20,6 @@ import kiss_tools.TimerWithPause;
|
|||||||
|
|
||||||
using kiss.FuzzyMapTools;
|
using kiss.FuzzyMapTools;
|
||||||
|
|
||||||
typedef Cloneable<T> = {
|
|
||||||
function clone():T;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum DelayHandling {
|
enum DelayHandling {
|
||||||
Auto;
|
Auto;
|
||||||
AutoWithSkip;
|
AutoWithSkip;
|
||||||
@@ -65,4 +61,4 @@ enum PlayMode {
|
|||||||
* Model/controller of a Hollywoo film, and main execution script
|
* Model/controller of a Hollywoo film, and main execution script
|
||||||
*/
|
*/
|
||||||
@:build(kiss.Kiss.build())
|
@:build(kiss.Kiss.build())
|
||||||
class Movie<Set:Cloneable<Set>, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource:Jsonable<LightSource>> extends AsyncEmbeddedScript2 {}
|
class Movie<Set, Actor, Sound, Song, Prop, VoiceTrack, Camera, LightSource:Jsonable<LightSource>> extends AsyncEmbeddedScript2 {}
|
||||||
|
@@ -142,11 +142,36 @@
|
|||||||
(throw "No handler for custom dialog type $type")))
|
(throw "No handler for custom dialog type $type")))
|
||||||
(otherwise (director.showDialog actorName dialogType wryly text skipCC)))))))
|
(otherwise (director.showDialog actorName dialogType wryly text skipCC)))))))
|
||||||
|
|
||||||
(method noVoiceTracks [actorName]
|
(defMacro withIndexedPath [pathVar typeDefaultDir &body body]
|
||||||
(dictSet voiceTracksPerActor actorName 0)
|
(#if (or sys hxnodejs)
|
||||||
(dictSet voiceLines actorName (new FuzzyMap<VoiceLine>)))
|
`(let [,pathVar
|
||||||
|
(if (StringTools.startsWith ,pathVar assetDir)
|
||||||
|
,pathVar
|
||||||
|
(assetPath ,typeDefaultDir ,pathVar))]
|
||||||
|
,@body)
|
||||||
|
body))
|
||||||
|
|
||||||
(method newVoiceTrack [actorName :VoiceTrack track :String lineJson]
|
// Methods for loading new assets in a hollywoo movie follow a special naming convention.
|
||||||
|
// _add*() is a method which takes the asset DIRECTLY and adds it to the corresponding asset map.
|
||||||
|
// This is to be used in cases where the asset needs to be loaded specially in a way
|
||||||
|
// the Director's load*() function can't handle.
|
||||||
|
// _load*() is a method which takes the asset's PATH and lets the Director load the asset object.
|
||||||
|
//
|
||||||
|
// Neither of these is not meant to be called directly, as a precaution against loading new assets
|
||||||
|
// at Movie runtime. However, within the context of (preload...) blocks, they will be
|
||||||
|
// bound to these names:
|
||||||
|
// add*()
|
||||||
|
// new*() At which point you can use them. Therefore, if you accidentally try to call new*()
|
||||||
|
// outside of a preload block, your code won't compile.
|
||||||
|
// Which is desired because (preload...) blocks are meant to be allowed at any point in a script,
|
||||||
|
// even following the usage of the assets they load. Runtime loading allows for errors
|
||||||
|
// caused by moving the load calls or asset usages around so the load doesn't precede the usage.
|
||||||
|
(method _loadVoiceTrack [actorName :String path :String lineJson]
|
||||||
|
(withIndexedPath path "vo"
|
||||||
|
(_addVoiceTrack actorName (director.loadVoiceTrack path) lineJson)))
|
||||||
|
|
||||||
|
(method _addVoiceTrack [actorName :VoiceTrack track :String lineJson]
|
||||||
|
(assert isLoading)
|
||||||
(let [actorNumVoiceTracks (or (dictGet voiceTracksPerActor actorName) 0)
|
(let [actorNumVoiceTracks (or (dictGet voiceTracksPerActor actorName) 0)
|
||||||
trackKey "${actorName}${actorNumVoiceTracks}"
|
trackKey "${actorName}${actorNumVoiceTracks}"
|
||||||
:haxe.DynamicAccess<Dynamic> lines (Json.parse lineJson)]
|
:haxe.DynamicAccess<Dynamic> lines (Json.parse lineJson)]
|
||||||
@@ -161,6 +186,68 @@
|
|||||||
(dictSet voiceLines actorName (new FuzzyMap<VoiceLine>)))
|
(dictSet voiceLines actorName (new FuzzyMap<VoiceLine>)))
|
||||||
(dictSet (dictGet voiceLines actorName) key (objectWith [start line.start end line.end] trackKey alts))))))
|
(dictSet (dictGet voiceLines actorName) key (objectWith [start line.start end line.end] trackKey alts))))))
|
||||||
|
|
||||||
|
(method _noVoiceTracks [actorName]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet voiceTracksPerActor actorName 0)
|
||||||
|
(dictSet voiceLines actorName (new FuzzyMap<VoiceLine>)))
|
||||||
|
|
||||||
|
(method _loadProp [name :String path]
|
||||||
|
(withIndexedPath path "images"
|
||||||
|
(_addProp name (director.loadProp path))))
|
||||||
|
|
||||||
|
(method _addProp [name :Prop prop]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet props name prop))
|
||||||
|
|
||||||
|
(method _loadSong [name :String path]
|
||||||
|
(withIndexedPath path "music"
|
||||||
|
(_addSong name (director.loadSong path))))
|
||||||
|
|
||||||
|
(method _addSong [name :Song song]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet songs name song))
|
||||||
|
|
||||||
|
(method _loadActor [name :String path]
|
||||||
|
(withIndexedPath path "images"
|
||||||
|
(_addActor name (director.loadActor path))))
|
||||||
|
|
||||||
|
(method _addActor [name :Actor actor]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet actors name actor))
|
||||||
|
|
||||||
|
(method _loadSet [name :String path]
|
||||||
|
(withIndexedPath path "images"
|
||||||
|
(_addSet name (director.loadSet path))))
|
||||||
|
|
||||||
|
(method _addSet [name :Set set]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet sets name set))
|
||||||
|
|
||||||
|
(method _newSceneFromSet [name :String setKey :SceneTime time :ScenePerspective perspective :Camera camera]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet scenes name (objectWith
|
||||||
|
[
|
||||||
|
set
|
||||||
|
(director.cloneSet (dictGet sets setKey))
|
||||||
|
characters
|
||||||
|
(new FuzzyMap<Character<Actor>>)
|
||||||
|
props
|
||||||
|
(new FuzzyMap<StageProp<Prop>>)
|
||||||
|
camera
|
||||||
|
camera
|
||||||
|
]
|
||||||
|
time
|
||||||
|
perspective)))
|
||||||
|
|
||||||
|
(method _loadSound [name :String path :String description]
|
||||||
|
(withIndexedPath path "sounds"
|
||||||
|
(_addSound name (director.loadSound path) description)))
|
||||||
|
|
||||||
|
(method _addSound [name :Sound s :String description]
|
||||||
|
(assert isLoading)
|
||||||
|
(dictSet sounds name s)
|
||||||
|
(dictSet soundDescriptions name description))
|
||||||
|
|
||||||
(method _ccForEach <>[T] [:Iterable<T> collection :(T,Continuation)->Void do_ :Continuation finalCC]
|
(method _ccForEach <>[T] [:Iterable<T> collection :(T,Continuation)->Void do_ :Continuation finalCC]
|
||||||
(let [:Iterator<T> iter (collection.iterator)]
|
(let [:Iterator<T> iter (collection.iterator)]
|
||||||
(withFunctions
|
(withFunctions
|
||||||
@@ -263,8 +350,10 @@
|
|||||||
|
|
||||||
(#when (or sys hxnodejs)
|
(#when (or sys hxnodejs)
|
||||||
(prop :FuzzyMap<FuzzyMap<String>> assetPaths (new FuzzyMap))
|
(prop :FuzzyMap<FuzzyMap<String>> assetPaths (new FuzzyMap))
|
||||||
|
(prop &mut :String assetDir "")
|
||||||
(prop :Array<Array<String>> loadedCredits [])
|
(prop :Array<Array<String>> loadedCredits [])
|
||||||
(method _indexAssetPaths [:String assetDir]
|
(method _indexAssetPaths [:String assetDir]
|
||||||
|
(set this.assetDir assetDir)
|
||||||
(let [dirParts (assetDir.split "/")]
|
(let [dirParts (assetDir.split "/")]
|
||||||
(doFor part dirParts
|
(doFor part dirParts
|
||||||
(dictSet assetPaths part (new FuzzyMap))))
|
(dictSet assetPaths part (new FuzzyMap))))
|
||||||
@@ -445,15 +534,8 @@
|
|||||||
((dictGet runners label))
|
((dictGet runners label))
|
||||||
})))))
|
})))))
|
||||||
|
|
||||||
(super)))
|
(super))
|
||||||
|
|
||||||
// END Parent class definitions
|
|
||||||
|
|
||||||
(defMacro indexAssetPaths [dir]
|
|
||||||
`(preload
|
|
||||||
(_indexAssetPaths ,dir)))
|
|
||||||
|
|
||||||
(#unless subclass
|
|
||||||
@:keep
|
@:keep
|
||||||
(method :Void _strobe [:Bool skipping :Bool prop :String actorOrPropKey :Float strobeSec :Int times &opt :Continuation cc]
|
(method :Void _strobe [:Bool skipping :Bool prop :String actorOrPropKey :Float strobeSec :Int times &opt :Continuation cc]
|
||||||
(when skipping
|
(when skipping
|
||||||
@@ -497,6 +579,13 @@
|
|||||||
(when cc
|
(when cc
|
||||||
(TimerWithPause.delay cc (* strobeSec 2 (+ 1 times)))))))
|
(TimerWithPause.delay cc (* strobeSec 2 (+ 1 times)))))))
|
||||||
|
|
||||||
|
// END Parent class definitions
|
||||||
|
|
||||||
|
(defMacro indexAssetPaths [dir]
|
||||||
|
`(preload
|
||||||
|
(_indexAssetPaths ,dir)))
|
||||||
|
|
||||||
|
|
||||||
// Some real magic happens here. This macro defines a method, AND a reader macro
|
// Some real magic happens here. This macro defines a method, AND a reader macro
|
||||||
// for calling it with skipping and cc passed automatically if cc is an argument.
|
// for calling it with skipping and cc passed automatically if cc is an argument.
|
||||||
// GOTCHA: DO NOT use (method) directly in this file!!
|
// GOTCHA: DO NOT use (method) directly in this file!!
|
||||||
@@ -574,26 +663,6 @@
|
|||||||
}))
|
}))
|
||||||
(otherwise (throw "Unsupported delay type $delayHandling")))))
|
(otherwise (throw "Unsupported delay type $delayHandling")))))
|
||||||
|
|
||||||
(hollywooMethod newSet [name :Set set]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet sets name set))
|
|
||||||
|
|
||||||
(hollywooMethod newSceneFromSet [name :String setKey :SceneTime time :ScenePerspective perspective :Camera camera]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet scenes name (objectWith
|
|
||||||
[
|
|
||||||
set
|
|
||||||
(.clone (dictGet sets setKey))
|
|
||||||
characters
|
|
||||||
(new FuzzyMap<Character<Actor>>)
|
|
||||||
props
|
|
||||||
(new FuzzyMap<StageProp<Prop>>)
|
|
||||||
camera
|
|
||||||
camera
|
|
||||||
]
|
|
||||||
time
|
|
||||||
perspective)))
|
|
||||||
|
|
||||||
(hollywooMethod setSceneSong [:String scene :String songKey &opt :Float volumeMod :Continuation cc]
|
(hollywooMethod setSceneSong [:String scene :String songKey &opt :Float volumeMod :Continuation cc]
|
||||||
(dictSet sceneMusic scene songKey)
|
(dictSet sceneMusic scene songKey)
|
||||||
(dictSet sceneMusicVolume scene volumeMod)
|
(dictSet sceneMusicVolume scene volumeMod)
|
||||||
@@ -633,12 +702,6 @@
|
|||||||
.camera (dictGet scenes name)
|
.camera (dictGet scenes name)
|
||||||
cc)))))
|
cc)))))
|
||||||
|
|
||||||
|
|
||||||
(hollywooMethod newSound [name :Sound s :String description]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet sounds name s)
|
|
||||||
(dictSet soundDescriptions name description))
|
|
||||||
|
|
||||||
(hollywooMethod playSound [:Bool skipping name :Continuation cc &opt :Float volumeMod :Bool waitForEnd]
|
(hollywooMethod playSound [:Bool skipping name :Continuation cc &opt :Float volumeMod :Bool waitForEnd]
|
||||||
(when skipping
|
(when skipping
|
||||||
(cc)
|
(cc)
|
||||||
@@ -692,10 +755,6 @@
|
|||||||
(playAgain))))
|
(playAgain))))
|
||||||
(cc))
|
(cc))
|
||||||
|
|
||||||
(hollywooMethod newSong [name :Song song]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet songs name song))
|
|
||||||
|
|
||||||
// This is never skipped because the music might be expected to continue on to the place
|
// This is never skipped because the music might be expected to continue on to the place
|
||||||
// we skip to:
|
// we skip to:
|
||||||
(hollywooMethod playSong [name :Continuation cc &opt :Float volumeMod :Bool loop :Bool waitForEnd]
|
(hollywooMethod playSong [name :Continuation cc &opt :Float volumeMod :Bool loop :Bool waitForEnd]
|
||||||
@@ -719,10 +778,6 @@
|
|||||||
(director.stopSong)
|
(director.stopSong)
|
||||||
(cc))
|
(cc))
|
||||||
|
|
||||||
(hollywooMethod newActor [name :Actor actor]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet actors name actor))
|
|
||||||
|
|
||||||
(hollywooMethod autoZProcess [:StagePosition position :Continuation cc]
|
(hollywooMethod autoZProcess [:StagePosition position :Continuation cc]
|
||||||
// handle auto z recursively
|
// handle auto z recursively
|
||||||
(ifLet [(Some (objectWith zPerLayer frontLayer)) (director.autoZConfig)]
|
(ifLet [(Some (objectWith zPerLayer frontLayer)) (director.autoZConfig)]
|
||||||
@@ -802,10 +857,6 @@
|
|||||||
// TODO moveCharacter remove them, add them to another scene
|
// TODO moveCharacter remove them, add them to another scene
|
||||||
// TODO moveCharacterAndFollow remove them, add them to another scene, set that the scene
|
// TODO moveCharacterAndFollow remove them, add them to another scene, set that the scene
|
||||||
|
|
||||||
(hollywooMethod newProp [name :Prop prop]
|
|
||||||
(assert isLoading)
|
|
||||||
(dictSet props name prop))
|
|
||||||
|
|
||||||
(hollywooMethod addProp [name :Dynamic position :Continuation cc]
|
(hollywooMethod addProp [name :Dynamic position :Continuation cc]
|
||||||
(let [name (FuzzyMapTools.bestMatch props name)
|
(let [name (FuzzyMapTools.bestMatch props name)
|
||||||
prop (dictGet props name)
|
prop (dictGet props name)
|
||||||
|
@@ -38,7 +38,7 @@ typedef StageProp<Prop> = {
|
|||||||
prop:Prop
|
prop:Prop
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Scene<Set:Cloneable<Set>, Actor, Prop, Camera> = {
|
typedef Scene<Set, Actor, Prop, Camera> = {
|
||||||
set:Set,
|
set:Set,
|
||||||
characters:FuzzyMap<Character<Actor>>,
|
characters:FuzzyMap<Character<Actor>>,
|
||||||
props:FuzzyMap<StageProp<Prop>>,
|
props:FuzzyMap<StageProp<Prop>>,
|
||||||
|
Reference in New Issue
Block a user