Implement mudinput (sending to MUD from terminal)
This commit is contained in:
		
							parent
							
								
									ff0411b040
								
							
						
					
					
						commit
						8816d76c53
					
				@ -1,8 +1,7 @@
 | 
			
		||||
use itertools::join;
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    echo_to_term_frame, lua_engine::LuaState, parsing::parse_commands, GlobalMemoCell, TermFrame,
 | 
			
		||||
};
 | 
			
		||||
use itertools::{join, Itertools};
 | 
			
		||||
 | 
			
		||||
pub fn debrace(inp: &str) -> &str {
 | 
			
		||||
    let v = inp.trim();
 | 
			
		||||
@ -52,6 +51,17 @@ fn reentrant_command_handler(
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    // A normal command. Try dispatching it to the frame object in Lua...
 | 
			
		||||
                    match lua_state
 | 
			
		||||
                        .dispatch_normal_command(term_frame, &command.arguments.iter().join(" "))
 | 
			
		||||
                    {
 | 
			
		||||
                        Ok(()) => (),
 | 
			
		||||
                        Err(msg) => {
 | 
			
		||||
                            echo_to_term_frame(globals, term_frame, &format!("{}\r\n", msg))
 | 
			
		||||
                                .unwrap_or(())
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -90,6 +90,30 @@ impl LuaState {
 | 
			
		||||
            .execute::<()>(&self.exec)
 | 
			
		||||
            .map_err(|err| format!("{}", err))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) fn dispatch_normal_command(
 | 
			
		||||
        &mut self,
 | 
			
		||||
        frame: &TermFrame,
 | 
			
		||||
        command: &str,
 | 
			
		||||
    ) -> anyhow::Result<()> {
 | 
			
		||||
        self.interp.try_enter(|ctx| {
 | 
			
		||||
            let frames: Table = ctx.get_global("frames")?;
 | 
			
		||||
            let frame_tab: Value = frames.get(ctx, frame.0 as i64)?;
 | 
			
		||||
            if frame_tab.is_nil() {
 | 
			
		||||
                Err(anyhow::Error::msg(
 | 
			
		||||
                    "Dispatching command to frame missing in Lua frames.",
 | 
			
		||||
                ))?;
 | 
			
		||||
            }
 | 
			
		||||
            ctx.fetch(&self.exec).restart(
 | 
			
		||||
                ctx,
 | 
			
		||||
                Function::Callback(send_command_to_frame(ctx)),
 | 
			
		||||
                (frame_tab, ctx.intern(command.as_bytes())),
 | 
			
		||||
            );
 | 
			
		||||
            Ok(())
 | 
			
		||||
        })?;
 | 
			
		||||
        self.interp.execute(&self.exec)?;
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn install_lua_globals(
 | 
			
		||||
@ -129,6 +153,8 @@ pub fn install_lua_globals(
 | 
			
		||||
            ctx.set_global("info", info_table);
 | 
			
		||||
            let muds_table = Table::new(&ctx);
 | 
			
		||||
            ctx.set_global("muds", muds_table);
 | 
			
		||||
            let frames_table = Table::new(&ctx);
 | 
			
		||||
            ctx.set_global("frames", frames_table);
 | 
			
		||||
 | 
			
		||||
            let handlers_table = Table::new(&ctx);
 | 
			
		||||
            ctx.set_global("handlers", handlers_table);
 | 
			
		||||
@ -180,6 +206,7 @@ pub fn install_lua_globals(
 | 
			
		||||
            register_class_function!(mud_class_table, mudoutput_do);
 | 
			
		||||
            register_class_function!(mud_class_table, mudoutput_dont);
 | 
			
		||||
            register_class_function!(mud_class_table, mudoutput_subnegotiation);
 | 
			
		||||
            register_class_function!(mud_class_table, mudinput_line);
 | 
			
		||||
            register_class_function!(mud_class_table, "new", new_mud);
 | 
			
		||||
 | 
			
		||||
            macro_rules! register_class_nop {
 | 
			
		||||
@ -200,6 +227,12 @@ pub fn install_lua_globals(
 | 
			
		||||
            register_class_nop!(mud_class_table, mudoutput_abort_output);
 | 
			
		||||
            register_class_nop!(mud_class_table, mudoutput_areyouthere);
 | 
			
		||||
 | 
			
		||||
            let frame_class_table = Table::new(&ctx);
 | 
			
		||||
            classes_table.set(ctx, "frame", frame_class_table)?;
 | 
			
		||||
            frame_class_table.set(ctx, MetaMethod::Index, frame_class_table)?;
 | 
			
		||||
            register_class_function!(frame_class_table, "new", new_frame);
 | 
			
		||||
            register_class_function!(frame_class_table, "input", frame_input);
 | 
			
		||||
 | 
			
		||||
            let frameroute_class_table = Table::new(&ctx);
 | 
			
		||||
            classes_table.set(ctx, "frameroute", frameroute_class_table)?;
 | 
			
		||||
            frameroute_class_table.set(ctx, MetaMethod::Index, frameroute_class_table)?;
 | 
			
		||||
@ -210,9 +243,26 @@ pub fn install_lua_globals(
 | 
			
		||||
        })
 | 
			
		||||
        .map_err(|e| e.to_string())?;
 | 
			
		||||
 | 
			
		||||
    lua_global_initialisation(global_memo)?;
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn lua_global_initialisation(global_memo: &GlobalMemoCell) -> Result<(), String> {
 | 
			
		||||
    let mut lua_engine = global_memo.lua_engine.borrow_mut();
 | 
			
		||||
    let lua_engine_ref: &mut LuaState = &mut lua_engine;
 | 
			
		||||
    lua_engine_ref.interp.enter(|ctx| {
 | 
			
		||||
        ctx.fetch(&lua_engine_ref.exec).restart(
 | 
			
		||||
            ctx,
 | 
			
		||||
            Function::Callback(ensure_frame_instance(ctx, &TermFrame(1))),
 | 
			
		||||
            (),
 | 
			
		||||
        );
 | 
			
		||||
    });
 | 
			
		||||
    lua_engine_ref
 | 
			
		||||
        .interp
 | 
			
		||||
        .execute(&lua_engine_ref.exec)
 | 
			
		||||
        .map_err(|e| e.to_string())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn lua_nop(ctx: Context<'_>) -> Callback<'_> {
 | 
			
		||||
    Callback::from_fn(&ctx, |_ctx, _ex, _stack| {
 | 
			
		||||
        Ok(piccolo::CallbackReturn::Return)
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,17 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    command_handler::debrace, echo_to_term_frame, GlobalLayoutCell, GlobalLayoutState,
 | 
			
		||||
    GlobalMemoCell, TermFrame,
 | 
			
		||||
    command_handler::debrace, echo_to_term_frame, id_intern::intern_id, GlobalLayoutCell,
 | 
			
		||||
    GlobalLayoutState, GlobalMemoCell, TermFrame,
 | 
			
		||||
};
 | 
			
		||||
use gc_arena::{Gc, Rootable};
 | 
			
		||||
use piccolo::{
 | 
			
		||||
    self, Callback, Context, FromValue, Function, IntoValue, Table, UserData, Value, Variadic,
 | 
			
		||||
    self, async_sequence, meta_ops, Callback, CallbackReturn, Context, FromValue, Function,
 | 
			
		||||
    IntoValue, SequenceReturn, Table, UserData, Value, Variadic,
 | 
			
		||||
};
 | 
			
		||||
use std::{rc::Rc, str};
 | 
			
		||||
use yew::UseStateSetter;
 | 
			
		||||
 | 
			
		||||
use super::prep_metaop_call;
 | 
			
		||||
 | 
			
		||||
pub fn echo_frame_raw<'gc, 'a>(
 | 
			
		||||
    ctx: Context<'gc>,
 | 
			
		||||
    global_memo: &'a GlobalMemoCell,
 | 
			
		||||
@ -84,19 +87,22 @@ pub fn vsplit<'gc>(
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let path: String = stack.from_front(ctx)?;
 | 
			
		||||
        let path: &str = debrace(&path);
 | 
			
		||||
        let frame: u64 = stack.from_front(ctx)?;
 | 
			
		||||
        let frame: TermFrame = TermFrame(stack.from_front(ctx)?);
 | 
			
		||||
        let new_splits = global_memo
 | 
			
		||||
            .layout
 | 
			
		||||
            .borrow()
 | 
			
		||||
            .term_splits
 | 
			
		||||
            .vsplit(path, TermFrame(frame))
 | 
			
		||||
            .vsplit(path, frame.clone())
 | 
			
		||||
            .map_err(|e| e.into_value(ctx))?;
 | 
			
		||||
        let new_layout = Rc::new(GlobalLayoutState {
 | 
			
		||||
            term_splits: new_splits.clone(),
 | 
			
		||||
        });
 | 
			
		||||
        global_layout.set(new_layout.clone());
 | 
			
		||||
        *(global_memo.layout.borrow_mut()) = new_layout;
 | 
			
		||||
        Ok(piccolo::CallbackReturn::Return)
 | 
			
		||||
        Ok(CallbackReturn::Call {
 | 
			
		||||
            function: Function::Callback(ensure_frame_instance(ctx, &frame)),
 | 
			
		||||
            then: None,
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -110,19 +116,22 @@ pub fn hsplit<'gc>(
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let path: String = stack.from_front(ctx)?;
 | 
			
		||||
        let path: &str = debrace(&path);
 | 
			
		||||
        let frame: u64 = stack.from_front(ctx)?;
 | 
			
		||||
        let frame: TermFrame = TermFrame(stack.from_front(ctx)?);
 | 
			
		||||
        let new_splits = global_memo
 | 
			
		||||
            .layout
 | 
			
		||||
            .borrow()
 | 
			
		||||
            .term_splits
 | 
			
		||||
            .hsplit(path, TermFrame(frame))
 | 
			
		||||
            .hsplit(path, frame.clone())
 | 
			
		||||
            .map_err(|e| e.into_value(ctx))?;
 | 
			
		||||
        let new_layout = Rc::new(GlobalLayoutState {
 | 
			
		||||
            term_splits: new_splits.clone(),
 | 
			
		||||
        });
 | 
			
		||||
        global_layout.set(new_layout.clone());
 | 
			
		||||
        *(global_memo.layout.borrow_mut()) = new_layout;
 | 
			
		||||
        Ok(piccolo::CallbackReturn::Return)
 | 
			
		||||
        Ok(CallbackReturn::Call {
 | 
			
		||||
            function: Function::Callback(ensure_frame_instance(ctx, &frame)),
 | 
			
		||||
            then: None,
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -163,3 +172,178 @@ pub fn try_unwrap_frame<'gc>(
 | 
			
		||||
            .clone()),
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn ensure_frame_instance<'gc>(ctx: Context<'gc>, frame: &TermFrame) -> Callback<'gc> {
 | 
			
		||||
    let frame = frame.clone();
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, _stack| {
 | 
			
		||||
        let frames: Table = ctx.get_global("frames")?;
 | 
			
		||||
        let frame_value: Value = frames.get(ctx, frame.0 as i64)?;
 | 
			
		||||
        if !frame_value.is_nil() {
 | 
			
		||||
            return Ok(CallbackReturn::Return);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let frame_tab = Table::new(&ctx);
 | 
			
		||||
        let classes: Table = ctx.get_global("classes")?;
 | 
			
		||||
        frame_tab.set_metatable(&ctx, Some(classes.get(ctx, "frame")?));
 | 
			
		||||
        frames.set(ctx, frame.0 as i64, frame_tab)?;
 | 
			
		||||
 | 
			
		||||
        // Call frame_tab:new(frame) to setup.
 | 
			
		||||
        let frame = frame.clone();
 | 
			
		||||
        let seq = async_sequence(&ctx, move |locals, mut seq| {
 | 
			
		||||
            let frame_tab = locals.stash(&ctx, frame_tab);
 | 
			
		||||
            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?;
 | 
			
		||||
 | 
			
		||||
                Ok(SequenceReturn::Return)
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        Ok(CallbackReturn::Sequence(seq))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(super) fn new_frame<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let frame_tab: Table = Table::from_value(
 | 
			
		||||
            ctx,
 | 
			
		||||
            stack
 | 
			
		||||
                .pop_front()
 | 
			
		||||
                .ok_or_else(|| anyhow::Error::msg("classes.frame:new missing object!"))?,
 | 
			
		||||
        )?;
 | 
			
		||||
        let frame: Value = stack
 | 
			
		||||
            .pop_front()
 | 
			
		||||
            .ok_or_else(|| anyhow::Error::msg("classes.frame:new missing frame!"))?;
 | 
			
		||||
 | 
			
		||||
        frame_tab.set(ctx, ctx.intern_static(b"frame"), frame)?;
 | 
			
		||||
 | 
			
		||||
        Ok(piccolo::CallbackReturn::Return)
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Note: send_command_to_frame is called from the command parser, and can't be overriden (or even
 | 
			
		||||
// called) by the user.
 | 
			
		||||
// It will normally result in a call into frame_input, but that can be overriden by scripts.
 | 
			
		||||
pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        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);
 | 
			
		||||
            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?;
 | 
			
		||||
 | 
			
		||||
                Ok(SequenceReturn::Return)
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        Ok(CallbackReturn::Sequence(seq))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let frame_tab: Table = Table::from_value(
 | 
			
		||||
            ctx,
 | 
			
		||||
            stack
 | 
			
		||||
                .pop_front()
 | 
			
		||||
                .ok_or_else(|| anyhow::Error::msg("classes.frame:new missing object!"))?,
 | 
			
		||||
        )?;
 | 
			
		||||
        let line: Value = stack
 | 
			
		||||
            .pop_front()
 | 
			
		||||
            .ok_or_else(|| anyhow::Error::msg("classes.frame:new missing line!"))?;
 | 
			
		||||
 | 
			
		||||
        let linked_mud = frame_tab.get_value(ctx, ctx.intern_static(b"linked_mud"));
 | 
			
		||||
        if linked_mud.is_nil() {
 | 
			
		||||
            return Ok(piccolo::CallbackReturn::Return);
 | 
			
		||||
        }
 | 
			
		||||
        let linked_mud: Table = Table::from_value(ctx, linked_mud)?;
 | 
			
		||||
 | 
			
		||||
        // linked_mud:mudinput_line(line)
 | 
			
		||||
        let seq = async_sequence(&ctx, |locals, mut seq| {
 | 
			
		||||
            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?;
 | 
			
		||||
 | 
			
		||||
                Ok(SequenceReturn::Return)
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Ok(piccolo::CallbackReturn::Sequence(seq))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@ use anyhow::Error;
 | 
			
		||||
use gc_arena::{Gc, Rootable};
 | 
			
		||||
use piccolo::{
 | 
			
		||||
    self, async_sequence, meta_ops, Callback, CallbackReturn, Context, FromValue, Function,
 | 
			
		||||
    IntoValue, MetaMethod, SequenceReturn, StashedValue, Table, UserData, Value,
 | 
			
		||||
    IntoValue, SequenceReturn, StashedValue, Table, UserData, Value,
 | 
			
		||||
};
 | 
			
		||||
use wasm_bindgen::JsValue;
 | 
			
		||||
use web_sys::console;
 | 
			
		||||
@ -16,7 +16,7 @@ use crate::{
 | 
			
		||||
    GlobalLayoutCell, GlobalMemoCell,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use super::{prep_metaop_call, LuaState};
 | 
			
		||||
use super::{prep_metaop_call, try_unwrap_frame, LuaState};
 | 
			
		||||
 | 
			
		||||
fn try_unwrap_socketid<'gc>(
 | 
			
		||||
    ctx: Context<'gc>,
 | 
			
		||||
@ -171,10 +171,25 @@ pub(super) fn connect_mud<'gc>(
 | 
			
		||||
        muds.set(ctx, new_socket, conntab)?;
 | 
			
		||||
        conntab.set(ctx, ctx.intern_static(b"socket"), new_socket)?;
 | 
			
		||||
        conntab.set(ctx, ctx.intern_static(b"buffer"), ctx.intern_static(b""))?;
 | 
			
		||||
        let conntab_meta = Table::new(&ctx);
 | 
			
		||||
        conntab_meta.set(ctx, MetaMethod::Index, mud_class)?;
 | 
			
		||||
        conntab.set_metatable(&ctx, Some(conntab_meta));
 | 
			
		||||
 | 
			
		||||
        conntab.set_metatable(&ctx, Some(mud_class));
 | 
			
		||||
        let curframe: Value = ctx
 | 
			
		||||
            .get_global::<Table>("info")?
 | 
			
		||||
            .get(ctx, ctx.intern_static(b"current_frame"))?;
 | 
			
		||||
        if let Ok(curframe) = try_unwrap_frame(ctx, &curframe) {
 | 
			
		||||
            if let Ok(frame) = ctx
 | 
			
		||||
                .get_global::<Table>("frames")?
 | 
			
		||||
                .get::<i64, Value>(ctx, curframe.0 as i64)
 | 
			
		||||
            {
 | 
			
		||||
                if !frame.is_nil() {
 | 
			
		||||
                    Table::from_value(ctx, frame)?.set(
 | 
			
		||||
                        ctx,
 | 
			
		||||
                        ctx.intern_static(b"linked_mud"),
 | 
			
		||||
                        conntab,
 | 
			
		||||
                    )?;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Call conntab:new...
 | 
			
		||||
        let seq = async_sequence(&ctx, |locals, mut seq| {
 | 
			
		||||
            let conntab = locals.stash(&ctx, conntab);
 | 
			
		||||
            async move {
 | 
			
		||||
@ -483,6 +498,27 @@ pub(super) fn mudoutput_subnegotiation<'gc>(
 | 
			
		||||
    Callback::from_fn(&ctx, move |_ctx, _ex, _stack| Ok(CallbackReturn::Return))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(super) fn mudinput_line<'gc>(
 | 
			
		||||
    ctx: Context<'gc>,
 | 
			
		||||
    _global_memo: &GlobalMemoCell,
 | 
			
		||||
) -> Callback<'gc> {
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let (mud, line): (Table, piccolo::String) = stack.consume(ctx)?;
 | 
			
		||||
        stack.push_back(mud.get::<piccolo::String, Value>(ctx, ctx.intern_static(b"socket"))?);
 | 
			
		||||
        let line = [line.as_bytes(), b"\r\n"].concat();
 | 
			
		||||
        stack.push_back(ctx.intern(&line).into_value(ctx));
 | 
			
		||||
 | 
			
		||||
        let func = ctx
 | 
			
		||||
            .get_global::<Table>("commands")?
 | 
			
		||||
            .get::<piccolo::String, Function>(ctx, ctx.intern_static(b"sendmud_raw"))?;
 | 
			
		||||
 | 
			
		||||
        Ok(CallbackReturn::Call {
 | 
			
		||||
            function: func,
 | 
			
		||||
            then: None,
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub(super) fn new_mud<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
 | 
			
		||||
    Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
 | 
			
		||||
        let mud: Table = Table::from_value(
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ fn app() -> Html {
 | 
			
		||||
    });
 | 
			
		||||
    use_memo((), |_| {
 | 
			
		||||
        install_lua_globals(&global_memo, global_layout.setter())
 | 
			
		||||
            .expect("Couldn't install Lua globals")
 | 
			
		||||
            .expect("Couldn't install Lua globals");
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    html! {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user