2019-04-27 01:55:06 +00:00
|
|
|
use crate::player::{RenderContext, UpdateContext};
|
2019-04-29 05:55:44 +00:00
|
|
|
use crate::prelude::*;
|
|
|
|
use crate::transform::Transform;
|
2019-05-09 01:10:43 +00:00
|
|
|
use gc::{Gc, GcCell, Trace};
|
|
|
|
use std::collections::VecDeque;
|
2019-04-25 17:52:22 +00:00
|
|
|
|
2019-05-09 01:10:43 +00:00
|
|
|
#[derive(Clone, Trace, Finalize)]
|
2019-04-29 05:55:44 +00:00
|
|
|
pub struct DisplayObjectBase {
|
2019-05-09 01:10:43 +00:00
|
|
|
#[unsafe_ignore_trace]
|
2019-04-29 05:55:44 +00:00
|
|
|
depth: Depth,
|
2019-05-09 01:10:43 +00:00
|
|
|
#[unsafe_ignore_trace]
|
2019-04-29 05:55:44 +00:00
|
|
|
transform: Transform,
|
2019-05-06 18:15:52 +00:00
|
|
|
name: String,
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
|
|
|
|
2019-04-29 05:55:44 +00:00
|
|
|
impl Default for DisplayObjectBase {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
depth: Default::default(),
|
|
|
|
transform: Default::default(),
|
2019-05-06 18:15:52 +00:00
|
|
|
name: Default::default(),
|
2019-04-26 03:27:44 +00:00
|
|
|
}
|
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
}
|
2019-04-26 03:27:44 +00:00
|
|
|
|
2019-04-29 05:55:44 +00:00
|
|
|
impl DisplayObjectImpl for DisplayObjectBase {
|
2019-05-01 16:55:54 +00:00
|
|
|
fn transform(&self) -> &Transform {
|
|
|
|
&self.transform
|
|
|
|
}
|
|
|
|
|
2019-04-29 05:55:44 +00:00
|
|
|
fn get_matrix(&self) -> &Matrix {
|
|
|
|
&self.transform.matrix
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
fn set_matrix(&mut self, matrix: &Matrix) {
|
2019-05-03 18:44:12 +00:00
|
|
|
self.transform.matrix = *matrix;
|
2019-04-26 03:27:44 +00:00
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
fn get_color_transform(&self) -> &ColorTransform {
|
|
|
|
&self.transform.color_transform
|
|
|
|
}
|
|
|
|
fn set_color_transform(&mut self, color_transform: &ColorTransform) {
|
2019-05-03 18:44:12 +00:00
|
|
|
self.transform.color_transform = *color_transform;
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
2019-05-06 18:15:52 +00:00
|
|
|
fn name(&self) -> &str {
|
|
|
|
&self.name
|
|
|
|
}
|
|
|
|
fn set_name(&mut self, name: &str) {
|
|
|
|
self.name = name.to_string();
|
|
|
|
}
|
2019-05-09 01:10:43 +00:00
|
|
|
fn box_clone(&self) -> Box<DisplayObjectImpl> {
|
|
|
|
Box::new(self.clone())
|
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 10:34:17 +00:00
|
|
|
pub trait DisplayObjectImpl: Trace {
|
2019-05-01 16:55:54 +00:00
|
|
|
fn transform(&self) -> &Transform;
|
2019-04-29 05:55:44 +00:00
|
|
|
fn get_matrix(&self) -> &Matrix;
|
|
|
|
fn set_matrix(&mut self, matrix: &Matrix);
|
|
|
|
fn get_color_transform(&self) -> &ColorTransform;
|
|
|
|
fn set_color_transform(&mut self, color_transform: &ColorTransform);
|
2019-05-06 18:15:52 +00:00
|
|
|
fn name(&self) -> &str;
|
|
|
|
fn set_name(&mut self, name: &str);
|
2019-04-26 21:11:29 +00:00
|
|
|
|
2019-05-06 00:35:00 +00:00
|
|
|
fn preload(&self, _context: &mut UpdateContext) {}
|
2019-04-29 05:55:44 +00:00
|
|
|
fn run_frame(&mut self, _context: &mut UpdateContext) {}
|
2019-05-02 00:46:49 +00:00
|
|
|
fn run_post_frame(&mut self, _context: &mut UpdateContext) {}
|
2019-04-29 05:55:44 +00:00
|
|
|
fn render(&self, _context: &mut RenderContext) {}
|
2019-05-03 18:44:12 +00:00
|
|
|
|
|
|
|
fn handle_click(&mut self, _pos: (f32, f32)) {}
|
2019-05-09 01:10:43 +00:00
|
|
|
fn visit_children(&self, queue: &mut VecDeque<Gc<GcCell<DisplayObject>>>) {}
|
2019-05-07 06:31:34 +00:00
|
|
|
fn as_movie_clip(&self) -> Option<&crate::movie_clip::MovieClip> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
fn as_movie_clip_mut(&mut self) -> Option<&mut crate::movie_clip::MovieClip> {
|
|
|
|
None
|
|
|
|
}
|
2019-05-09 01:10:43 +00:00
|
|
|
fn box_clone(&self) -> Box<DisplayObjectImpl>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clone for Box<DisplayObjectImpl> {
|
|
|
|
fn clone(&self) -> Box<DisplayObjectImpl> {
|
|
|
|
self.box_clone()
|
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! impl_display_object {
|
2019-05-07 10:34:17 +00:00
|
|
|
($field:ident) => {
|
2019-05-09 01:10:43 +00:00
|
|
|
fn transform(&self) -> &crate::transform::Transform {
|
|
|
|
self.$field.transform()
|
|
|
|
}
|
|
|
|
fn get_matrix(&self) -> &Matrix {
|
|
|
|
self.$field.get_matrix()
|
|
|
|
}
|
|
|
|
fn set_matrix(&mut self, matrix: &Matrix) {
|
|
|
|
self.$field.set_matrix(matrix)
|
|
|
|
}
|
|
|
|
fn get_color_transform(&self) -> &ColorTransform {
|
|
|
|
self.$field.get_color_transform()
|
|
|
|
}
|
|
|
|
fn set_color_transform(&mut self, color_transform: &ColorTransform) {
|
|
|
|
self.$field.set_color_transform(color_transform)
|
|
|
|
}
|
|
|
|
fn name(&self) -> &str {
|
|
|
|
self.$field.name()
|
|
|
|
}
|
|
|
|
fn set_name(&mut self, name: &str) {
|
|
|
|
self.$field.set_name(name)
|
|
|
|
}
|
|
|
|
fn box_clone(&self) -> Box<$crate::display_object::DisplayObjectImpl> {
|
|
|
|
Box::new(self.clone())
|
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO(Herschel): We wrap in a box because using a trait object
|
|
|
|
// directly with Cc gets hairy.
|
|
|
|
// Extra heap allocation, though.
|
|
|
|
// Revisit this eventually, some possibilities:
|
|
|
|
// - Just use a dumb enum.
|
|
|
|
// - Some DST magic if we remove the Box below and mark this !Sized?
|
2019-05-09 01:10:43 +00:00
|
|
|
#[derive(Clone, Trace, Finalize)]
|
2019-04-29 05:55:44 +00:00
|
|
|
pub struct DisplayObject {
|
|
|
|
inner: Box<DisplayObjectImpl>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DisplayObject {
|
|
|
|
pub fn new(inner: Box<DisplayObjectImpl>) -> DisplayObject {
|
|
|
|
DisplayObject { inner }
|
2019-04-26 21:11:29 +00:00
|
|
|
}
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 10:34:17 +00:00
|
|
|
impl DisplayObjectImpl for DisplayObject {
|
|
|
|
impl_display_object!(inner);
|
2019-04-29 05:55:44 +00:00
|
|
|
|
2019-05-06 00:35:00 +00:00
|
|
|
fn preload(&self, context: &mut UpdateContext) {
|
|
|
|
self.inner.preload(context);
|
|
|
|
}
|
|
|
|
|
2019-04-29 05:55:44 +00:00
|
|
|
fn run_frame(&mut self, context: &mut UpdateContext) {
|
|
|
|
self.inner.run_frame(context)
|
|
|
|
}
|
2019-05-02 00:46:49 +00:00
|
|
|
|
|
|
|
fn run_post_frame(&mut self, context: &mut UpdateContext) {
|
|
|
|
self.inner.run_post_frame(context)
|
2019-04-29 05:55:44 +00:00
|
|
|
}
|
2019-05-02 00:46:49 +00:00
|
|
|
|
2019-04-29 05:55:44 +00:00
|
|
|
fn render(&self, context: &mut RenderContext) {
|
|
|
|
self.inner.render(context)
|
|
|
|
}
|
2019-05-03 18:44:12 +00:00
|
|
|
|
|
|
|
fn handle_click(&mut self, pos: (f32, f32)) {
|
|
|
|
self.inner.handle_click(pos)
|
|
|
|
}
|
2019-05-07 06:31:34 +00:00
|
|
|
|
2019-05-09 01:10:43 +00:00
|
|
|
fn visit_children(&self, queue: &mut VecDeque<Gc<GcCell<DisplayObject>>>) {
|
2019-05-07 06:31:34 +00:00
|
|
|
self.inner.visit_children(queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn as_movie_clip(&self) -> Option<&crate::movie_clip::MovieClip> {
|
|
|
|
self.inner.as_movie_clip()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn as_movie_clip_mut(&mut self) -> Option<&mut crate::movie_clip::MovieClip> {
|
|
|
|
self.inner.as_movie_clip_mut()
|
|
|
|
}
|
2019-04-29 05:55:44 +00:00
|
|
|
}
|
|
|
|
|
2019-05-07 06:31:34 +00:00
|
|
|
pub struct DisplayObjectVisitor {
|
2019-05-09 01:10:43 +00:00
|
|
|
pub open: VecDeque<Gc<GcCell<DisplayObject>>>,
|
2019-05-07 06:31:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl DisplayObjectVisitor {
|
|
|
|
pub fn run(&mut self, context: &mut crate::player::UpdateContext) {
|
|
|
|
let root = self.open[0].clone();
|
|
|
|
while let Some(node) = self.open.pop_front() {
|
|
|
|
// {
|
|
|
|
// let mut node = node.borrow_mut();
|
|
|
|
// node.run_frame(context);
|
|
|
|
// }
|
|
|
|
let mut action = None;
|
|
|
|
if let Some(clip) = node.borrow().as_movie_clip() {
|
|
|
|
action = clip.action();
|
|
|
|
}
|
|
|
|
if let Some((pos, len)) = action {
|
|
|
|
let mut action_context = crate::avm1::ActionContext {
|
|
|
|
global_time: context.global_time,
|
|
|
|
start_clip: node.clone(),
|
|
|
|
active_clip: node.clone(),
|
|
|
|
root: root.clone(),
|
|
|
|
audio: context.audio,
|
|
|
|
};
|
|
|
|
let data = &context.tag_stream.get_ref().get_ref()[pos..pos + len];
|
|
|
|
if let Err(e) = context.avm1.do_action(&mut action_context, &data[..]) {}
|
|
|
|
}
|
|
|
|
node.borrow_mut().run_post_frame(context);
|
|
|
|
node.borrow().visit_children(&mut self.open);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|