Skip to content

Commit f40e3d9

Browse files
committed
core/render/web: replace uses of the Downcast trait with Any
Now that Rust supports trait upcasting, the direct dependency on `downcast-rs` isn't needed anymore.
1 parent 4f5032c commit f40e3d9

File tree

24 files changed

+82
-127
lines changed

24 files changed

+82
-127
lines changed

Cargo.lock

Lines changed: 1 addition & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ smallvec = { version = "1.15.0", features = ["union"] }
3030
num-traits = { workspace = true }
3131
num-derive = { workspace = true }
3232
quick-xml = "0.37.4"
33-
downcast-rs = "2.0.1"
3433
url = { workspace = true }
3534
weak-table = "0.3.2"
3635
percent-encoding = "2.3.1"

core/src/avm2/filters.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use ruffle_macros::istr;
1919
use ruffle_render::filters::{
2020
DisplacementMapFilter, DisplacementMapFilterMode, Filter, ShaderFilter, ShaderObject,
2121
};
22+
use std::any::Any;
2223
use std::fmt::Debug;
2324
use swf::{
2425
BevelFilter, BevelFilterFlags, BlurFilter, BlurFilterFlags, Color, ColorMatrixFilter,
@@ -50,7 +51,7 @@ impl ShaderObject for ObjectWrapper {
5051
}
5152

5253
fn equals(&self, other: &dyn ShaderObject) -> bool {
53-
if let Some(other_wrapper) = other.downcast_ref::<ObjectWrapper>() {
54+
if let Some(other_wrapper) = <dyn Any>::downcast_ref::<ObjectWrapper>(other) {
5455
std::ptr::eq(self.root.as_ptr(), other_wrapper.root.as_ptr())
5556
} else {
5657
false
@@ -857,9 +858,7 @@ fn shader_filter_to_avm2<'gc>(
857858
activation: &mut Activation<'_, 'gc>,
858859
filter: &ShaderFilter<'static>,
859860
) -> Result<Value<'gc>, Error<'gc>> {
860-
let object_wrapper: &ObjectWrapper = filter
861-
.shader_object
862-
.downcast_ref::<ObjectWrapper>()
861+
let object_wrapper: &ObjectWrapper = <dyn Any>::downcast_ref(filter.shader_object.as_ref())
863862
.expect("ShaderObject was not an ObjectWrapper");
864863

865864
let obj = *activation.context.dynamic_root.fetch(&object_wrapper.root);

core/src/backend/audio.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::any::Any;
2+
13
use crate::{
24
avm1::{NativeObject, Object as Avm1Object},
35
avm2::{Avm2, EventObject as Avm2EventObject, SoundChannelObject},
@@ -6,7 +8,6 @@ use crate::{
68
display_object::{self, DisplayObject, MovieClip, TDisplayObject},
79
string::AvmString,
810
};
9-
use downcast_rs::Downcast;
1011
use gc_arena::Collect;
1112
use slotmap::{new_key_type, Key, SlotMap};
1213

@@ -84,7 +85,7 @@ pub enum RegisterError {
8485
ShortMp3,
8586
}
8687

87-
pub trait AudioBackend: Downcast {
88+
pub trait AudioBackend: Any {
8889
fn play(&mut self);
8990
fn pause(&mut self);
9091

@@ -194,8 +195,6 @@ pub trait AudioBackend: Downcast {
194195
}
195196
}
196197

197-
impl_downcast!(AudioBackend);
198-
199198
/// Information about a sound provided to `NullAudioBackend`.
200199
struct NullSound {
201200
/// The duration of the sound in milliseconds.

core/src/backend/navigator.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use crate::loader::Error;
44
use crate::socket::{ConnectionState, SocketAction, SocketHandle};
55
use crate::string::WStr;
66
use async_channel::{Receiver, Sender};
7-
use downcast_rs::Downcast;
87
use encoding_rs::Encoding;
98
use indexmap::IndexMap;
9+
use std::any::Any;
1010
use std::borrow::Cow;
1111
use std::fmt;
1212
use std::fmt::Display;
@@ -227,7 +227,7 @@ pub struct ErrorResponse {
227227
pub type OwnedFuture<T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + 'static>>;
228228

229229
/// A backend interacting with a browser environment.
230-
pub trait NavigatorBackend: Downcast {
230+
pub trait NavigatorBackend: Any {
231231
/// Cause a browser navigation to a given URL.
232232
///
233233
/// The URL given may be any URL scheme a browser can support. This may not
@@ -302,7 +302,6 @@ pub trait NavigatorBackend: Downcast {
302302
sender: Sender<SocketAction>,
303303
);
304304
}
305-
impl_downcast!(NavigatorBackend);
306305

307306
#[cfg(not(target_family = "wasm"))]
308307
pub struct NullExecutor(futures::executor::LocalPool);

core/src/backend/ui.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use crate::backend::navigator::OwnedFuture;
22
pub use crate::loader::Error as DialogLoaderError;
33
use chrono::{DateTime, Utc};
4-
use downcast_rs::Downcast;
54
use fluent_templates::loader::langid;
65
pub use fluent_templates::LanguageIdentifier;
7-
use std::borrow::Cow;
6+
use std::{any::Any, borrow::Cow};
87
use url::Url;
98

109
pub type FullscreenError = Cow<'static, str>;
@@ -38,7 +37,7 @@ pub struct FileFilter {
3837
}
3938

4039
/// A result of a file selection
41-
pub trait FileDialogResult: Downcast {
40+
pub trait FileDialogResult: Any {
4241
/// Was the file selection canceled by the user
4342
fn is_cancelled(&self) -> bool;
4443
fn creation_time(&self) -> Option<DateTime<Utc>>;
@@ -55,12 +54,11 @@ pub trait FileDialogResult: Downcast {
5554
/// the state at the time of the last refresh
5655
fn write_and_refresh(&mut self, data: &[u8]);
5756
}
58-
impl_downcast!(FileDialogResult);
5957

6058
/// Future representing a file selection in process
6159
pub type DialogResultFuture = OwnedFuture<Box<dyn FileDialogResult>, DialogLoaderError>;
6260

63-
pub trait UiBackend: Downcast {
61+
pub trait UiBackend: Any {
6462
fn mouse_visible(&self) -> bool;
6563

6664
fn set_mouse_visible(&mut self, visible: bool);
@@ -129,7 +127,6 @@ pub trait UiBackend: Downcast {
129127
/// Mark that any previously open dialog has been closed
130128
fn close_file_dialog(&mut self);
131129
}
132-
impl_downcast!(UiBackend);
133130

134131
/// A mouse cursor icon displayed by the Flash Player.
135132
/// Communicated from the core to the UI backend via `UiBackend::set_mouse_cursor`.

core/src/lib.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ pub use display_object::{StageAlign, StageDisplayState, StageScaleMode};
1212
#[macro_use]
1313
extern crate smallvec;
1414

15-
#[macro_use]
16-
extern crate downcast_rs;
17-
1815
#[macro_use]
1916
extern crate num_derive;
2017

desktop/src/gui/controller.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use ruffle_core::{Player, PlayerEvent};
1313
use ruffle_render_wgpu::backend::{request_adapter_and_device, WgpuRenderBackend};
1414
use ruffle_render_wgpu::descriptors::Descriptors;
1515
use ruffle_render_wgpu::utils::{format_list, get_backend_names};
16+
use std::any::Any;
1617
use std::sync::{Arc, MutexGuard};
1718
use std::time::{Duration, Instant};
1819
use url::Url;
@@ -329,11 +330,10 @@ impl GuiController {
329330
// If we're not in a UI, tell egui which cursor we prefer to use instead
330331
if !self.egui_winit.egui_ctx().wants_pointer_input() {
331332
if let Some(player) = player.as_deref() {
332-
full_output.platform_output.cursor_icon = player
333-
.ui()
334-
.downcast_ref::<DesktopUiBackend>()
335-
.unwrap_or_else(|| panic!("UI Backend should be DesktopUiBackend"))
336-
.cursor();
333+
full_output.platform_output.cursor_icon =
334+
<dyn Any>::downcast_ref::<DesktopUiBackend>(player.ui())
335+
.unwrap_or_else(|| panic!("UI Backend should be DesktopUiBackend"))
336+
.cursor();
337337
}
338338
}
339339
self.egui_winit
@@ -375,10 +375,9 @@ impl GuiController {
375375
);
376376

377377
let movie_view = if let Some(player) = player.as_deref_mut() {
378-
let renderer = player
379-
.renderer_mut()
380-
.downcast_mut::<WgpuRenderBackend<MovieView>>()
381-
.expect("Renderer must be correct type");
378+
let renderer =
379+
<dyn Any>::downcast_ref::<WgpuRenderBackend<MovieView>>(player.renderer_mut())
380+
.expect("Renderer must be correct type");
382381
Some(renderer.target())
383382
} else {
384383
None

exporter/src/main.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use ruffle_render_wgpu::clap::{GraphicsBackend, PowerPreference};
1111
use ruffle_render_wgpu::descriptors::Descriptors;
1212
use ruffle_render_wgpu::target::TextureTarget;
1313
use ruffle_render_wgpu::wgpu;
14+
use std::any::Any;
1415
use std::fs::create_dir_all;
1516
use std::io::{self, Write};
1617
use std::panic::catch_unwind;
@@ -135,10 +136,10 @@ fn take_screenshot(
135136
let image = || {
136137
player.lock().unwrap().render();
137138
let mut player = player.lock().unwrap();
138-
let renderer = player
139-
.renderer_mut()
140-
.downcast_mut::<WgpuRenderBackend<TextureTarget>>()
141-
.unwrap();
139+
let renderer = <dyn Any>::downcast_mut::<WgpuRenderBackend<TextureTarget>>(
140+
player.renderer_mut(),
141+
)
142+
.unwrap();
142143
renderer.capture_frame()
143144
};
144145
match catch_unwind(image) {

render/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ gif = "0.13.1"
1818
png = "0.17.16"
1919
flate2 = { workspace = true }
2020
smallvec = { version = "1.15.0", features = ["union"] }
21-
downcast-rs = "2.0.1"
2221
lyon = { version = "1.0.1", optional = true }
2322
lyon_geom = "1.0.6"
2423
thiserror = { workspace = true }

render/canvas/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use ruffle_render::quality::StageQuality;
1717
use ruffle_render::shape_utils::{DistilledShape, DrawCommand, LineScaleMode, LineScales};
1818
use ruffle_render::transform::Transform;
1919
use ruffle_web_common::{JsError, JsResult};
20+
use std::any::Any;
2021
use std::borrow::Cow;
2122
use std::sync::Arc;
2223
use swf::{BlendMode, Color, ColorTransform, Point, Twips};
@@ -52,8 +53,7 @@ struct ShapeData(Vec<CanvasDrawCommand>);
5253
impl ShapeHandleImpl for ShapeData {}
5354

5455
fn as_shape_data(handle: &ShapeHandle) -> &ShapeData {
55-
<dyn ShapeHandleImpl>::downcast_ref(&*handle.0)
56-
.expect("Shape handle must be a Canvas ShapeData")
56+
<dyn Any>::downcast_ref(&*handle.0).expect("Shape handle must be a Canvas ShapeData")
5757
}
5858

5959
#[derive(Debug)]
@@ -155,8 +155,7 @@ struct BitmapData {
155155
impl BitmapHandleImpl for BitmapData {}
156156

157157
fn as_bitmap_data(handle: &BitmapHandle) -> &BitmapData {
158-
<dyn BitmapHandleImpl>::downcast_ref(&*handle.0)
159-
.expect("Bitmap handle must be a Canvas BitmapData")
158+
<dyn Any>::downcast_ref(&*handle.0).expect("Bitmap handle must be a Canvas BitmapData")
160159
}
161160

162161
impl BitmapData {

render/src/backend.rs

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use crate::filters::Filter;
77
use crate::pixel_bender::{PixelBenderShader, PixelBenderShaderArgument, PixelBenderShaderHandle};
88
use crate::quality::StageQuality;
99
use crate::shape_utils::DistilledShape;
10-
use downcast_rs::{impl_downcast, Downcast};
1110
use ruffle_wstr::WStr;
11+
use std::any::Any;
1212
use std::borrow::Cow;
1313
use std::cell::RefCell;
1414
use std::fmt::Debug;
@@ -23,7 +23,7 @@ pub struct BitmapCacheEntry {
2323
pub filters: Vec<Filter>,
2424
}
2525

26-
pub trait RenderBackend: Downcast {
26+
pub trait RenderBackend: Any {
2727
fn viewport_dimensions(&self) -> ViewportDimensions;
2828
// Do not call this method directly - use `player.set_viewport_dimensions`,
2929
// which will ensure that the stage is properly updated as well.
@@ -112,7 +112,6 @@ pub trait RenderBackend: Downcast {
112112
with_rgba: RgbaBufRead,
113113
) -> Result<(), Error>;
114114
}
115-
impl_downcast!(RenderBackend);
116115

117116
pub enum PixelBenderTarget {
118117
// The shader will write to the provided bitmap texture,
@@ -129,29 +128,24 @@ pub enum PixelBenderOutput {
129128
Bytes(Vec<u8>),
130129
}
131130

132-
pub trait IndexBuffer: Downcast {}
133-
impl_downcast!(IndexBuffer);
134-
pub trait VertexBuffer: Downcast {}
135-
impl_downcast!(VertexBuffer);
131+
pub trait IndexBuffer: Any {}
132+
pub trait VertexBuffer: Any {}
136133

137-
pub trait ShaderModule: Downcast {}
138-
impl_downcast!(ShaderModule);
134+
pub trait ShaderModule: Any {}
139135

140-
pub trait Texture: Downcast + Debug {
136+
pub trait Texture: Any + Debug {
141137
fn width(&self) -> u32;
142138
fn height(&self) -> u32;
143139
}
144-
impl_downcast!(Texture);
145140

146-
pub trait RawTexture: Downcast + Debug {
141+
pub trait RawTexture: Any + Debug {
147142
fn equals(&self, other: &dyn RawTexture) -> bool;
148143
}
149-
impl_downcast!(RawTexture);
150144

151145
#[cfg(feature = "wgpu")]
152146
impl RawTexture for wgpu::Texture {
153147
fn equals(&self, other: &dyn RawTexture) -> bool {
154-
if let Some(other_texture) = other.downcast_ref::<wgpu::Texture>() {
148+
if let Some(other_texture) = (other as &dyn Any).downcast_ref::<wgpu::Texture>() {
155149
std::ptr::eq(self, other_texture)
156150
} else {
157151
false
@@ -241,7 +235,7 @@ pub enum ProgramType {
241235
Fragment,
242236
}
243237

244-
pub trait Context3D: Downcast {
238+
pub trait Context3D: Any {
245239
fn profile(&self) -> Context3DProfile;
246240
// The BitmapHandle for the texture we're rendering to
247241
fn bitmap_handle(&self) -> BitmapHandle;
@@ -284,7 +278,6 @@ pub trait Context3D: Downcast {
284278

285279
fn process_command(&mut self, command: Context3DCommand<'_>);
286280
}
287-
impl_downcast!(Context3D);
288281

289282
#[derive(Copy, Clone, Debug)]
290283
pub enum Context3DVertexBufferFormat {
@@ -529,8 +522,7 @@ pub enum Context3DCommand<'a> {
529522
#[derive(Clone, Debug)]
530523
pub struct ShapeHandle(pub Arc<dyn ShapeHandleImpl>);
531524

532-
pub trait ShapeHandleImpl: Downcast + Debug {}
533-
impl_downcast!(ShapeHandleImpl);
525+
pub trait ShapeHandleImpl: Any + Debug {}
534526

535527
#[derive(Copy, Clone, Debug)]
536528
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]

0 commit comments

Comments
 (0)