ruffle/core/src/graphic.rs

91 lines
2.5 KiB
Rust
Raw Normal View History

use crate::backend::render::ShapeHandle;
2019-07-19 08:32:41 +00:00
use crate::display_object::{DisplayObject, DisplayObjectBase};
2019-04-27 01:55:06 +00:00
use crate::player::{RenderContext, UpdateContext};
use crate::prelude::*;
2019-04-25 17:52:22 +00:00
#[derive(Clone, Debug)]
2019-08-13 02:00:12 +00:00
pub struct Graphic<'gc> {
base: DisplayObjectBase<'gc>,
static_data: gc_arena::Gc<'gc, GraphicStatic>,
2019-04-25 17:52:22 +00:00
}
2019-08-13 02:00:12 +00:00
impl<'gc> Graphic<'gc> {
pub fn from_swf_tag(context: &mut UpdateContext<'_, 'gc, '_>, swf_shape: &swf::Shape) -> Self {
let static_data = GraphicStatic {
id: swf_shape.id,
render_handle: context.renderer.register_shape(swf_shape),
bounds: swf_shape.shape_bounds.clone().into(),
};
2019-04-25 17:52:22 +00:00
Graphic {
base: DisplayObjectBase::new(context.swf_version),
static_data: gc_arena::Gc::allocate(context.gc_context, static_data),
2019-04-25 17:52:22 +00:00
}
}
}
2019-08-13 02:00:12 +00:00
impl<'gc> DisplayObject<'gc> for Graphic<'gc> {
2019-05-07 10:34:17 +00:00
impl_display_object!(base);
2019-04-29 05:55:44 +00:00
2019-09-15 18:34:30 +00:00
fn id(&self) -> CharacterId {
self.static_data.id
}
fn local_bounds(&self) -> BoundingBox {
self.static_data.bounds.clone()
}
fn world_bounds(&self) -> BoundingBox {
// TODO: Use dirty flags and cache this.
let mut bounds = self.local_bounds().transform(self.matrix());
let mut node = self.parent();
while let Some(display_object) = node {
let display_object = display_object.read();
bounds = bounds.transform(display_object.matrix());
node = display_object.parent();
}
bounds
}
2019-04-26 03:27:44 +00:00
fn run_frame(&mut self, _context: &mut UpdateContext) {
2019-04-25 17:52:22 +00:00
// Noop
}
fn render(&self, context: &mut RenderContext) {
if !self.world_bounds().intersects(&context.view_bounds) {
// Off-screen; culled
return;
}
2019-05-01 16:55:54 +00:00
context.transform_stack.push(self.transform());
2019-04-26 21:11:29 +00:00
context.renderer.render_shape(
self.static_data.render_handle,
context.transform_stack.transform(),
);
2019-04-27 17:54:37 +00:00
2019-05-01 16:55:54 +00:00
context.transform_stack.pop();
2019-04-26 21:11:29 +00:00
}
2019-04-25 17:52:22 +00:00
}
2019-05-24 17:25:03 +00:00
2019-08-13 02:00:12 +00:00
unsafe impl<'gc> gc_arena::Collect for Graphic<'gc> {
fn trace(&self, cc: gc_arena::CollectionContext) {
self.base.trace(cc);
self.static_data.trace(cc);
2019-05-24 17:25:03 +00:00
}
}
/// Static data shared between all instances of a graphic.
#[allow(dead_code)]
struct GraphicStatic {
id: CharacterId,
render_handle: ShapeHandle,
bounds: BoundingBox,
}
unsafe impl<'gc> gc_arena::Collect for GraphicStatic {
#[inline]
fn needs_trace() -> bool {
false
}
}