You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.7KB

  1. use std::fs::File;
  2. use std::io::{BufReader, BufRead, Read};
  3. use std::path::{Path, PathBuf};
  4. use std::sync::{RwLock};
  5. use crate::instruction::{Instruction, CameraData};
  6. lazy_static! {
  7. pub(crate) static ref FILE_HANDLES: RwLock<Vec<FilmscriptFile>> = RwLock::new(Vec::new());
  8. }
  9. pub struct FilmscriptFile {
  10. path: Option<PathBuf>,
  11. buffer: Box<dyn BufRead + Sync + Send>,
  12. index: usize,
  13. instructions: Vec<Instruction>,
  14. done: bool,
  15. done_msg: String,
  16. }
  17. impl FilmscriptFile {
  18. pub fn from_path<'a>(path: &'a Path) -> std::io::Result<FilmscriptFile> {
  19. let new_reader = File::open(path)?;
  20. std::io::Result::Ok(FilmscriptFile {
  21. path: Some(PathBuf::from(path)),
  22. //reader: new_reader,
  23. buffer: Box::new(BufReader::new(new_reader)),
  24. index: 0,
  25. instructions: Vec::new(),
  26. done: false,
  27. done_msg: String::new(),
  28. })
  29. }
  30. pub fn from_static_slice(buf: &'static[u8]) -> std::io::Result<FilmscriptFile> {
  31. std::io::Result::Ok(FilmscriptFile {
  32. path: None,
  33. buffer: Box::new(buf),
  34. index: 0,
  35. instructions: Vec::new(),
  36. done: false,
  37. done_msg: String::new(),
  38. })
  39. }
  40. pub fn from_slice(buf: &[u8]) -> std::io::Result<FilmscriptFile> {
  41. Self::from_vec(&Vec::from(buf))
  42. }
  43. pub fn from_vec(buf: &Vec<u8>) -> std::io::Result<FilmscriptFile> {
  44. let new_reader = VectorReader{vec: buf.clone()};
  45. std::io::Result::Ok(FilmscriptFile {
  46. path: None,
  47. buffer: Box::new(BufReader::new(new_reader)),
  48. index: 0,
  49. instructions: Vec::new(),
  50. done: false,
  51. done_msg: String::new(),
  52. })
  53. }
  54. pub fn filepath(&self) -> Option<PathBuf> {
  55. self.path.clone()
  56. }
  57. pub fn is_done(&self) -> bool {
  58. self.done
  59. }
  60. pub fn done_msg(&self) -> String {
  61. self.done_msg.clone()
  62. }
  63. fn next_instruction(&mut self) -> Result<Instruction, String> {
  64. let mut buf = String::new();
  65. if let Ok(len) = self.buffer.read_line(&mut buf) {
  66. let instr = Instruction::parse_line(&buf[..len])?;
  67. self.instructions.push(instr.clone());
  68. return Ok(instr);
  69. }
  70. Err("End of file".to_string())
  71. }
  72. pub(crate) fn lerp(&mut self, now: f64) -> CameraData {
  73. if self.index >= self.instructions.len() {
  74. match self.next_instruction() {
  75. Ok(_) => {
  76. if self.index == 0 {
  77. // do initial init
  78. self.instructions[0].start(now, CameraData::default());
  79. } else {
  80. let end = self.instructions[self.index-1].start + self.instructions[self.index-1].instr.time();
  81. let base = self.instructions[self.index-1].instr.lerp(0.0, self.instructions[self.index-1].instr.time());
  82. self.instructions[self.index].start(end, base);
  83. }
  84. },
  85. Err(msg) => {
  86. self.done = true;
  87. self.done_msg = msg;
  88. },
  89. }
  90. }
  91. let curr_instr = &mut self.instructions[self.index];
  92. let cam_data = curr_instr.lerp(now);
  93. if curr_instr.done() {
  94. self.index+=1;
  95. }
  96. cam_data
  97. }
  98. }
  99. impl Read for FilmscriptFile {
  100. fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
  101. self.buffer.read(buf)
  102. }
  103. }
  104. struct VectorReader {
  105. vec: Vec<u8>
  106. }
  107. impl Read for VectorReader {
  108. fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
  109. self.vec.as_slice().read(buf)
  110. }
  111. }