core: Add SocketKind and use it to separate XMLSocket and Socket

This commit is contained in:
sleepycatcoding 2023-08-01 23:46:06 +03:00 committed by Nathan Adams
parent 662c7f986d
commit cd92677b2a
2 changed files with 90 additions and 46 deletions

View File

@ -43,7 +43,7 @@ pub fn connect<'gc>(
sockets, navigator, .. sockets, navigator, ..
} = &mut activation.context; } = &mut activation.context;
sockets.connect(*navigator, socket, host.to_utf8_lossy().into_owned(), port); sockets.connect_avm2(*navigator, socket, host.to_utf8_lossy().into_owned(), port);
Ok(Value::Undefined) Ok(Value::Undefined)
} }

View File

@ -1,4 +1,5 @@
use crate::{ use crate::{
avm1::globals::xml_socket::XmlSocket,
avm2::{object::SocketObject, Activation, Avm2, EventObject, TObject}, avm2::{object::SocketObject, Activation, Avm2, EventObject, TObject},
backend::navigator::NavigatorBackend, backend::navigator::NavigatorBackend,
context::UpdateContext, context::UpdateContext,
@ -14,15 +15,22 @@ use std::{
pub type SocketHandle = Index; pub type SocketHandle = Index;
#[derive(Collect)]
#[collect(no_drop)]
enum SocketKind<'gc> {
Avm2(SocketObject<'gc>),
Avm1(XmlSocket<'gc>),
}
#[derive(Collect)] #[derive(Collect)]
#[collect(no_drop)] #[collect(no_drop)]
struct Socket<'gc> { struct Socket<'gc> {
target: SocketObject<'gc>, target: SocketKind<'gc>,
sender: RefCell<AsyncSender<Vec<u8>>>, sender: RefCell<AsyncSender<Vec<u8>>>,
} }
impl<'gc> Socket<'gc> { impl<'gc> Socket<'gc> {
fn new(target: SocketObject<'gc>, sender: AsyncSender<Vec<u8>>) -> Self { fn new(target: SocketKind<'gc>, sender: AsyncSender<Vec<u8>>) -> Self {
Self { Self {
target, target,
sender: RefCell::new(sender), sender: RefCell::new(sender),
@ -71,7 +79,7 @@ impl<'gc> Sockets<'gc> {
} }
} }
pub fn connect( pub fn connect_avm2(
&mut self, &mut self,
backend: &mut dyn NavigatorBackend, backend: &mut dyn NavigatorBackend,
target: SocketObject<'gc>, target: SocketObject<'gc>,
@ -80,7 +88,7 @@ impl<'gc> Sockets<'gc> {
) { ) {
let (sender, receiver) = unbounded(); let (sender, receiver) = unbounded();
let socket = Socket::new(target, sender); let socket = Socket::new(SocketKind::Avm2(target), sender);
let handle = self.sockets.insert(socket); let handle = self.sockets.insert(socket);
// NOTE: This call will send SocketAction::Connect to sender with connection status. // NOTE: This call will send SocketAction::Connect to sender with connection status.
@ -134,9 +142,19 @@ impl<'gc> Sockets<'gc> {
None => continue, None => continue,
}; };
let connect_evt = match target {
EventObject::bare_default_event(&mut activation.context, "connect"); SocketKind::Avm2(target) => {
Avm2::dispatch_event(&mut activation.context, connect_evt, target.into()); let connect_evt =
EventObject::bare_default_event(&mut activation.context, "connect");
Avm2::dispatch_event(
&mut activation.context,
connect_evt,
target.into(),
);
}
// TODO: Implement this.
SocketKind::Avm1(_) => {}
}
} }
SocketAction::Connect( SocketAction::Connect(
handle, handle,
@ -148,23 +166,33 @@ impl<'gc> Sockets<'gc> {
None => continue, None => continue,
}; };
let io_error_evt = activation match target {
.avm2() SocketKind::Avm2(target) => {
.classes() let io_error_evt = activation
.ioerrorevent .avm2()
.construct( .classes()
&mut activation, .ioerrorevent
&[ .construct(
"ioError".into(), &mut activation,
false.into(), &[
false.into(), "ioError".into(),
"Error #2031: Socket Error.".into(), false.into(),
2031.into(), false.into(),
], "Error #2031: Socket Error.".into(),
) 2031.into(),
.expect("IOErrorEvent should be constructed"); ],
)
.expect("IOErrorEvent should be constructed");
Avm2::dispatch_event(&mut activation.context, io_error_evt, target.into()); Avm2::dispatch_event(
&mut activation.context,
io_error_evt,
target.into(),
);
}
// TODO: Not sure if avm1 xmlsocket has a way to notify a error. (Probably should just fire connect event with success as false).
SocketKind::Avm1(_) => {}
}
} }
SocketAction::Data(handle, data) => { SocketAction::Data(handle, data) => {
let target = match activation.context.sockets.sockets.get(handle) { let target = match activation.context.sockets.sockets.get(handle) {
@ -173,27 +201,37 @@ impl<'gc> Sockets<'gc> {
None => continue, None => continue,
}; };
let bytes_loaded = data.len(); match target {
target.read_buffer().extend(data); SocketKind::Avm2(target) => {
let bytes_loaded = data.len();
target.read_buffer().extend(data);
let progress_evt = activation let progress_evt = activation
.avm2() .avm2()
.classes() .classes()
.progressevent .progressevent
.construct( .construct(
&mut activation, &mut activation,
&[ &[
"socketData".into(), "socketData".into(),
false.into(), false.into(),
false.into(), false.into(),
bytes_loaded.into(), bytes_loaded.into(),
//NOTE: bytesTotal is not used by socketData event. //NOTE: bytesTotal is not used by socketData event.
0.into(), 0.into(),
], ],
) )
.expect("ProgressEvent should be constructed"); .expect("ProgressEvent should be constructed");
Avm2::dispatch_event(&mut activation.context, progress_evt, target.into()); Avm2::dispatch_event(
&mut activation.context,
progress_evt,
target.into(),
);
}
// TODO: Implement this.
SocketKind::Avm1(_) => {}
}
} }
SocketAction::Close(handle) => { SocketAction::Close(handle) => {
let target = match activation.context.sockets.sockets.get(handle) { let target = match activation.context.sockets.sockets.get(handle) {
@ -202,9 +240,15 @@ impl<'gc> Sockets<'gc> {
None => continue, None => continue,
}; };
let close_evt = match target {
EventObject::bare_default_event(&mut activation.context, "close"); SocketKind::Avm2(target) => {
Avm2::dispatch_event(&mut activation.context, close_evt, target.into()); let close_evt =
EventObject::bare_default_event(&mut activation.context, "close");
Avm2::dispatch_event(&mut activation.context, close_evt, target.into());
}
// TODO: Implement this.
SocketKind::Avm1(_) => {}
}
} }
} }
} }