Make #alias work.
This commit is contained in:
parent
ff840c04c2
commit
a215133ea6
@ -3,9 +3,10 @@ use anyhow::Error;
|
|||||||
use piccolo::{
|
use piccolo::{
|
||||||
async_callback::{AsyncSequence, Locals},
|
async_callback::{AsyncSequence, Locals},
|
||||||
meta_ops::{self, MetaResult},
|
meta_ops::{self, MetaResult},
|
||||||
|
stash::Fetchable,
|
||||||
Callback, Closure, Context, Executor, ExternError, FromValue, Function, IntoValue, Lua,
|
Callback, Closure, Context, Executor, ExternError, FromValue, Function, IntoValue, Lua,
|
||||||
MetaMethod, Stack, StashedError, StashedExecutor, StashedFunction, StashedTable, StashedValue,
|
MetaMethod, Stack, StashedError, StashedExecutor, StashedFunction, StashedValue, Table, Value,
|
||||||
Table, Value, Variadic,
|
Variadic,
|
||||||
};
|
};
|
||||||
use yew::UseStateSetter;
|
use yew::UseStateSetter;
|
||||||
|
|
||||||
@ -147,11 +148,21 @@ pub fn install_lua_globals(
|
|||||||
.map_err(|_| Error::msg("Can't add command"))?;
|
.map_err(|_| Error::msg("Can't add command"))?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
macro_rules! register_stateless_command {
|
||||||
register_command!(alias);
|
($sym: ident) => {
|
||||||
|
cmd_table
|
||||||
|
.set(
|
||||||
|
ctx,
|
||||||
|
ctx.intern_static(stringify!($sym).as_bytes()),
|
||||||
|
$sym(ctx),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::msg("Can't add command"))?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
register_stateless_command!(alias);
|
||||||
register_command!(close_mud);
|
register_command!(close_mud);
|
||||||
register_command!(connect_mud);
|
register_command!(connect_mud);
|
||||||
register_command!(create_match_table);
|
register_stateless_command!(create_match_table);
|
||||||
register_command!(delete_mud);
|
register_command!(delete_mud);
|
||||||
register_command!(echo);
|
register_command!(echo);
|
||||||
register_command!(echo_frame);
|
register_command!(echo_frame);
|
||||||
@ -210,6 +221,22 @@ pub fn install_lua_globals(
|
|||||||
.map_err(|_| Error::msg("Can't add handler"))?;
|
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
macro_rules! register_stateless_class_function {
|
||||||
|
($class_table: ident, $sym: ident) => {
|
||||||
|
$class_table
|
||||||
|
.set(
|
||||||
|
ctx,
|
||||||
|
ctx.intern_static(stringify!($sym).as_bytes()),
|
||||||
|
$sym(ctx),
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||||
|
};
|
||||||
|
($class_table: ident, $name: literal, $sym: ident) => {
|
||||||
|
$class_table
|
||||||
|
.set(ctx, ctx.intern_static($name.as_bytes()), $sym(ctx))
|
||||||
|
.map_err(|_| Error::msg("Can't add handler"))?;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
register_class_function!(mud_class_table, mudoutput_line);
|
register_class_function!(mud_class_table, mudoutput_line);
|
||||||
register_class_function!(mud_class_table, mudoutput_prompt);
|
register_class_function!(mud_class_table, mudoutput_prompt);
|
||||||
@ -254,9 +281,17 @@ pub fn install_lua_globals(
|
|||||||
let match_table_class_table = Table::new(&ctx);
|
let match_table_class_table = Table::new(&ctx);
|
||||||
classes_table.set(ctx, "match_table", match_table_class_table)?;
|
classes_table.set(ctx, "match_table", match_table_class_table)?;
|
||||||
match_table_class_table.set(ctx, MetaMethod::Index, match_table_class_table)?;
|
match_table_class_table.set(ctx, MetaMethod::Index, match_table_class_table)?;
|
||||||
register_class_function!(match_table_class_table, "add", match_table_add);
|
register_stateless_class_function!(match_table_class_table, "add", match_table_add);
|
||||||
register_class_function!(match_table_class_table, "remove", match_table_remove);
|
register_stateless_class_function!(
|
||||||
register_class_function!(match_table_class_table, "lua_table", match_table_lua_table);
|
match_table_class_table,
|
||||||
|
"remove",
|
||||||
|
match_table_remove
|
||||||
|
);
|
||||||
|
register_stateless_class_function!(
|
||||||
|
match_table_class_table,
|
||||||
|
"lua_table",
|
||||||
|
match_table_lua_table
|
||||||
|
);
|
||||||
register_class_function!(
|
register_class_function!(
|
||||||
match_table_class_table,
|
match_table_class_table,
|
||||||
"try_run_sub",
|
"try_run_sub",
|
||||||
@ -312,12 +347,15 @@ pub fn prep_metaop_call<'gc, const N: usize>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn call_checking_metatable<'gc, 'a>(
|
pub async fn call_checking_metatable<'gc, T: Fetchable>(
|
||||||
seq: &mut AsyncSequence,
|
seq: &mut AsyncSequence,
|
||||||
obj: StashedTable,
|
obj: T,
|
||||||
func_name: &'static str,
|
func_name: &'static str,
|
||||||
arguments: &[StashedValue],
|
arguments: &[StashedValue],
|
||||||
) -> Result<(), StashedError> {
|
) -> Result<(), StashedError>
|
||||||
|
where
|
||||||
|
for<'gcb> <T as Fetchable>::Fetched<'gcb>: IntoValue<'gcb>,
|
||||||
|
{
|
||||||
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
let call = seq.try_enter(|ctx, locals, _execution, mut stack| {
|
||||||
let obj = locals.fetch(&obj);
|
let obj = locals.fetch(&obj);
|
||||||
stack.consume(ctx)?;
|
stack.consume(ctx)?;
|
||||||
|
@ -1,23 +1,20 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
echo_to_term_frame, id_intern::intern_id, GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell,
|
echo_to_term_frame,
|
||||||
TermFrame,
|
id_intern::intern_id,
|
||||||
|
match_table::{create_match_table, match_table_add},
|
||||||
|
GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell, TermFrame,
|
||||||
};
|
};
|
||||||
use gc_arena::{Gc, Rootable};
|
use gc_arena::{Gc, Rootable};
|
||||||
use piccolo::{
|
use piccolo::{
|
||||||
self, async_sequence, Callback, CallbackReturn, Context, FromValue, Function, IntoValue,
|
self, async_sequence, Callback, CallbackReturn, Context, FromValue, Function, IntoValue,
|
||||||
SequenceReturn, Table, UserData, Value, Variadic,
|
SequenceReturn, StashedTable, StashedUserData, StashedValue, Table, UserData, Value, Variadic,
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
|
||||||
use std::{rc::Rc, str};
|
use std::{rc::Rc, str};
|
||||||
use yew::UseStateSetter;
|
use yew::UseStateSetter;
|
||||||
|
|
||||||
use super::call_checking_metatable;
|
use super::call_checking_metatable;
|
||||||
|
|
||||||
pub fn alias<'gc, 'a>(
|
pub fn alias<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||||
ctx: Context<'gc>,
|
|
||||||
_global_memo: &'a GlobalMemoCell,
|
|
||||||
_global_layout: &'a UseStateSetter<GlobalLayoutCell>,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
let info: Table = ctx.get_global("info")?;
|
let info: Table = ctx.get_global("info")?;
|
||||||
let cur_frame: TermFrame =
|
let cur_frame: TermFrame =
|
||||||
@ -43,11 +40,20 @@ pub fn alias<'gc, 'a>(
|
|||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let aliases: Table = cur_frame.get(ctx, "aliases")?;
|
let aliases: UserData = cur_frame.get(ctx, "aliases")?;
|
||||||
|
|
||||||
aliases.set(ctx, alias_match, sub_to)?;
|
stack.push_back(aliases.into_value(ctx));
|
||||||
|
stack.push_back(alias_match.into_value(ctx));
|
||||||
|
stack.push_back(sub_to.into_value(ctx));
|
||||||
|
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||||
|
let add_func = locals.stash(&ctx, Function::Callback(match_table_add(ctx)));
|
||||||
|
async move {
|
||||||
|
seq.call(&add_func, 0).await?;
|
||||||
|
Ok(SequenceReturn::Return)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +235,8 @@ pub fn ensure_frame_instance<'gc>(ctx: Context<'gc>, frame: &TermFrame) -> Callb
|
|||||||
let frame_tab = locals.stash(&ctx, frame_tab);
|
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||||
let frame = locals.stash(&ctx, frame);
|
let frame = locals.stash(&ctx, frame);
|
||||||
async move {
|
async move {
|
||||||
call_checking_metatable(&mut seq, frame_tab, "new", &[frame]).await?;
|
call_checking_metatable::<StashedTable>(&mut seq, frame_tab, "new", &[frame])
|
||||||
|
.await?;
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -251,10 +258,21 @@ pub(super) fn new_frame<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
|||||||
|
|
||||||
frame_tab.set(ctx, ctx.intern_static(b"frame"), frame)?;
|
frame_tab.set(ctx, ctx.intern_static(b"frame"), frame)?;
|
||||||
|
|
||||||
let aliases_tab: Table = Table::new(&ctx);
|
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||||
frame_tab.set(ctx, ctx.intern_static(b"aliases"), aliases_tab)?;
|
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||||
|
let create_match_tab = locals.stash(&ctx, Function::Callback(create_match_table(ctx)));
|
||||||
|
async move {
|
||||||
|
seq.call(&create_match_tab, 0).await?;
|
||||||
|
seq.try_enter(|ctx, locals, _exec, mut stack| {
|
||||||
|
let frame_tab = locals.fetch(&frame_tab);
|
||||||
|
frame_tab.set(ctx, "aliases", stack.consume::<Value>(ctx)?)?;
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
Ok(piccolo::SequenceReturn::Return)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +286,7 @@ pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
|
|||||||
let frame = locals.stash(&ctx, frame);
|
let frame = locals.stash(&ctx, frame);
|
||||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||||
async move {
|
async move {
|
||||||
call_checking_metatable(&mut seq, frame, "input", &[line]).await?;
|
call_checking_metatable::<StashedTable>(&mut seq, frame, "input", &[line]).await?;
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -278,47 +296,64 @@ pub(super) fn send_command_to_frame<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
|
|||||||
|
|
||||||
pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
|
pub(super) fn frame_input<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let callback_return = {
|
||||||
let frame_tab: Table = Table::from_value(
|
let frame_tab: Table = Table::from_value(
|
||||||
ctx,
|
ctx,
|
||||||
stack
|
stack
|
||||||
.pop_front()
|
.pop_front()
|
||||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:new missing object!"))?,
|
.ok_or_else(|| anyhow::Error::msg("classes.frame:input missing object!"))?,
|
||||||
)?;
|
)?;
|
||||||
let line: Value = stack
|
let line: Value = stack
|
||||||
.pop_front()
|
.pop_front()
|
||||||
.ok_or_else(|| anyhow::Error::msg("classes.frame:new missing line!"))?;
|
.ok_or_else(|| anyhow::Error::msg("classes.frame:input missing line!"))?;
|
||||||
stack.consume(ctx)?;
|
stack.consume(ctx)?;
|
||||||
|
|
||||||
// Check for an alias match...
|
let aliases: UserData = frame_tab.get(ctx, "aliases")?;
|
||||||
for (alias_match, alias_sub) in frame_tab.get::<&str, Table>(ctx, "aliases")?.iter() {
|
let frame: Value = frame_tab.get(ctx, "frame")?;
|
||||||
if let Some(alias_match) = piccolo::String::from_value(ctx, alias_match)
|
|
||||||
.ok()
|
|
||||||
.and_then(|am| am.to_str().ok())
|
|
||||||
.and_then(|v| Regex::new(v).ok())
|
|
||||||
{
|
|
||||||
if let Some(alias_sub) = piccolo::String::from_value(ctx, alias_sub)
|
|
||||||
.ok()
|
|
||||||
.and_then(|am| am.to_str().ok())
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 seq = async_sequence(&ctx, |locals, mut seq| {
|
||||||
let linked_mud = locals.stash(&ctx, linked_mud);
|
let aliases = locals.stash(&ctx, aliases);
|
||||||
let line = locals.stash(&ctx, line);
|
let line = locals.stash(&ctx, line);
|
||||||
|
let frame_tab = locals.stash(&ctx, frame_tab);
|
||||||
|
let frame = locals.stash(&ctx, frame);
|
||||||
async move {
|
async move {
|
||||||
call_checking_metatable(&mut seq, linked_mud, "mudinput_line", &[line]).await?;
|
call_checking_metatable::<StashedUserData>(
|
||||||
|
&mut seq,
|
||||||
|
aliases.clone(),
|
||||||
|
"try_run_sub",
|
||||||
|
&[line.clone(), frame],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let (alias_hit, linked_mud, linked_mud_nil) =
|
||||||
|
seq.try_enter(|ctx, locals, _ex, mut stack| {
|
||||||
|
let linked_mud = locals
|
||||||
|
.fetch(&frame_tab)
|
||||||
|
.get_value(ctx, ctx.intern_static(b"linked_mud"));
|
||||||
|
Ok((
|
||||||
|
stack.consume::<bool>(ctx)?,
|
||||||
|
locals.stash(&ctx, linked_mud),
|
||||||
|
linked_mud.is_nil(),
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if alias_hit || linked_mud_nil {
|
||||||
|
return Ok(SequenceReturn::Return);
|
||||||
|
}
|
||||||
|
|
||||||
|
call_checking_metatable::<StashedValue>(
|
||||||
|
&mut seq,
|
||||||
|
linked_mud,
|
||||||
|
"mudinput_line",
|
||||||
|
&[line],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(piccolo::CallbackReturn::Sequence(seq))
|
Ok(piccolo::CallbackReturn::Sequence(seq))
|
||||||
|
};
|
||||||
|
callback_return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ pub(super) fn connect_mud<'gc>(
|
|||||||
let seq = async_sequence(&ctx, |locals, mut seq| {
|
let seq = async_sequence(&ctx, |locals, mut seq| {
|
||||||
let conntab = locals.stash(&ctx, conntab);
|
let conntab = locals.stash(&ctx, conntab);
|
||||||
async move {
|
async move {
|
||||||
call_checking_metatable(&mut seq, conntab, "new", &[]).await?;
|
call_checking_metatable::<StashedTable>(&mut seq, conntab, "new", &[]).await?;
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -319,7 +319,7 @@ pub(super) fn mudoutput<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -
|
|||||||
.collect();
|
.collect();
|
||||||
async move {
|
async move {
|
||||||
for (func_name, params) in fns {
|
for (func_name, params) in fns {
|
||||||
call_checking_metatable(
|
call_checking_metatable::<StashedTable>(
|
||||||
&mut seq,
|
&mut seq,
|
||||||
conntab.clone(),
|
conntab.clone(),
|
||||||
func_name,
|
func_name,
|
||||||
@ -401,7 +401,13 @@ pub(super) fn mudoutput_line<'gc>(
|
|||||||
let line = locals.stash(&ctx, line.into_value(ctx));
|
let line = locals.stash(&ctx, line.into_value(ctx));
|
||||||
async move {
|
async move {
|
||||||
for frameroute in frameroutes {
|
for frameroute in frameroutes {
|
||||||
call_checking_metatable(&mut seq, frameroute, "route", &[line.clone()]).await?;
|
call_checking_metatable::<StashedTable>(
|
||||||
|
&mut seq,
|
||||||
|
frameroute,
|
||||||
|
"route",
|
||||||
|
&[line.clone()],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
@ -494,7 +500,8 @@ pub(super) fn new_mud<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) ->
|
|||||||
let curr_frame = locals.stash(&ctx, curr_frame);
|
let curr_frame = locals.stash(&ctx, curr_frame);
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
call_checking_metatable(&mut seq, frameroute, "new", &[curr_frame]).await?;
|
call_checking_metatable::<StashedTable>(&mut seq, frameroute, "new", &[curr_frame])
|
||||||
|
.await?;
|
||||||
Ok(SequenceReturn::Return)
|
Ok(SequenceReturn::Return)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -8,12 +8,11 @@ use gc_arena::{Collect, GcRefLock, Rootable};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use piccolo::{Callback, Context, IntoValue, Table, UserData, Value};
|
use piccolo::{Callback, Context, IntoValue, Table, UserData, Value};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use yew::UseStateSetter;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
lua_engine::frames::try_unwrap_frame,
|
lua_engine::frames::try_unwrap_frame,
|
||||||
parsing::{parse_commands, quote_string, ArgumentGuard, ParsedArgument, ParsedCommand},
|
parsing::{parse_commands, quote_string, ArgumentGuard, ParsedArgument, ParsedCommand},
|
||||||
GlobalLayoutCell, GlobalMemoCell,
|
GlobalMemoCell,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Debug, Collect)]
|
#[derive(Default, Debug, Collect)]
|
||||||
@ -251,6 +250,87 @@ pub enum SubTextPart {
|
|||||||
Variable(String),
|
Variable(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_match_table<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||||
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let _: () = stack.consume(ctx)?;
|
||||||
|
let user_data = UserData::<'gc>::new::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>(
|
||||||
|
&ctx,
|
||||||
|
GcRefLock::new(&ctx, <MatchSubTable as Default>::default().into()),
|
||||||
|
);
|
||||||
|
let match_table_class: Table = ctx
|
||||||
|
.get_global::<Table>("classes")?
|
||||||
|
.get(ctx, "match_table")?;
|
||||||
|
user_data.set_metatable(&ctx, Some(match_table_class));
|
||||||
|
|
||||||
|
stack.push_back(user_data.into_value(ctx));
|
||||||
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn match_table_add<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||||
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let (match_table, match_text, sub_text): (UserData, piccolo::String, piccolo::String) =
|
||||||
|
stack.consume(ctx)?;
|
||||||
|
match_table
|
||||||
|
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||||
|
.borrow_mut(&ctx)
|
||||||
|
.add_record(match_text.to_str()?, sub_text.to_str()?)?;
|
||||||
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn match_table_remove<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||||
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let (match_table, match_text): (UserData, piccolo::String) = stack.consume(ctx)?;
|
||||||
|
match_table
|
||||||
|
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||||
|
.borrow_mut(&ctx)
|
||||||
|
.remove_record(match_text.to_str()?)?;
|
||||||
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn match_table_lua_table<'gc, 'a>(ctx: Context<'gc>) -> Callback<'gc> {
|
||||||
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let match_table: UserData = stack.consume(ctx)?;
|
||||||
|
stack.push_back(
|
||||||
|
match_table
|
||||||
|
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||||
|
.borrow_mut(&ctx)
|
||||||
|
.to_value(ctx)?,
|
||||||
|
);
|
||||||
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn match_table_try_run_sub<'gc, 'a>(
|
||||||
|
ctx: Context<'gc>,
|
||||||
|
global_memo: &'a GlobalMemoCell,
|
||||||
|
) -> Callback<'gc> {
|
||||||
|
let global_memo = global_memo.clone();
|
||||||
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
|
let (match_table, sub, frame): (UserData, piccolo::String, Value) = stack.consume(ctx)?;
|
||||||
|
let frame = try_unwrap_frame(ctx, &frame)?;
|
||||||
|
|
||||||
|
let cmds = match_table
|
||||||
|
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
||||||
|
.borrow()
|
||||||
|
.try_sub(sub.to_str()?);
|
||||||
|
|
||||||
|
match cmds {
|
||||||
|
None => stack.push_back(false.into_value(ctx)),
|
||||||
|
Some(cmds) => {
|
||||||
|
let mut cq = global_memo.command_queue.borrow_mut();
|
||||||
|
for cmd in cmds.into_iter().rev() {
|
||||||
|
cq.push_front((frame.clone(), cmd));
|
||||||
|
}
|
||||||
|
stack.push_back(Value::Boolean(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -452,97 +532,3 @@ mod tests {
|
|||||||
.is_err())
|
.is_err())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_match_table<'gc, 'a>(
|
|
||||||
ctx: Context<'gc>,
|
|
||||||
_global_memo: &'a GlobalMemoCell,
|
|
||||||
_global_layout: &'a UseStateSetter<GlobalLayoutCell>,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
||||||
let _: () = stack.consume(ctx)?;
|
|
||||||
let user_data = UserData::<'gc>::new::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>(
|
|
||||||
&ctx,
|
|
||||||
GcRefLock::new(&ctx, <MatchSubTable as Default>::default().into()),
|
|
||||||
);
|
|
||||||
let match_table_class: Table = ctx
|
|
||||||
.get_global::<Table>("classes")?
|
|
||||||
.get(ctx, "match_table")?;
|
|
||||||
user_data.set_metatable(&ctx, Some(match_table_class));
|
|
||||||
|
|
||||||
stack.push_back(user_data.into_value(ctx));
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_table_add<'gc, 'a>(
|
|
||||||
ctx: Context<'gc>,
|
|
||||||
_global_memo: &'a GlobalMemoCell,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
||||||
let (match_table, match_text, sub_text): (UserData, piccolo::String, piccolo::String) =
|
|
||||||
stack.consume(ctx)?;
|
|
||||||
match_table
|
|
||||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
|
||||||
.borrow_mut(&ctx)
|
|
||||||
.add_record(match_text.to_str()?, sub_text.to_str()?)?;
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_table_remove<'gc, 'a>(
|
|
||||||
ctx: Context<'gc>,
|
|
||||||
_global_memo: &'a GlobalMemoCell,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
||||||
let (match_table, match_text): (UserData, piccolo::String) = stack.consume(ctx)?;
|
|
||||||
match_table
|
|
||||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
|
||||||
.borrow_mut(&ctx)
|
|
||||||
.remove_record(match_text.to_str()?)?;
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_table_lua_table<'gc, 'a>(
|
|
||||||
ctx: Context<'gc>,
|
|
||||||
_global_memo: &'a GlobalMemoCell,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
||||||
let match_table: UserData = stack.consume(ctx)?;
|
|
||||||
stack.push_back(
|
|
||||||
match_table
|
|
||||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
|
||||||
.borrow_mut(&ctx)
|
|
||||||
.to_value(ctx)?,
|
|
||||||
);
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn match_table_try_run_sub<'gc, 'a>(
|
|
||||||
ctx: Context<'gc>,
|
|
||||||
global_memo: &'a GlobalMemoCell,
|
|
||||||
) -> Callback<'gc> {
|
|
||||||
let global_memo = global_memo.clone();
|
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
|
||||||
let (match_table, sub, frame): (UserData, piccolo::String, Value) = stack.consume(ctx)?;
|
|
||||||
let frame = try_unwrap_frame(ctx, &frame)?;
|
|
||||||
|
|
||||||
let cmds = match_table
|
|
||||||
.downcast::<Rootable!['gcb => GcRefLock<'gcb, MatchSubTable>]>()?
|
|
||||||
.borrow()
|
|
||||||
.try_sub(sub.to_str()?);
|
|
||||||
|
|
||||||
match cmds {
|
|
||||||
None => stack.push_back(false.into_value(ctx)),
|
|
||||||
Some(cmds) => {
|
|
||||||
let mut cq = global_memo.command_queue.borrow_mut();
|
|
||||||
for cmd in cmds.into_iter().rev() {
|
|
||||||
cq.push_front((frame.clone(), cmd));
|
|
||||||
}
|
|
||||||
stack.push_back(Value::Boolean(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user