lua - 如何从 Rust 的上下文中检索 lua 表?
问题描述
我正在尝试从 Rust 中的 lua 文件中检索表。我正在register_entity
lua 全局上下文中注册一个函数,以便数据文件注册它们的表。当 lua 文件被执行并调用该register_entity
函数时,注册的回调在 Rust 中被调用。回调应将传递的表添加到 aHashMap
中以维护所有实体的集合。
这是一个正在读取的示例 lua 文件。
Goblin = {
glyph: "2"
}
register_entity("Goblin", Goblin)
锈代码
fn load_lua_globals(&self) {
let entities = Arc::new(Mutex::new(HashMap::new()));
self.lua.context(|lua_ctx| {
let register_entity = {
let entities = Arc::clone(&entities);
let register_entity = lua_ctx.create_function(
move |_, (name, table): (String, Table)| {
entities.lock().unwrap().insert(name, table);
Ok(())
}).unwrap();
};
lua_ctx.globals().set("register_entity", register_entity).unwrap();
});
}
}
这是错误。
error[E0277]: `*mut rlua::ffi::lua_State` cannot be sent between threads safely
--> src/bin/main.rs:106:47
|
106 | let register_entity = lua_ctx.create_function(
| ^^^^^^^^^^^^^^^ `*mut rlua::ffi::lua_State` cannot be sent between threads safely
|
= help: within `(std::string::String, rlua::Table<'_>)`, the trait `std::marker::Send` is not implemented for `*mut rlua::ffi::lua_State`
= note: required because it appears within the type `rlua::Context<'_>`
= note: required because it appears within the type `rlua::types::LuaRef<'_>`
= note: required because it appears within the type `rlua::Table<'_>`
= note: required because it appears within the type `(std::string::String, rlua::Table<'_>)`
= note: required because of the requirements on the impl of `std::marker::Send` for `hashbrown::raw::RawTable<(std::string::String, rlua::Table<'_>)>`
= note: required because it appears within the type `hashbrown::map::HashMap<std::string::String, rlua::Table<'_>, std::collections::hash_map::RandomState>`
= note: required because it appears within the type `std::collections::HashMap<std::string::String, rlua::Table<'_>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<std::collections::HashMap<std::string::String, rlua::Table<'_>>>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Arc<std::sync::Mutex<std::collections::HashMap<std::string::String, rlua::Table<'_>>>>`
= note: required because it appears within the type `[closure@src/bin/main.rs:107:21: 112:18 entities:std::sync::Arc<std::sync::Mutex<std::collections::HashMap<std::string::String, rlua::Table<'_>>>>]
解决方案
您不能lua_ctx
在调用之外存储对 的引用Lua::context
。rlua::Table
您存储在实体中的内容与lua_ctx
.
rlua 提供了一种在上下文调用之外存储对 Lua 对象的引用的方法,使用Context::create_registry_value
. 它返回一个Regsitry
键,您可以安全地存储在 HashMap 中,然后在另一个调用中使用它Lua::context
。检查以下代码以获取示例:
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use rlua::{Lua, RegistryKey, Table};
const LUA_SOURCE: &str = r#"
Goblin = {
glyph = "2"
}
register_entity("Goblin", Goblin)
"#;
fn setup_register_entity(lua: &Lua) -> Arc<Mutex<HashMap<String, RegistryKey>>> {
let entities = Arc::new(Mutex::new(HashMap::new()));
lua.context(|lua_ctx| {
let entities = entities.clone();
let register_entity = lua_ctx.create_function(
move |ctx, (name, table): (String, Table)| {
// Store a refenrence to the object as a RegistryKey
let key = ctx.create_registry_value(table)
.expect("should have inserted in registry");
entities.lock().unwrap().insert(name, key);
Ok(())
})
.unwrap();
lua_ctx.globals().set("register_entity", register_entity).unwrap();
});
entities
}
fn main() {
let lua = Lua::new();
let entities = setup_register_entity(&lua);
lua.context(|lua_ctx| {
// Load lua code
lua_ctx.load(LUA_SOURCE)
.exec()
.expect("should load");
for (name, key) in entities.lock().unwrap().iter() {
// Retreive table
let table: Table = lua_ctx.registry_value(key).unwrap();
// Use it
let glyph: String = table.get("glyph").unwrap();
println!("{}.glyph = {}", name, glyph);
}
});
}
推荐阅读
- java - 如何将带日期的文件存储到SD卡中?
- java - 无法应用 setSupportActionBar(android.widget.Toolbar) 错误
- sqlite - 从包含关系表的数据库向客户端返回数据
- java - 当数据跨越多个块时如何建模分页
- android - 错误:无法解决:vectordrawable-animated
- typescript - `(keyof FormValues & string) | 的目的是什么?字符串`?
- javascript - 在函数外部定义的对象中填充函数的响应
- ssis - 卡在数据转换 SSIS
- java - 我们如何禁用休眠日志?
- spring-boot - 如何从远程机器上的 jar 文件运行测试?