use std::fs::File; use std::io::{BufReader, BufRead, Read}; use std::path::{Path, PathBuf}; use std::sync::{RwLock}; use crate::instruction::{Instruction, CameraData}; lazy_static! { pub(crate) static ref FILE_HANDLES: RwLock> = RwLock::new(Vec::new()); } pub struct FilmscriptFile { path: Option, buffer: Box, index: usize, instructions: Vec, done: bool, done_msg: String, } impl FilmscriptFile { pub fn from_path<'a>(path: &'a Path) -> std::io::Result { let new_reader = File::open(path)?; std::io::Result::Ok(FilmscriptFile { path: Some(PathBuf::from(path)), //reader: new_reader, buffer: Box::new(BufReader::new(new_reader)), index: 0, instructions: Vec::new(), done: false, done_msg: String::new(), }) } pub fn from_static_slice(buf: &'static[u8]) -> std::io::Result { std::io::Result::Ok(FilmscriptFile { path: None, buffer: Box::new(buf), index: 0, instructions: Vec::new(), done: false, done_msg: String::new(), }) } pub fn from_slice(buf: &[u8]) -> std::io::Result { Self::from_vec(&Vec::from(buf)) } pub fn from_vec(buf: &Vec) -> std::io::Result { let new_reader = VectorReader{vec: buf.clone()}; std::io::Result::Ok(FilmscriptFile { path: None, buffer: Box::new(BufReader::new(new_reader)), index: 0, instructions: Vec::new(), done: false, done_msg: String::new(), }) } pub fn filepath(&self) -> Option { self.path.clone() } pub fn is_done(&self) -> bool { self.done } pub fn done_msg(&self) -> String { self.done_msg.clone() } fn next_instruction(&mut self) -> Result { let mut buf = String::new(); if let Ok(len) = self.buffer.read_line(&mut buf) { let instr = Instruction::parse_line(&buf[..len])?; self.instructions.push(instr.clone()); return Ok(instr); } Err("End of file".to_string()) } pub(crate) fn lerp(&mut self, now: f64) -> CameraData { if self.index >= self.instructions.len() { match self.next_instruction() { Ok(_) => { if self.index == 0 { // do initial init self.instructions[0].start(now, CameraData::default()); } else { let end = self.instructions[self.index-1].start + self.instructions[self.index-1].instr.time(); let base = self.instructions[self.index-1].instr.lerp(0.0, self.instructions[self.index-1].instr.time()); self.instructions[self.index].start(end, base); } }, Err(msg) => { self.done = true; self.done_msg = msg; }, } } let curr_instr = &mut self.instructions[self.index]; let cam_data = curr_instr.lerp(now); if curr_instr.done() { self.index+=1; } cam_data } } impl Read for FilmscriptFile { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { self.buffer.read(buf) } } struct VectorReader { vec: Vec } impl Read for VectorReader { fn read(&mut self, buf: &mut [u8]) -> std::io::Result { self.vec.as_slice().read(buf) } }