Simplify async_sequence function calls.
This commit is contained in:
parent
855ecfc13a
commit
0214897a91
@ -1,8 +1,10 @@
|
||||
use self::{frameroutes::*, frames::*, muds::*};
|
||||
use anyhow::Error;
|
||||
use piccolo::{
|
||||
async_callback::Locals, meta_ops::MetaResult, Callback, Closure, Context, Executor,
|
||||
ExternError, FromValue, Function, Lua, MetaMethod, Stack, StashedExecutor, StashedFunction,
|
||||
async_callback::{AsyncSequence, Locals},
|
||||
meta_ops::{self, MetaResult},
|
||||
Callback, Closure, Context, Executor, ExternError, FromValue, Function, IntoValue, Lua,
|
||||
MetaMethod, Stack, StashedError, StashedExecutor, StashedFunction, StashedTable, StashedValue,
|
||||
Table, Value, Variadic,
|
||||
};
|
||||
use yew::UseStateSetter;
|
||||
@ -140,15 +142,16 @@ pub fn install_lua_globals(
|
||||
};
|
||||
}
|
||||
|
||||
register_command!(alias);
|
||||
register_command!(close_mud);
|
||||
register_command!(connect_mud);
|
||||
register_command!(delete_mud);
|
||||
register_command!(echo);
|
||||
register_command!(echo_frame);
|
||||
register_command!(echo_frame_raw);
|
||||
register_command!(connect_mud);
|
||||
register_command!(delete_mud);
|
||||
register_command!(close_mud);
|
||||
register_command!(sendmud_raw);
|
||||
register_command!(hsplit);
|
||||
register_command!(panel_merge);
|
||||
register_command!(sendmud_raw);
|
||||
register_command!(vsplit);
|
||||
ctx.set_global("commands", cmd_table);
|
||||
let info_table = Table::new(&ctx);
|
||||
@ -289,3 +292,41 @@ pub fn prep_metaop_call<'gc, const N: usize>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn call_checking_metatable<'gc, 'a>(
|
||||
seq: &mut AsyncSequence,
|
||||
obj: StashedTable,
|
||||
func_name: &'static str,
|
||||
arguments: &[StashedValue],
|
||||
) -> Result<(), StashedError> {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let obj = locals.fetch(&obj);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
obj.into_value(ctx),
|
||||
ctx.intern_static(func_name.as_bytes()).into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let call = seq.try_enter(|ctx, locals, _, mut stack| {
|
||||
let value = stack
|
||||
.pop_back()
|
||||
.ok_or_else(|| anyhow::Error::msg("Index didn't return value"))?;
|
||||
stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&obj).into_value(ctx));
|
||||
for arg in arguments {
|
||||
stack.push_back(locals.fetch(arg));
|
||||
}
|
||||
Ok(locals.stash(&ctx, Function::from_value(ctx, value)?))
|
||||
})?;
|
||||
seq.call(&call, 0).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -4,13 +4,23 @@ use crate::{
|
||||
};
|
||||
use gc_arena::{Gc, Rootable};
|
||||
use piccolo::{
|
||||
self, async_sequence, meta_ops, Callback, CallbackReturn, Context, FromValue, Function,
|
||||
IntoValue, SequenceReturn, Table, UserData, Value, Variadic,
|
||||
self, async_sequence, Callback, CallbackReturn, Context, FromValue, Function, IntoValue,
|
||||
SequenceReturn, Table, UserData, Value, Variadic,
|
||||
};
|
||||
use std::{rc::Rc, str};
|
||||
use yew::UseStateSetter;
|
||||
|
||||
use super::prep_metaop_call;
|
||||
use super::call_checking_metatable;
|
||||
|
||||
pub fn alias<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
_global_memo: &'a GlobalMemoCell,
|
||||
_global_layout: &'a UseStateSetter<GlobalLayoutCell>,
|
||||
) -> Callback<'gc> {
|
||||
Callback::from_fn(&ctx, move |_ctx, _ex, _stack| {
|
||||
Ok(piccolo::CallbackReturn::Return)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn echo_frame_raw<'gc, 'a>(
|
||||
ctx: Context<'gc>,
|
||||
@ -185,38 +195,12 @@ pub fn ensure_frame_instance<'gc>(ctx: Context<'gc>, frame: &TermFrame) -> Callb
|
||||
frames.set(ctx, frame.0 as i64, frame_tab)?;
|
||||
|
||||
// Call frame_tab:new(frame) to setup.
|
||||
let frame = frame.clone();
|
||||
let frame = intern_id::<TermFrame>(ctx, frame.clone());
|
||||
let seq = async_sequence(&ctx, move |locals, mut seq| {
|
||||
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||
let frame = locals.stash(&ctx, frame);
|
||||
async move {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let frame_tab = locals.fetch(&frame_tab);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
frame_tab.into_value(ctx),
|
||||
ctx.intern_static(b"new").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let call = seq.try_enter(|ctx, locals, _, mut stack| {
|
||||
let value = stack
|
||||
.pop_back()
|
||||
.ok_or_else(|| anyhow::Error::msg("Index didn't return value"))?;
|
||||
stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&frame_tab).into_value(ctx));
|
||||
stack.push_back(intern_id::<TermFrame>(ctx, frame.clone()));
|
||||
Ok(locals.stash(&ctx, Function::from_value(ctx, value)?))
|
||||
})?;
|
||||
seq.call(&call, 0).await?;
|
||||
|
||||
call_checking_metatable(&mut seq, frame_tab, "new", &[frame]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -250,35 +234,9 @@ pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||
let (frame, line): (Table, piccolo::String) = stack.consume(ctx)?;
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let frame = locals.stash(&ctx, frame);
|
||||
let line = locals.stash(&ctx, line);
|
||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||
async move {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, stack| {
|
||||
let frame = locals.fetch(&frame);
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
frame.into_value(ctx),
|
||||
ctx.intern_static(b"input").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let call = seq.try_enter(|ctx, locals, _, mut stack| {
|
||||
let value = stack
|
||||
.pop_back()
|
||||
.ok_or_else(|| anyhow::Error::msg("Index didn't return value"))?;
|
||||
stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&frame).into_value(ctx));
|
||||
stack.push_back(locals.fetch(&line).into_value(ctx));
|
||||
Ok(locals.stash(&ctx, Function::from_value(ctx, value)?))
|
||||
})?;
|
||||
seq.call(&call, 0).await?;
|
||||
|
||||
call_checking_metatable(&mut seq, frame, "input", &[line]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -297,6 +255,7 @@ pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell)
|
||||
let line: Value = stack
|
||||
.pop_front()
|
||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:new missing line!"))?;
|
||||
stack.consume(ctx)?;
|
||||
|
||||
let linked_mud = frame_tab.get_value(ctx, ctx.intern_static(b"linked_mud"));
|
||||
if linked_mud.is_nil() {
|
||||
@ -309,34 +268,7 @@ pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell)
|
||||
let linked_mud = locals.stash(&ctx, linked_mud);
|
||||
let line = locals.stash(&ctx, line);
|
||||
async move {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let linked_mud = locals.fetch(&linked_mud);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
linked_mud.into_value(ctx),
|
||||
ctx.intern_static(b"mudinput_line").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let call = seq.try_enter(|ctx, locals, _, mut stack| {
|
||||
let value = stack
|
||||
.pop_back()
|
||||
.ok_or_else(|| anyhow::Error::msg("Index didn't return value"))?;
|
||||
stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&linked_mud).into_value(ctx));
|
||||
stack.push_back(locals.fetch(&line));
|
||||
Ok(locals.stash(&ctx, Function::from_value(ctx, value)?))
|
||||
})?;
|
||||
seq.call(&call, 0).await?;
|
||||
|
||||
call_checking_metatable(&mut seq, linked_mud, "mudinput_line", &[line]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
@ -1,8 +1,8 @@
|
||||
use anyhow::Error;
|
||||
use gc_arena::{Gc, Rootable};
|
||||
use piccolo::{
|
||||
self, async_sequence, meta_ops, Callback, CallbackReturn, Context, FromValue, Function,
|
||||
IntoValue, SequenceReturn, StashedValue, Table, UserData, Value,
|
||||
self, async_sequence, Callback, CallbackReturn, Context, FromValue, Function, IntoValue,
|
||||
SequenceReturn, StashedTable, StashedValue, Table, UserData, Value,
|
||||
};
|
||||
use wasm_bindgen::JsValue;
|
||||
use web_sys::console;
|
||||
@ -15,7 +15,7 @@ use crate::{
|
||||
GlobalLayoutCell, GlobalMemoCell,
|
||||
};
|
||||
|
||||
use super::{prep_metaop_call, try_unwrap_frame, LuaState};
|
||||
use super::{call_checking_metatable, try_unwrap_frame, LuaState};
|
||||
|
||||
fn try_unwrap_socketid<'gc>(
|
||||
ctx: Context<'gc>,
|
||||
@ -192,29 +192,7 @@ pub(super) fn connect_mud<'gc>(
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let conntab = locals.stash(&ctx, conntab);
|
||||
async move {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let conntab = locals.fetch(&conntab);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
conntab.into_value(ctx),
|
||||
ctx.intern_static(b"new").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let new_fn = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let new_fn: Function = stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&conntab).into_value(ctx));
|
||||
Ok(locals.stash(&ctx, new_fn))
|
||||
})?;
|
||||
seq.call(&new_fn, 0).await?;
|
||||
call_checking_metatable(&mut seq, conntab, "new", &[]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
@ -310,7 +288,7 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
.as_bytes();
|
||||
let mut cur_buf: Vec<u8> = [buf, output].concat();
|
||||
|
||||
let mut fns: Vec<(&'static [u8], Vec<Value>)> = vec![];
|
||||
let mut fns: Vec<(&'static str, Vec<Value>)> = vec![];
|
||||
loop {
|
||||
match parse_telnet_buf(&cur_buf) {
|
||||
(new_buf, None) => {
|
||||
@ -318,7 +296,7 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
|
||||
let seq = piccolo::async_sequence(&ctx, |locals, mut seq| {
|
||||
let conntab = locals.stash(&ctx, conntab);
|
||||
let fns: Vec<(&'static [u8], Vec<StashedValue>)> = fns
|
||||
let fns: Vec<(&'static str, Vec<StashedValue>)> = fns
|
||||
.into_iter()
|
||||
.map(|fnv| {
|
||||
(
|
||||
@ -329,37 +307,13 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
.collect();
|
||||
async move {
|
||||
for (func_name, params) in fns {
|
||||
let call =
|
||||
seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let conntab = locals.fetch(&conntab);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
conntab.into_value(ctx),
|
||||
ctx.intern_static(func_name).into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let call = seq.try_enter(|ctx, locals, _, mut stack| {
|
||||
let value = stack.pop_back().ok_or_else(|| {
|
||||
anyhow::Error::msg("Index didn't return value")
|
||||
})?;
|
||||
stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&conntab).into_value(ctx));
|
||||
for param in ¶ms {
|
||||
stack.push_back(locals.fetch(param));
|
||||
}
|
||||
|
||||
Ok(locals.stash(&ctx, Function::from_value(ctx, value)?))
|
||||
})?;
|
||||
seq.call(&call, 0).await?;
|
||||
call_checking_metatable(
|
||||
&mut seq,
|
||||
conntab.clone(),
|
||||
func_name,
|
||||
¶ms,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
Ok(piccolo::SequenceReturn::Return)
|
||||
}
|
||||
@ -371,30 +325,30 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
||||
cur_buf = new_buf;
|
||||
match cmd {
|
||||
TelnetOutput::Line(l) => {
|
||||
fns.push((b"mudoutput_line", vec![ctx.intern(&l).into_value(ctx)]))
|
||||
fns.push(("mudoutput_line", vec![ctx.intern(&l).into_value(ctx)]))
|
||||
}
|
||||
TelnetOutput::Prompt(p) => {
|
||||
fns.push((b"mudoutput_prompt", vec![ctx.intern(&p).into_value(ctx)]))
|
||||
fns.push(("mudoutput_prompt", vec![ctx.intern(&p).into_value(ctx)]))
|
||||
}
|
||||
TelnetOutput::Nop => {}
|
||||
TelnetOutput::Break => fns.push((b"mudoutput_break", vec![])),
|
||||
TelnetOutput::Sync => fns.push((b"mudoutput_sync", vec![])),
|
||||
TelnetOutput::Interrupt => fns.push((b"mudoutput_interrupt", vec![])),
|
||||
TelnetOutput::Break => fns.push(("mudoutput_break", vec![])),
|
||||
TelnetOutput::Sync => fns.push(("mudoutput_sync", vec![])),
|
||||
TelnetOutput::Interrupt => fns.push(("mudoutput_interrupt", vec![])),
|
||||
|
||||
TelnetOutput::AbortOutput => fns.push((b"mudoutput_abort_output", vec![])),
|
||||
TelnetOutput::AreYouThere => fns.push((b"mudoutput_areyouthere", vec![])),
|
||||
TelnetOutput::AbortOutput => fns.push(("mudoutput_abort_output", vec![])),
|
||||
TelnetOutput::AreYouThere => fns.push(("mudoutput_areyouthere", vec![])),
|
||||
TelnetOutput::Will(v) => {
|
||||
fns.push((b"mudoutput_will", vec![v.into_value(ctx)]))
|
||||
fns.push(("mudoutput_will", vec![v.into_value(ctx)]))
|
||||
}
|
||||
TelnetOutput::Wont(v) => {
|
||||
fns.push((b"mudoutput_wont", vec![v.into_value(ctx)]))
|
||||
fns.push(("mudoutput_wont", vec![v.into_value(ctx)]))
|
||||
}
|
||||
TelnetOutput::Do(v) => fns.push((b"mudoutput_do", vec![v.into_value(ctx)])),
|
||||
TelnetOutput::Do(v) => fns.push(("mudoutput_do", vec![v.into_value(ctx)])),
|
||||
TelnetOutput::Dont(v) => {
|
||||
fns.push((b"mudoutput_dont", vec![v.into_value(ctx)]))
|
||||
fns.push(("mudoutput_dont", vec![v.into_value(ctx)]))
|
||||
}
|
||||
TelnetOutput::Subnegotiation(t) => {
|
||||
fns.push((b"mudoutput_subnegotiation", vec![t.into_value(ctx)]))
|
||||
fns.push(("mudoutput_subnegotiation", vec![t.into_value(ctx)]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -424,37 +378,18 @@ pub(super) fn mudoutput_line<'gc>(
|
||||
let frameroutes: Table = mud.get(ctx, "frameroutes")?;
|
||||
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let frameroutes: Vec<StashedValue> = frameroutes
|
||||
let frameroutes: Vec<StashedTable> = frameroutes
|
||||
.iter()
|
||||
.map(|fr| locals.stash(&ctx, fr.1))
|
||||
.filter_map(|fr| {
|
||||
Table::from_value(ctx, fr.1)
|
||||
.ok()
|
||||
.map(|v| locals.stash(&ctx, v))
|
||||
})
|
||||
.collect();
|
||||
let line = locals.stash(&ctx, line);
|
||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||
async move {
|
||||
for frameroute in frameroutes {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let frameroute = locals.fetch(&frameroute);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
frameroute.into_value(ctx),
|
||||
ctx.intern_static(b"route").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let route_fn = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let route_fn: Function = stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&frameroute).into_value(ctx));
|
||||
stack.push_back(locals.fetch(&line).into_value(ctx));
|
||||
Ok(locals.stash(&ctx, route_fn))
|
||||
})?;
|
||||
seq.call(&route_fn, 0).await?;
|
||||
call_checking_metatable(&mut seq, frameroute, "route", &[line.clone()]).await?;
|
||||
}
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
@ -538,38 +473,16 @@ pub(super) fn new_mud<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) ->
|
||||
);
|
||||
mud.set(ctx, ctx.intern_static(b"frameroutes"), frameroutes)?;
|
||||
|
||||
let curr_frame: Value = ctx
|
||||
.get_global::<Table>("info")?
|
||||
.get(ctx, ctx.intern_static(b"current_frame"))?;
|
||||
// And call new on the frameroute, for the current frame.
|
||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||
let frameroute = locals.stash(&ctx, frameroute);
|
||||
async move {
|
||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let frameroute = locals.fetch(&frameroute);
|
||||
stack.consume(ctx)?;
|
||||
Ok(prep_metaop_call(
|
||||
ctx,
|
||||
stack,
|
||||
locals,
|
||||
meta_ops::index(
|
||||
ctx,
|
||||
frameroute.into_value(ctx),
|
||||
ctx.intern_static(b"new").into_value(ctx),
|
||||
)?,
|
||||
))
|
||||
})?;
|
||||
if let Some(call) = call {
|
||||
seq.call(&call, 0).await?;
|
||||
}
|
||||
let new_fn = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||
let new_fn: Function = stack.consume(ctx)?;
|
||||
stack.push_back(locals.fetch(&frameroute).into_value(ctx));
|
||||
stack.push_back(
|
||||
ctx.get_global::<Table>("info")?
|
||||
.get(ctx, ctx.intern_static(b"current_frame"))?,
|
||||
);
|
||||
Ok(locals.stash(&ctx, new_fn))
|
||||
})?;
|
||||
seq.call(&new_fn, 0).await?;
|
||||
let curr_frame = locals.stash(&ctx, curr_frame);
|
||||
|
||||
async move {
|
||||
call_checking_metatable(&mut seq, frameroute, "new", &[curr_frame]).await?;
|
||||
Ok(SequenceReturn::Return)
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user