avm1: Implement some event handlers
This commit is contained in:
parent
78a68f95ea
commit
dccf254281
|
@ -118,7 +118,7 @@ pub fn connect<'gc>(
|
||||||
..
|
..
|
||||||
} = &mut activation.context;
|
} = &mut activation.context;
|
||||||
|
|
||||||
sockets.connect_avm1(*navigator, xml_socket, host.to_utf8_lossy().into_owned(), port);
|
sockets.connect_avm1(*navigator, this, host.to_utf8_lossy().into_owned(), port);
|
||||||
|
|
||||||
// NOTE: At this point we do not know if the connection will succeed
|
// NOTE: At this point we do not know if the connection will succeed
|
||||||
// because connecting is an asynchronous process, so we just return true.
|
// because connecting is an asynchronous process, so we just return true.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
avm1::globals::xml_socket::XmlSocket,
|
avm1::{globals::xml_socket::XmlSocket, Activation, ActivationIdentifier, ExecutionReason, TObject, Object},
|
||||||
avm2::{object::SocketObject, Activation, Avm2, EventObject, TObject},
|
avm2::{object::SocketObject, Activation as Avm2Activation, Avm2, EventObject, TObject as Avm2TObject},
|
||||||
backend::navigator::NavigatorBackend,
|
backend::navigator::NavigatorBackend,
|
||||||
context::UpdateContext,
|
context::UpdateContext,
|
||||||
};
|
};
|
||||||
|
@ -15,11 +15,11 @@ use std::{
|
||||||
|
|
||||||
pub type SocketHandle = Index;
|
pub type SocketHandle = Index;
|
||||||
|
|
||||||
#[derive(Collect)]
|
#[derive(Copy, Clone, Collect)]
|
||||||
#[collect(no_drop)]
|
#[collect(no_drop)]
|
||||||
enum SocketKind<'gc> {
|
enum SocketKind<'gc> {
|
||||||
Avm2(SocketObject<'gc>),
|
Avm2(SocketObject<'gc>),
|
||||||
Avm1(XmlSocket<'gc>),
|
Avm1(Object<'gc>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Collect)]
|
#[derive(Collect)]
|
||||||
|
@ -111,12 +111,17 @@ impl<'gc> Sockets<'gc> {
|
||||||
pub fn connect_avm1(
|
pub fn connect_avm1(
|
||||||
&mut self,
|
&mut self,
|
||||||
backend: &mut dyn NavigatorBackend,
|
backend: &mut dyn NavigatorBackend,
|
||||||
target: XmlSocket<'gc>,
|
target: Object<'gc>,
|
||||||
host: String,
|
host: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
) {
|
) {
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
|
|
||||||
|
let xml_socket = match XmlSocket::cast(target.into()) {
|
||||||
|
Some(xml_socket) => xml_socket,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
let socket = Socket::new(SocketKind::Avm1(target), sender);
|
let socket = Socket::new(SocketKind::Avm1(target), sender);
|
||||||
let handle = self.sockets.insert(socket);
|
let handle = self.sockets.insert(socket);
|
||||||
|
|
||||||
|
@ -124,13 +129,13 @@ impl<'gc> Sockets<'gc> {
|
||||||
backend.connect_socket(
|
backend.connect_socket(
|
||||||
host,
|
host,
|
||||||
port,
|
port,
|
||||||
Duration::from_millis(target.timeout().into()),
|
Duration::from_millis(xml_socket.timeout().into()),
|
||||||
handle,
|
handle,
|
||||||
receiver,
|
receiver,
|
||||||
self.sender.clone(),
|
self.sender.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(existing_handle) = target.set_handle(handle) {
|
if let Some(existing_handle) = xml_socket.set_handle(handle) {
|
||||||
// NOTE: AS2 docs don't specify what happens when connect is called with open connection,
|
// NOTE: AS2 docs don't specify what happens when connect is called with open connection,
|
||||||
// but we will close the existing connection anyway.
|
// but we will close the existing connection anyway.
|
||||||
self.close(existing_handle)
|
self.close(existing_handle)
|
||||||
|
@ -154,18 +159,16 @@ impl<'gc> Sockets<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_sockets(context: &mut UpdateContext<'_, 'gc>) {
|
pub fn update_sockets(context: &mut UpdateContext<'_, 'gc>) {
|
||||||
let mut activation = Activation::from_nothing(context.reborrow());
|
|
||||||
|
|
||||||
let mut actions = vec![];
|
let mut actions = vec![];
|
||||||
|
|
||||||
while let Ok(action) = activation.context.sockets.receiver.try_recv() {
|
while let Ok(action) = context.sockets.receiver.try_recv() {
|
||||||
actions.push(action)
|
actions.push(action)
|
||||||
}
|
}
|
||||||
|
|
||||||
for action in actions {
|
for action in actions {
|
||||||
match action {
|
match action {
|
||||||
SocketAction::Connect(handle, ConnectionState::Connected) => {
|
SocketAction::Connect(handle, ConnectionState::Connected) => {
|
||||||
let target = match activation.context.sockets.sockets.get(handle) {
|
let target = match context.sockets.sockets.get(handle) {
|
||||||
Some(socket) => socket.target,
|
Some(socket) => socket.target,
|
||||||
// Socket must have been closed before we could send event.
|
// Socket must have been closed before we could send event.
|
||||||
None => continue,
|
None => continue,
|
||||||
|
@ -173,6 +176,8 @@ impl<'gc> Sockets<'gc> {
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
SocketKind::Avm2(target) => {
|
SocketKind::Avm2(target) => {
|
||||||
|
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||||
|
|
||||||
let connect_evt =
|
let connect_evt =
|
||||||
EventObject::bare_default_event(&mut activation.context, "connect");
|
EventObject::bare_default_event(&mut activation.context, "connect");
|
||||||
Avm2::dispatch_event(
|
Avm2::dispatch_event(
|
||||||
|
@ -181,15 +186,23 @@ impl<'gc> Sockets<'gc> {
|
||||||
target.into(),
|
target.into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: Implement this.
|
SocketKind::Avm1(target) => {
|
||||||
SocketKind::Avm1(_) => {}
|
let mut activation = Activation::from_stub(context.reborrow(), ActivationIdentifier::root("[XMLSocket]"));
|
||||||
|
|
||||||
|
let _ = target.call_method(
|
||||||
|
"onConnect".into(),
|
||||||
|
&[true.into()],
|
||||||
|
&mut activation,
|
||||||
|
ExecutionReason::Special,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketAction::Connect(
|
SocketAction::Connect(
|
||||||
handle,
|
handle,
|
||||||
ConnectionState::Failed | ConnectionState::TimedOut,
|
ConnectionState::Failed | ConnectionState::TimedOut,
|
||||||
) => {
|
) => {
|
||||||
let target = match activation.context.sockets.sockets.get(handle) {
|
let target = match context.sockets.sockets.get(handle) {
|
||||||
Some(socket) => socket.target,
|
Some(socket) => socket.target,
|
||||||
// Socket must have been closed before we could send event.
|
// Socket must have been closed before we could send event.
|
||||||
None => continue,
|
None => continue,
|
||||||
|
@ -197,6 +210,8 @@ impl<'gc> Sockets<'gc> {
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
SocketKind::Avm2(target) => {
|
SocketKind::Avm2(target) => {
|
||||||
|
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||||
|
|
||||||
let io_error_evt = activation
|
let io_error_evt = activation
|
||||||
.avm2()
|
.avm2()
|
||||||
.classes()
|
.classes()
|
||||||
|
@ -220,11 +235,20 @@ impl<'gc> Sockets<'gc> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: Not sure if avm1 xmlsocket has a way to notify a error. (Probably should just fire connect event with success as false).
|
// 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(_) => {}
|
SocketKind::Avm1(target) => {
|
||||||
|
let mut activation = Activation::from_stub(context.reborrow(), ActivationIdentifier::root("[XMLSocket]"));
|
||||||
|
|
||||||
|
let _ = target.call_method(
|
||||||
|
"onConnect".into(),
|
||||||
|
&[false.into()],
|
||||||
|
&mut activation,
|
||||||
|
ExecutionReason::Special,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketAction::Data(handle, data) => {
|
SocketAction::Data(handle, data) => {
|
||||||
let target = match activation.context.sockets.sockets.get(handle) {
|
let target = match context.sockets.sockets.get(handle) {
|
||||||
Some(socket) => socket.target,
|
Some(socket) => socket.target,
|
||||||
// Socket must have been closed before we could send event.
|
// Socket must have been closed before we could send event.
|
||||||
None => continue,
|
None => continue,
|
||||||
|
@ -232,6 +256,8 @@ impl<'gc> Sockets<'gc> {
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
SocketKind::Avm2(target) => {
|
SocketKind::Avm2(target) => {
|
||||||
|
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||||
|
|
||||||
let bytes_loaded = data.len();
|
let bytes_loaded = data.len();
|
||||||
target.read_buffer().extend(data);
|
target.read_buffer().extend(data);
|
||||||
|
|
||||||
|
@ -259,11 +285,13 @@ impl<'gc> Sockets<'gc> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO: Implement this.
|
// TODO: Implement this.
|
||||||
SocketKind::Avm1(_) => {}
|
SocketKind::Avm1(_) => {
|
||||||
|
let mut activation = Activation::from_stub(context.reborrow(), ActivationIdentifier::root("[XMLSocket]"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketAction::Close(handle) => {
|
SocketAction::Close(handle) => {
|
||||||
let target = match activation.context.sockets.sockets.get(handle) {
|
let target = match context.sockets.sockets.get(handle) {
|
||||||
Some(socket) => socket.target,
|
Some(socket) => socket.target,
|
||||||
// Socket must have been closed before we could send event.
|
// Socket must have been closed before we could send event.
|
||||||
None => continue,
|
None => continue,
|
||||||
|
@ -271,12 +299,22 @@ impl<'gc> Sockets<'gc> {
|
||||||
|
|
||||||
match target {
|
match target {
|
||||||
SocketKind::Avm2(target) => {
|
SocketKind::Avm2(target) => {
|
||||||
|
let mut activation = Avm2Activation::from_nothing(context.reborrow());
|
||||||
|
|
||||||
let close_evt =
|
let close_evt =
|
||||||
EventObject::bare_default_event(&mut activation.context, "close");
|
EventObject::bare_default_event(&mut activation.context, "close");
|
||||||
Avm2::dispatch_event(&mut activation.context, close_evt, target.into());
|
Avm2::dispatch_event(&mut activation.context, close_evt, target.into());
|
||||||
}
|
}
|
||||||
// TODO: Implement this.
|
SocketKind::Avm1(target) => {
|
||||||
SocketKind::Avm1(_) => {}
|
let mut activation = Activation::from_stub(context.reborrow(), ActivationIdentifier::root("[XMLSocket]"));
|
||||||
|
|
||||||
|
let _ = target.call_method(
|
||||||
|
"onClose".into(),
|
||||||
|
&[],
|
||||||
|
&mut activation,
|
||||||
|
ExecutionReason::Special,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue