swf: Simplify read of `PlaceObject` tags
`tag_length` isn't really necessary since each tag is read using a dedicated `swf::Reader`, which keeps track of the tag boundary internally. As a result, `tag_len` can be avoided passed around many times in `movie_clip.rs`.
This commit is contained in:
parent
8f214ff9a3
commit
c516fef65d
|
@ -1339,16 +1339,16 @@ impl<'gc> MovieClip<'gc> {
|
|||
match tag_code {
|
||||
TagCode::DoAction => self.do_action(context, reader, tag_len),
|
||||
TagCode::PlaceObject if run_display_actions && !context.is_action_script_3() => {
|
||||
self.place_object(context, reader, tag_len, 1)
|
||||
self.place_object(context, reader, 1)
|
||||
}
|
||||
TagCode::PlaceObject2 if run_display_actions && !context.is_action_script_3() => {
|
||||
self.place_object(context, reader, tag_len, 2)
|
||||
self.place_object(context, reader, 2)
|
||||
}
|
||||
TagCode::PlaceObject3 if run_display_actions && !context.is_action_script_3() => {
|
||||
self.place_object(context, reader, tag_len, 3)
|
||||
self.place_object(context, reader, 3)
|
||||
}
|
||||
TagCode::PlaceObject4 if run_display_actions && !context.is_action_script_3() => {
|
||||
self.place_object(context, reader, tag_len, 4)
|
||||
self.place_object(context, reader, 4)
|
||||
}
|
||||
TagCode::RemoveObject if run_display_actions && !context.is_action_script_3() => {
|
||||
self.remove_object(context, reader, 1)
|
||||
|
@ -1357,22 +1357,22 @@ impl<'gc> MovieClip<'gc> {
|
|||
self.remove_object(context, reader, 2)
|
||||
}
|
||||
TagCode::PlaceObject if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_place_object(context, reader, tag_len, 1)
|
||||
self.queue_place_object(context, reader, 1)
|
||||
}
|
||||
TagCode::PlaceObject2 if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_place_object(context, reader, tag_len, 2)
|
||||
self.queue_place_object(context, reader, 2)
|
||||
}
|
||||
TagCode::PlaceObject3 if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_place_object(context, reader, tag_len, 3)
|
||||
self.queue_place_object(context, reader, 3)
|
||||
}
|
||||
TagCode::PlaceObject4 if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_place_object(context, reader, tag_len, 4)
|
||||
self.queue_place_object(context, reader, 4)
|
||||
}
|
||||
TagCode::RemoveObject if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_remove_object(context, reader, tag_len, 1)
|
||||
self.queue_remove_object(context, reader, 1)
|
||||
}
|
||||
TagCode::RemoveObject2 if run_display_actions && context.is_action_script_3() => {
|
||||
self.queue_remove_object(context, reader, tag_len, 2)
|
||||
self.queue_remove_object(context, reader, 2)
|
||||
}
|
||||
TagCode::SetBackgroundColor => self.set_background_color(context, reader),
|
||||
TagCode::StartSound if run_sounds => self.start_sound_1(context, reader),
|
||||
|
@ -1675,60 +1675,28 @@ impl<'gc> MovieClip<'gc> {
|
|||
self.0.write(context.gc_context).current_frame += 1;
|
||||
frame_pos = reader.get_ref().as_ptr() as u64 - tag_stream_start;
|
||||
|
||||
use swf::TagCode;
|
||||
let tag_callback = |reader: &mut _, tag_code, tag_len| {
|
||||
let tag_callback = |reader: &mut _, tag_code, _tag_len| {
|
||||
use swf::TagCode;
|
||||
match tag_code {
|
||||
TagCode::PlaceObject => {
|
||||
index += 1;
|
||||
let mut mc = self.0.write(context.gc_context);
|
||||
|
||||
mc.goto_place_object(
|
||||
reader,
|
||||
tag_len,
|
||||
1,
|
||||
&mut goto_commands,
|
||||
is_rewind,
|
||||
index,
|
||||
)
|
||||
mc.goto_place_object(reader, 1, &mut goto_commands, is_rewind, index)
|
||||
}
|
||||
TagCode::PlaceObject2 => {
|
||||
index += 1;
|
||||
let mut mc = self.0.write(context.gc_context);
|
||||
|
||||
mc.goto_place_object(
|
||||
reader,
|
||||
tag_len,
|
||||
2,
|
||||
&mut goto_commands,
|
||||
is_rewind,
|
||||
index,
|
||||
)
|
||||
mc.goto_place_object(reader, 2, &mut goto_commands, is_rewind, index)
|
||||
}
|
||||
TagCode::PlaceObject3 => {
|
||||
index += 1;
|
||||
let mut mc = self.0.write(context.gc_context);
|
||||
|
||||
mc.goto_place_object(
|
||||
reader,
|
||||
tag_len,
|
||||
3,
|
||||
&mut goto_commands,
|
||||
is_rewind,
|
||||
index,
|
||||
)
|
||||
mc.goto_place_object(reader, 3, &mut goto_commands, is_rewind, index)
|
||||
}
|
||||
TagCode::PlaceObject4 => {
|
||||
index += 1;
|
||||
let mut mc = self.0.write(context.gc_context);
|
||||
|
||||
mc.goto_place_object(
|
||||
reader,
|
||||
tag_len,
|
||||
4,
|
||||
&mut goto_commands,
|
||||
is_rewind,
|
||||
index,
|
||||
)
|
||||
mc.goto_place_object(reader, 4, &mut goto_commands, is_rewind, index)
|
||||
}
|
||||
TagCode::RemoveObject => self.goto_remove_object(
|
||||
reader,
|
||||
|
@ -1808,7 +1776,6 @@ impl<'gc> MovieClip<'gc> {
|
|||
let new_tag = QueuedTag {
|
||||
tag_type: QueuedTagAction::Place(params.version),
|
||||
tag_start: params.tag_start,
|
||||
tag_len: params.tag_len,
|
||||
};
|
||||
let bucket = write
|
||||
.queued_tags
|
||||
|
@ -2343,7 +2310,7 @@ impl<'gc> TDisplayObject<'gc> for MovieClip<'gc> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let Err(e) = self.place_object(context, &mut reader, tag.tag_len, version) {
|
||||
if let Err(e) = self.place_object(context, &mut reader, version) {
|
||||
log::error!("Error running queued tag: {:?}, got {}", tag.tag_type, e);
|
||||
}
|
||||
}
|
||||
|
@ -2914,7 +2881,6 @@ impl<'gc> MovieClipData<'gc> {
|
|||
fn goto_place_object<'a>(
|
||||
&mut self,
|
||||
reader: &mut SwfStream<'a>,
|
||||
tag_len: usize,
|
||||
version: u8,
|
||||
goto_commands: &mut Vec<GotoPlaceObject<'a>>,
|
||||
is_rewind: bool,
|
||||
|
@ -2923,7 +2889,7 @@ impl<'gc> MovieClipData<'gc> {
|
|||
let tag_start =
|
||||
reader.get_ref().as_ptr() as u64 - self.static_data.swf.as_ref().as_ptr() as u64;
|
||||
let place_object = if version == 1 {
|
||||
reader.read_place_object(tag_len)
|
||||
reader.read_place_object()
|
||||
} else {
|
||||
reader.read_place_object_2_or_3(version)
|
||||
}?;
|
||||
|
@ -2936,7 +2902,6 @@ impl<'gc> MovieClipData<'gc> {
|
|||
is_rewind,
|
||||
index,
|
||||
tag_start,
|
||||
tag_len,
|
||||
version,
|
||||
);
|
||||
if let Some(i) = goto_commands.iter().position(|o| o.depth() == depth) {
|
||||
|
@ -3663,14 +3628,13 @@ impl<'gc, 'a> MovieClip<'gc> {
|
|||
self,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
reader: &mut SwfStream<'a>,
|
||||
tag_len: usize,
|
||||
version: u8,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(context.gc_context);
|
||||
let tag_start =
|
||||
reader.get_ref().as_ptr() as u64 - write.static_data.swf.as_ref().as_ptr() as u64;
|
||||
let place_object = if version == 1 {
|
||||
reader.read_place_object(tag_len)
|
||||
reader.read_place_object()
|
||||
} else {
|
||||
reader.read_place_object_2_or_3(version)
|
||||
}?;
|
||||
|
@ -3678,7 +3642,6 @@ impl<'gc, 'a> MovieClip<'gc> {
|
|||
let new_tag = QueuedTag {
|
||||
tag_type: QueuedTagAction::Place(version),
|
||||
tag_start,
|
||||
tag_len,
|
||||
};
|
||||
let bucket = write
|
||||
.queued_tags
|
||||
|
@ -3694,11 +3657,10 @@ impl<'gc, 'a> MovieClip<'gc> {
|
|||
self,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
reader: &mut SwfStream<'a>,
|
||||
tag_len: usize,
|
||||
version: u8,
|
||||
) -> Result<(), Error> {
|
||||
let place_object = if version == 1 {
|
||||
reader.read_place_object(tag_len)
|
||||
reader.read_place_object()
|
||||
} else {
|
||||
reader.read_place_object_2_or_3(version)
|
||||
}?;
|
||||
|
@ -3753,7 +3715,6 @@ impl<'gc, 'a> MovieClip<'gc> {
|
|||
self,
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
reader: &mut SwfStream<'a>,
|
||||
tag_len: usize,
|
||||
version: u8,
|
||||
) -> Result<(), Error> {
|
||||
let mut write = self.0.write(context.gc_context);
|
||||
|
@ -3768,7 +3729,6 @@ impl<'gc, 'a> MovieClip<'gc> {
|
|||
let new_tag = QueuedTag {
|
||||
tag_type: QueuedTagAction::Remove(version),
|
||||
tag_start,
|
||||
tag_len,
|
||||
};
|
||||
let bucket = write
|
||||
.queued_tags
|
||||
|
@ -3998,9 +3958,6 @@ struct GotoPlaceObject<'a> {
|
|||
/// not possible and we want to add children after the goto completes.
|
||||
tag_start: u64,
|
||||
|
||||
/// The length of the PlaceObject tag at `tag_start`.
|
||||
tag_len: usize,
|
||||
|
||||
/// The version of the PlaceObject tag at `tag_start`.
|
||||
version: u8,
|
||||
}
|
||||
|
@ -4012,7 +3969,6 @@ impl<'a> GotoPlaceObject<'a> {
|
|||
is_rewind: bool,
|
||||
index: usize,
|
||||
tag_start: u64,
|
||||
tag_len: usize,
|
||||
version: u8,
|
||||
) -> Self {
|
||||
if is_rewind {
|
||||
|
@ -4050,7 +4006,6 @@ impl<'a> GotoPlaceObject<'a> {
|
|||
place_object,
|
||||
index,
|
||||
tag_start,
|
||||
tag_len,
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
@ -4177,7 +4132,6 @@ impl QueuedTagList {
|
|||
pub struct QueuedTag {
|
||||
pub tag_type: QueuedTagAction,
|
||||
pub tag_start: u64,
|
||||
pub tag_len: usize,
|
||||
}
|
||||
|
||||
/// The type of queued tag.
|
||||
|
|
|
@ -591,9 +591,7 @@ impl<'a> Reader<'a> {
|
|||
|
||||
TagCode::DefineSprite => Tag::DefineSprite(tag_reader.read_define_sprite()?),
|
||||
|
||||
TagCode::PlaceObject => {
|
||||
Tag::PlaceObject(Box::new(tag_reader.read_place_object(length)?))
|
||||
}
|
||||
TagCode::PlaceObject => Tag::PlaceObject(Box::new(tag_reader.read_place_object()?)),
|
||||
TagCode::PlaceObject2 => {
|
||||
Tag::PlaceObject(Box::new(tag_reader.read_place_object_2_or_3(2)?))
|
||||
}
|
||||
|
@ -1834,20 +1832,14 @@ impl<'a> Reader<'a> {
|
|||
Ok(exports)
|
||||
}
|
||||
|
||||
pub fn read_place_object(&mut self, tag_length: usize) -> Result<PlaceObject<'a>> {
|
||||
// TODO: What's a best way to know if the tag has a color transform?
|
||||
// You only know if there is still data remaining after the matrix.
|
||||
// This sucks.
|
||||
let mut vector = [0; 128];
|
||||
self.get_mut().read_exact(&mut vector[..tag_length])?;
|
||||
let mut reader = Reader::new(&vector[..], self.version);
|
||||
pub fn read_place_object(&mut self) -> Result<PlaceObject<'a>> {
|
||||
Ok(PlaceObject {
|
||||
version: 1,
|
||||
action: PlaceObjectAction::Place(reader.read_u16()?),
|
||||
depth: reader.read_u16()?,
|
||||
matrix: Some(reader.read_matrix()?),
|
||||
color_transform: if !reader.get_ref().is_empty() {
|
||||
Some(reader.read_color_transform(false)?)
|
||||
action: PlaceObjectAction::Place(self.read_u16()?),
|
||||
depth: self.read_u16()?,
|
||||
matrix: Some(self.read_matrix()?),
|
||||
color_transform: if !self.get_ref().is_empty() {
|
||||
Some(self.read_color_transform(false)?)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue