Implement UserData interning + websocket connect
This commit is contained in:
parent
1df6e574d2
commit
466566a6c5
41
src/id_intern.rs
Normal file
41
src/id_intern.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
use gc_arena::{lock::GcRefLock, Collect, Gc, Rootable};
|
||||||
|
use piccolo::{Context, IntoValue, Singleton, UserData, Value};
|
||||||
|
|
||||||
|
#[derive(Collect)]
|
||||||
|
#[collect(no_drop)]
|
||||||
|
struct InternMapSingleton<'gc, A>(GcRefLock<'gc, BTreeMap<A, Gc<'gc, A>>>);
|
||||||
|
|
||||||
|
impl<'gc, A> Singleton<'gc> for InternMapSingleton<'gc, A>
|
||||||
|
where
|
||||||
|
A: Collect,
|
||||||
|
{
|
||||||
|
fn create(ctx: Context<'gc>) -> Self {
|
||||||
|
InternMapSingleton(Gc::new(&ctx, Default::default()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn intern_id<'gc, A>(ctx: Context<'gc>, input: A) -> Value<'gc>
|
||||||
|
where
|
||||||
|
A: Collect + Ord + Clone + 'static,
|
||||||
|
{
|
||||||
|
let intern_map: &'gc InternMapSingleton<'gc, A> =
|
||||||
|
ctx.singleton::<Rootable!['gcb => InternMapSingleton<'gcb, A>]>();
|
||||||
|
let gc_id = intern_map
|
||||||
|
.0
|
||||||
|
.borrow_mut(&ctx)
|
||||||
|
.entry(input.clone())
|
||||||
|
.or_insert_with(|| Gc::new(&ctx, input.clone()))
|
||||||
|
.clone();
|
||||||
|
UserData::<'gc>::new::<Rootable!['gcb => Gc<'gcb, A>]>(&ctx, gc_id).into_value(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unintern_id<'gc, A>(ctx: Context<'gc>, input: &A)
|
||||||
|
where
|
||||||
|
A: Collect + Ord + Clone + 'static,
|
||||||
|
{
|
||||||
|
let intern_map: &InternMapSingleton<'gc, A> =
|
||||||
|
ctx.singleton::<Rootable!['gcb => InternMapSingleton<'gcb, A>]>();
|
||||||
|
intern_map.0.borrow_mut(&ctx).remove(input);
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use gc_arena::Rootable;
|
use gc_arena::{Gc, Rootable};
|
||||||
use piccolo::{
|
use piccolo::{
|
||||||
self, Callback, Closure, Context, Executor, FromValue, Function, IntoValue, Lua,
|
self, Callback, Closure, Context, Executor, FromValue, Function, IntoValue, Lua,
|
||||||
StashedExecutor, StaticError, Table, UserData, Value, Variadic,
|
StashedExecutor, StaticError, Table, UserData, Value, Variadic,
|
||||||
@ -11,6 +11,7 @@ use yew::UseStateSetter;
|
|||||||
use crate::{
|
use crate::{
|
||||||
command_handler::debrace,
|
command_handler::debrace,
|
||||||
echo_to_term_frame,
|
echo_to_term_frame,
|
||||||
|
id_intern::intern_id,
|
||||||
websocket::{connect_websocket, send_message_to_mud, WebSocketId},
|
websocket::{connect_websocket, send_message_to_mud, WebSocketId},
|
||||||
GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell, TermFrame,
|
GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell, TermFrame,
|
||||||
};
|
};
|
||||||
@ -36,7 +37,7 @@ impl LuaState {
|
|||||||
info_table.set(
|
info_table.set(
|
||||||
ctx,
|
ctx,
|
||||||
ctx.intern_static(b"current_frame"),
|
ctx.intern_static(b"current_frame"),
|
||||||
wrap_frame(ctx, frame),
|
intern_id::<TermFrame>(ctx, frame.clone()),
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -120,6 +121,7 @@ pub fn install_lua_globals(
|
|||||||
register_command!(echo);
|
register_command!(echo);
|
||||||
register_command!(echo_frame);
|
register_command!(echo_frame);
|
||||||
register_command!(echo_frame_raw);
|
register_command!(echo_frame_raw);
|
||||||
|
register_command!(connect_mud);
|
||||||
register_command!(sendmud_raw);
|
register_command!(sendmud_raw);
|
||||||
register_command!(hsplit);
|
register_command!(hsplit);
|
||||||
register_command!(panel_merge);
|
register_command!(panel_merge);
|
||||||
@ -281,10 +283,6 @@ fn panel_merge<'gc>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_frame<'gc>(ctx: Context<'gc>, frame: &TermFrame) -> Value<'gc> {
|
|
||||||
UserData::new::<Rootable![TermFrame]>(&ctx, frame.clone()).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_unwrap_frame<'gc>(
|
fn try_unwrap_frame<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
value: &Value<'gc>,
|
value: &Value<'gc>,
|
||||||
@ -292,21 +290,19 @@ fn try_unwrap_frame<'gc>(
|
|||||||
match u64::from_value(ctx, *value) {
|
match u64::from_value(ctx, *value) {
|
||||||
Ok(v) => Ok(TermFrame(v)),
|
Ok(v) => Ok(TermFrame(v)),
|
||||||
Err(_) => Ok(UserData::from_value(ctx, *value)?
|
Err(_) => Ok(UserData::from_value(ctx, *value)?
|
||||||
.downcast::<Rootable![TermFrame]>()?
|
.downcast::<Rootable!['gcb => Gc<'gcb, TermFrame>]>()?
|
||||||
|
.as_ref()
|
||||||
.clone()),
|
.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap_socketid<'gc>(ctx: Context<'gc>, socket: &WebSocketId) -> Value<'gc> {
|
|
||||||
UserData::new::<Rootable![WebSocketId]>(&ctx, socket.clone()).into()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_unwrap_socketid<'gc>(
|
fn try_unwrap_socketid<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
value: &Value<'gc>,
|
value: &Value<'gc>,
|
||||||
) -> Result<WebSocketId, piccolo::Error<'gc>> {
|
) -> Result<WebSocketId, piccolo::Error<'gc>> {
|
||||||
Ok(UserData::from_value(ctx, *value)?
|
Ok(UserData::from_value(ctx, *value)?
|
||||||
.downcast::<Rootable![WebSocketId]>()?
|
.downcast::<Rootable!['gcb => Gc<'gcb, WebSocketId>]>()?
|
||||||
|
.as_ref()
|
||||||
.clone())
|
.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,7 +320,7 @@ pub fn handle_websocket_output(
|
|||||||
ctx.fetch(&engine.exec).restart(
|
ctx.fetch(&engine.exec).restart(
|
||||||
ctx,
|
ctx,
|
||||||
input_fn,
|
input_fn,
|
||||||
(wrap_socketid(ctx, socket), ctx.intern(input)),
|
(intern_id(ctx, socket.clone()), ctx.intern(input)),
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -353,7 +349,7 @@ pub fn handle_websocket_close(socket: &WebSocketId, engine: &mut LuaState) -> Re
|
|||||||
let input_fn =
|
let input_fn =
|
||||||
Function::from_value(ctx, handlers.get(ctx, ctx.intern_static(b"mudclose")))?;
|
Function::from_value(ctx, handlers.get(ctx, ctx.intern_static(b"mudclose")))?;
|
||||||
ctx.fetch(&engine.exec)
|
ctx.fetch(&engine.exec)
|
||||||
.restart(ctx, input_fn, wrap_socketid(ctx, socket));
|
.restart(ctx, input_fn, intern_id(ctx, socket.clone()));
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.map_err(|err| format!("{}", err))?;
|
.map_err(|err| format!("{}", err))?;
|
||||||
@ -394,7 +390,7 @@ fn connect_mud<'gc>(
|
|||||||
) -> Callback<'gc> {
|
) -> Callback<'gc> {
|
||||||
let global_memo = global_memo.clone();
|
let global_memo = global_memo.clone();
|
||||||
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
|
||||||
let trusted: bool = false;
|
let mut trusted: bool = false;
|
||||||
let name: String = loop {
|
let name: String = loop {
|
||||||
let v: String = stack.from_front(ctx)?;
|
let v: String = stack.from_front(ctx)?;
|
||||||
if v == "-trust" {
|
if v == "-trust" {
|
||||||
@ -413,20 +409,17 @@ fn connect_mud<'gc>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let url: String = stack.from_front(ctx)?;
|
let url: String = stack.from_front(ctx)?;
|
||||||
let new_socket = connect_websocket(
|
let new_socket = intern_id(
|
||||||
trusted,
|
ctx,
|
||||||
&url,
|
connect_websocket(
|
||||||
&mut global_memo.ws_registry.borrow_mut(),
|
trusted,
|
||||||
&global_memo,
|
&url,
|
||||||
)?;
|
&mut global_memo.ws_registry.borrow_mut(),
|
||||||
|
&global_memo,
|
||||||
ctx.registry.singleton()
|
)?,
|
||||||
|
);
|
||||||
|
|
||||||
muds.set(ctx, name, new_socket)?;
|
muds.set(ctx, name, new_socket)?;
|
||||||
|
|
||||||
let mud: WebSocketId = try_unwrap_socketid(ctx, &stack.pop_front())?;
|
|
||||||
let msg: piccolo::String = stack.from_front(ctx)?;
|
|
||||||
send_message_to_mud(&mud, msg.as_bytes(), &global_memo)?;
|
|
||||||
Ok(piccolo::CallbackReturn::Return)
|
Ok(piccolo::CallbackReturn::Return)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ use term_split::TermSplit;
|
|||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
pub mod command_handler;
|
pub mod command_handler;
|
||||||
|
pub mod id_intern;
|
||||||
pub mod lineengine;
|
pub mod lineengine;
|
||||||
pub mod lua_state;
|
pub mod lua_state;
|
||||||
pub mod parsing;
|
pub mod parsing;
|
||||||
|
Loading…
Reference in New Issue
Block a user