1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
#![allow(unused_imports)]
use std::{collections::HashMap, rc::Rc};
use crate::engine::d2::{
asset::{AssetPack, File},
display::Sprite,
swf::Format,
};
use super::{
BitmapSymbol, Flipbook, KeyframeFormat, MovieFormat, MovieSprite, MovieSymbol, Symbol,
};
/// An exported Flump library containing movies and bitmaps.
#[derive(Default, Clone, Debug)]
pub struct Library {
/// The original frame rate of movies in this library.
pub frame_rate: f32,
file: Option<Rc<dyn File>>,
symbols: HashMap<String, Rc<dyn Symbol<MovieSprite>>>,
}
impl Library {
/// Creates a library using files in an AssetPack.
/// @param baseDir The directory in the pack containing Flump's library.json and texture atlases.
pub fn new(pack: impl AssetPack, base_dir: String) -> Self {
let instance = Self {
file: pack.file(base_dir + "/library.json", true),
symbols: HashMap::new(),
frame_rate: 0.0,
};
// let json: Format = Json::parse(instance._file.toString());
// instance.frameRate = json.frameRate;
// let movies = Vec::new();
// for movieObject in json.movies {
// let movie = MovieSymbol::new(instance, movieObject);
// movies.push(movie);
// instance._symbols.set(movie.name, movie);
// }
// let groups = json.textureGroups;
// if groups[0].scaleFactor != 1 || groups.len() > 1 {
// log::warn!("Dx doesn't support Additional Scale Factors. Use Base Scales and load from different asset packs instead." );
// }
// let atlases = groups[0].atlases;
// for atlasObject in atlases {
// let atlas = pack.get_texture(baseDir + "/" + atlasObject.file.removeFileExtension());
// for textureObject in atlasObject.textures {
// let bitmap = BitmapSymbol::new(textureObject, atlas);
// instance._symbols.set(bitmap.name, bitmap);
// }
// }
// // Now that all symbols have been parsed, go through keyframes and resolve references
// for movie in movies {
// for layer in movie.layers {
// let keyframes = layer.keyframes;
// let ll = keyframes.len();
// for ii in 0..ll {
// let kf = keyframes[ii];
// if kf.symbolName.is_some() {
// let symbol = instance._symbols.get(kf.symbolName);
// assert!(symbol.is_some());
// kf.setSymbol(symbol);
// }
// // Specially handle "stop frames". These are one-frame keyframes that preceed an
// // invisible or empty keyframe. Dx animates at 60 FPS, which can cause unexpected motion/flickering as those
// // one-frame keyframes are interpolated. So, assume that these frames are never
// // meant to actually be displayed and hide them.
// if kf.tweened && kf.duration == 1 && ii + 1 < ll {
// let nextKf = keyframes[ii + 1];
// if !nextKf.visible || nextKf.symbolName.is_none() {
// kf.setVisible(false);
// }
// }
// }
// }
// }
instance
}
/// Creates a library procedurally using a set of Flipbook definitions. Each flipbook will be
/// converted to a movie that can be instanciated with `createMovie()`.
/// *
// ```
// let lib = Library.fromFlipbooks([
// // A walk animation from a 5x3 sprite sheet, that lasts 5 seconds
// Flipbook::new("walk", spriteSheet.split(5, 3)).set_duration(5).set_anchor(10, 10),
// *
// // Another animation where each frame comes from a separate image (Jump1.png, Jump2.png, ..)
// Flipbook::new("jump", [for (frame in 1..10) pack.get_texture("Jump"+frame)]),
// ]);
// let movie = lib.createMovie("walk");
// ```
// static
pub fn from_flipbooks(flipbooks: Vec<Flipbook>) -> Library {
// let lib = Type::createEmptyInstance(Library);
// lib._symbols = HashMap::new();
// lib.frameRate = 60;
// lib._file = None;
// for flipbook in flipbooks {
// // Fake up some Flump metadata to create a movie symbol
// let keyframes: Vec<KeyframeFormat> = Vec::new();
// for frame in flipbook.frames {
// // keyframes.push({
// // duration: frame.duration*lib.frameRate,
// // label: frame.label,
// // pivot: [frame.anchorX, frame.anchorY],
// // ref_: "", // Hack so that this keyframe doesn't get marked as empty
// // });
// }
// let movie = MovieSymbol::new(
// lib, MovieFormat::default()//,
// // {
// // id: flipbook.name,
// // layers: [{
// // name: "flipbook",
// // flipbook: true,
// // keyframes: keyframes,
// // }],
// // }
// );
// lib._symbols.set(flipbook.name, movie);
// // Assign symbols at each keyframe
// let keyframes = movie.layers[0].keyframes;
// for ii in 0..flipbook.frames.len() {
// keyframes[ii].setSymbol(flipbook.frames[ii].toSymbol());
// }
// }
// lib
unimplemented!()
}
/// Disposes the source library.json File used to create this Library. This can free up some
/// memory, if you don't intend to recreate this Library later from the same AssetPack.
/// *
/// @returns This instance, for chaining.
pub fn dispose_files(&self) -> &Self {
if let Some(ref file) = self.file {
file.dispose();
}
self
}
/// Retrieve a name symbol from this library, or None if not found.
#[inline]
pub fn symbol(&self, symbol_name: String) -> Option<&Rc<dyn Symbol<MovieSprite>>> {
self.symbols.get(&symbol_name)
}
/// Creates a sprite from a symbol name, it'll either be a movie or a bitmap.
/// @param required If true and the symbol is not in this library, an error is thrown.
// required :bool = true
pub fn create_sprite(&self, symbol_name: String, required: bool) -> Option<Sprite> {
// if let Some(symbol) = self.symbols.get(&symbolName) {
// Some(symbol.create_sprite())
// } else {
// if required {
// panic!("Missing symbol {}", symbolName);
// }
// return None;
// }
unimplemented!()
}
/// Creates a movie sprite from a symbol name.
/// @param required If true and the symbol is not in this library, an error is thrown.
// required :bool = true
#[inline]
pub fn create_movie(&self, symbol_name: String, required: bool) -> Option<MovieSprite> {
// self.create_sprite(symbolName, required)
unimplemented!()
}
/// Iterates over all the symbols in this library.
// #[inline]
// pub fn iter(&self) -> impl Iterator<Item = (&'_ String, &'_ Box<dyn Symbol<MovieSprite>>)> {
// self.symbols.iter()
// }
#[inline]
pub fn iter(&self) -> impl Iterator<Item = (&String, &Rc<dyn Symbol<MovieSprite>>)> + '_ {
self.symbols.iter()
}
}