Skip to content

Commit b2b1dff

Browse files
DinnerboneAaron1011
authored andcommitted
avm2: Move DisplayObject assignment into an initializer
1 parent cf4ca54 commit b2b1dff

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+969
-414
lines changed

core/src/avm2.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ pub use crate::avm2::globals::flash::ui::context_menu::make_context_menu_state;
6363
pub use crate::avm2::multiname::Multiname;
6464
pub use crate::avm2::namespace::Namespace;
6565
pub use crate::avm2::object::{
66-
ArrayObject, ClassObject, EventObject, Object, ScriptObject, SoundChannelObject, StageObject,
67-
TObject,
66+
ArrayObject, BitmapDataObject, ClassObject, EventObject, Object, ScriptObject,
67+
SoundChannelObject, StageObject, TObject,
6868
};
6969
pub use crate::avm2::qname::QName;
7070
pub use crate::avm2::value::Value;

core/src/avm2/globals.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub struct SystemClasses<'gc> {
7777
pub graphicstrianglepath: ClassObject<'gc>,
7878
pub graphicssolidfill: ClassObject<'gc>,
7979
pub graphicsstroke: ClassObject<'gc>,
80+
pub loader: ClassObject<'gc>,
8081
pub loaderinfo: ClassObject<'gc>,
8182
pub bytearray: ClassObject<'gc>,
8283
pub stage: ClassObject<'gc>,
@@ -188,6 +189,7 @@ impl<'gc> SystemClasses<'gc> {
188189
graphicstrianglepath: object,
189190
graphicssolidfill: object,
190191
graphicsstroke: object,
192+
loader: object,
191193
loaderinfo: object,
192194
bytearray: object,
193195
stage: object,
@@ -661,6 +663,7 @@ fn load_playerglobal<'gc>(
661663
("flash.display", "GraphicsSolidFill", graphicssolidfill),
662664
("flash.display", "GraphicsStroke", graphicsstroke),
663665
("flash.display", "Graphics", graphics),
666+
("flash.display", "Loader", loader),
664667
("flash.display", "LoaderInfo", loaderinfo),
665668
("flash.display", "MorphShape", morphshape),
666669
("flash.display", "MovieClip", movieclip),

core/src/avm2/globals/flash/display.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod graphics;
88
pub mod interactive_object;
99
pub mod loader;
1010
pub mod loader_info;
11+
pub mod morph_shape;
1112
pub mod movie_clip;
1213
pub mod shape;
1314
pub mod simple_button;

core/src/avm2/globals/flash/display/Bitmap.as

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package flash.display {
22

3+
[Ruffle(InstanceAllocator)]
34
public class Bitmap extends DisplayObject {
45
public native function get bitmapData():BitmapData;
56
public native function set bitmapData(value:BitmapData):void;

core/src/avm2/globals/flash/display/Loader.as

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
package flash.display {
2+
3+
[Ruffle(InstanceAllocator)]
24
public class Loader extends DisplayObjectContainer {
35
import flash.display.LoaderInfo;
46
import flash.display.DisplayObject;
@@ -14,12 +16,6 @@ package flash.display {
1416
return this._contentLoaderInfo;
1517
}
1618

17-
private native function init();
18-
19-
public function Loader() {
20-
this.init()
21-
}
22-
2319
public function get content():DisplayObject {
2420
if (this.numChildren == 0) {
2521
return null;
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package flash.display {
2+
[Ruffle(InstanceAllocator)]
23
public final class MorphShape extends DisplayObject {
34
public function MorphShape() {
4-
throw new ArgumentError("Error #2012: MorphShape$ class cannot be instantiated.", 2012)
5+
// We throw an error in `morph_shape_allocator`
56
}
67
}
78
}

core/src/avm2/globals/flash/display/Shape.as

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package flash.display {
2-
public class Shape extends DisplayObject {
3-
public function Shape() {
4-
this.init();
5-
}
6-
private native function init();
72

3+
[Ruffle(InstanceAllocator)]
4+
public class Shape extends DisplayObject {
85
public native function get graphics():Graphics;
96

107
internal var _graphics:Graphics;

core/src/avm2/globals/flash/display/SimpleButton.as

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package flash.display {
66
import flash.display.DisplayObject;
77
import flash.media.SoundTransform;
88

9+
[Ruffle(InstanceAllocator)]
910
public class SimpleButton extends InteractiveObject {
1011
public function SimpleButton(upState:DisplayObject = null, overState:DisplayObject = null, downState:DisplayObject = null, hitTestState:DisplayObject = null) {
1112
this.init(upState, overState, downState, hitTestState)

core/src/avm2/globals/flash/display/Sprite.as

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,10 @@ package flash.display {
44
import flash.geom.Rectangle;
55
import flash.media.SoundTransform;
66

7+
[Ruffle(InstanceAllocator)]
78
public class Sprite extends DisplayObjectContainer {
89

910
internal var _graphics:Graphics;
10-
11-
public function Sprite() {
12-
this.init();
13-
}
14-
15-
private native function init();
1611

1712
public native function get graphics():Graphics;
1813
public native function get dropTarget():DisplayObject;

core/src/avm2/globals/flash/display/bitmap.rs

Lines changed: 64 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
33
use crate::avm2::activation::Activation;
44
use crate::avm2::globals::flash::display::bitmap_data::fill_bitmap_data_from_symbol;
5-
use crate::avm2::object::{BitmapDataObject, Object, TObject};
5+
use crate::avm2::globals::flash::display::display_object::initialize_for_allocator;
6+
use crate::avm2::object::{BitmapDataObject, ClassObject, Object, TObject};
67
use crate::avm2::value::Value;
78
use crate::avm2::Error;
89

@@ -12,15 +13,70 @@ use crate::character::Character;
1213
use crate::display_object::{Bitmap, TDisplayObject};
1314
use crate::{avm2_stub_getter, avm2_stub_setter};
1415

16+
pub fn bitmap_allocator<'gc>(
17+
class: ClassObject<'gc>,
18+
activation: &mut Activation<'_, 'gc>,
19+
) -> Result<Object<'gc>, Error<'gc>> {
20+
let bitmap_cls = activation.avm2().classes().bitmap;
21+
let bitmapdata_cls = activation.context.avm2.classes().bitmapdata;
22+
23+
let mut class_object = Some(class);
24+
let orig_class = class;
25+
while let Some(class) = class_object {
26+
if class == bitmap_cls {
27+
let bitmap_data = BitmapDataWrapper::dummy(activation.context.gc_context);
28+
let display_object =
29+
Bitmap::new_with_bitmap_data(&mut activation.context, 0, bitmap_data, false).into();
30+
return initialize_for_allocator(activation, display_object, orig_class);
31+
}
32+
33+
if let Some((movie, symbol)) = activation
34+
.context
35+
.library
36+
.avm2_class_registry()
37+
.class_symbol(class)
38+
{
39+
if let Some(Character::Bitmap(bitmap)) = activation
40+
.context
41+
.library
42+
.library_for_movie_mut(movie)
43+
.character_by_id(symbol)
44+
.cloned()
45+
{
46+
let new_bitmap_data = fill_bitmap_data_from_symbol(activation, &bitmap);
47+
let bitmap_data_obj = BitmapDataObject::from_bitmap_data_internal(
48+
activation,
49+
BitmapDataWrapper::dummy(activation.context.gc_context),
50+
bitmapdata_cls,
51+
)?;
52+
bitmap_data_obj.init_bitmap_data(activation.context.gc_context, new_bitmap_data);
53+
new_bitmap_data.init_object2(activation.context.gc_context, bitmap_data_obj);
54+
55+
let child = Bitmap::new_with_bitmap_data(
56+
&mut activation.context,
57+
0,
58+
new_bitmap_data,
59+
false,
60+
)
61+
.into();
62+
63+
let mut obj = initialize_for_allocator(activation, child, orig_class)?;
64+
obj.set_public_property("bitmapData", bitmap_data_obj.into(), activation)?;
65+
return Ok(obj);
66+
}
67+
}
68+
class_object = class.superclass_object();
69+
}
70+
unreachable!("A Bitmap subclass should have Bitmap in superclass chain");
71+
}
72+
1573
/// Implements `flash.display.Bitmap`'s `init` method, which is called from the constructor
1674
pub fn init<'gc>(
1775
activation: &mut Activation<'_, 'gc>,
1876
this: Option<Object<'gc>>,
1977
args: &[Value<'gc>],
2078
) -> Result<Value<'gc>, Error<'gc>> {
21-
if let Some(mut this) = this {
22-
activation.super_init(this, &[])?;
23-
79+
if let Some(this) = this {
2480
let bitmap_data = args
2581
.try_get_object(activation, 0)
2682
.and_then(|o| o.as_bitmap_data());
@@ -29,69 +85,12 @@ pub fn init<'gc>(
2985
let smoothing = args.get_bool(2);
3086

3187
if let Some(bitmap) = this.as_display_object().and_then(|dobj| dobj.as_bitmap()) {
32-
//We are being initialized by the movie. This means that we
33-
//need to create bitmap data right away, since all AVM2 bitmaps
34-
//hold bitmap data.
35-
36-
let bd_object = if let Some(bd_class) = bitmap.avm2_bitmapdata_class() {
37-
// We call the custom BitmapData class with width and height...
38-
// but, it always seems to be 1 in Flash Player when constructed from timeline?
39-
bd_class.construct(activation, &[1.into(), 1.into()])?
40-
} else if let Some(b_class) = bitmap.avm2_bitmap_class() {
41-
// Instantiating Bitmap from a Flex-style bitmap asset.
42-
// Contrary to the above comment, this code path DOES
43-
// trigger from AVM2, since the DisplayObject instantiation
44-
// logic does its job in this case.
45-
if let Some((movie, symbol_id)) = activation
46-
.context
47-
.library
48-
.avm2_class_registry()
49-
.class_symbol(b_class)
50-
{
51-
if let Some(Character::Bitmap(bitmap)) = activation
52-
.context
53-
.library
54-
.library_for_movie_mut(movie)
55-
.character_by_id(symbol_id)
56-
.cloned()
57-
{
58-
let new_bitmap_data =
59-
fill_bitmap_data_from_symbol(activation.context.gc_context, bitmap);
60-
BitmapDataObject::from_bitmap_data(
61-
activation,
62-
new_bitmap_data,
63-
activation.context.avm2.classes().bitmapdata,
64-
)?
65-
} else {
66-
//Class association not to a Bitmap
67-
return Err("Attempted to instantiate Bitmap from timeline with symbol class associated to non-Bitmap!".into());
68-
}
69-
} else {
70-
//Class association not bidirectional
71-
return Err("Cannot instantiate Bitmap from timeline without bidirectional symbol class association".into());
72-
}
73-
} else {
74-
// No class association
75-
return Err(
76-
"Cannot instantiate Bitmap from timeline without associated symbol class"
77-
.into(),
78-
);
79-
};
80-
81-
this.set_public_property("bitmapData", bd_object.into(), activation)?;
82-
88+
if let Some(bitmap_data) = bitmap_data {
89+
bitmap.set_bitmap_data(&mut activation.context, bitmap_data);
90+
}
8391
bitmap.set_smoothing(activation.context.gc_context, smoothing);
8492
} else {
85-
//We are being initialized by AVM2 (and aren't associated with a
86-
//Bitmap subclass).
87-
88-
let bitmap_data = bitmap_data
89-
.unwrap_or_else(|| BitmapDataWrapper::dummy(activation.context.gc_context));
90-
91-
let bitmap =
92-
Bitmap::new_with_bitmap_data(&mut activation.context, 0, bitmap_data, smoothing);
93-
94-
this.init_display_object(&mut activation.context, bitmap.into());
93+
unreachable!();
9594
}
9695
}
9796

0 commit comments

Comments
 (0)