engine: rewrite component metatable setup to lua
parent
9c2c2c1f3c
commit
1553bdce9b
|
@ -1,10 +1,4 @@
|
||||||
sent = {}
|
sent = {}
|
||||||
sent.newindex = function(t, k, v)
|
|
||||||
return __sent_components_newindex(t, k, v)
|
|
||||||
end
|
|
||||||
sent.index = function(t, k)
|
|
||||||
return __sent_components_index(t, k)
|
|
||||||
end
|
|
||||||
sent.register = function (cfg)
|
sent.register = function (cfg)
|
||||||
if cfg.name == nil then
|
if cfg.name == nil then
|
||||||
error("sent.register: needs name")
|
error("sent.register: needs name")
|
||||||
|
@ -32,11 +26,35 @@ sent.register = function (cfg)
|
||||||
cls.__sent_class_id = sent_class_id
|
cls.__sent_class_id = sent_class_id
|
||||||
cls.new = function(...)
|
cls.new = function(...)
|
||||||
local arg = {...}
|
local arg = {...}
|
||||||
local res = __sent_new(sent_class_id)
|
|
||||||
if res.init ~= nil then
|
-- Make object table, instantiate with runtime.
|
||||||
res:init(unpack(arg))
|
local table = {}
|
||||||
|
local sent_id = __sent_new(table, sent_class_id)
|
||||||
|
table.__sent_id = sent_id
|
||||||
|
|
||||||
|
-- Configure components dispatcher.
|
||||||
|
table.components = {}
|
||||||
|
table.components.__sent_id = sent_id
|
||||||
|
local components_meta = {}
|
||||||
|
components_meta.__index = function(t, k)
|
||||||
|
return __sent_components_index(t, k)
|
||||||
end
|
end
|
||||||
return res
|
components_meta.__newindex = function(t, k, v)
|
||||||
|
return __sent_components_newindex(t, k, v)
|
||||||
|
end
|
||||||
|
setmetatable(table.components, components_meta)
|
||||||
|
|
||||||
|
-- Make table deref via table to class.
|
||||||
|
local metatable = {}
|
||||||
|
metatable.__index = cls
|
||||||
|
setmetatable(table, metatable)
|
||||||
|
|
||||||
|
-- Call initializer, if present.
|
||||||
|
if table.init ~= nil then
|
||||||
|
table:init(unpack(arg))
|
||||||
|
end
|
||||||
|
|
||||||
|
return table
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -52,14 +52,12 @@ struct ScriptedEntity {
|
||||||
internal_id: u64,
|
internal_id: u64,
|
||||||
status: ScriptedEntityStatus,
|
status: ScriptedEntityStatus,
|
||||||
table: mlua::RegistryKey,
|
table: mlua::RegistryKey,
|
||||||
cls: mlua::RegistryKey,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScriptedEntity {
|
impl ScriptedEntity {
|
||||||
fn new(
|
fn new(
|
||||||
class_name: String,
|
class_name: String,
|
||||||
table: mlua::RegistryKey,
|
table: mlua::RegistryKey,
|
||||||
cls: mlua::RegistryKey,
|
|
||||||
components: BTreeMap<String, Box<dyn ecs::Component>>,
|
components: BTreeMap<String, Box<dyn ecs::Component>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let internal_id = GLOBAL_SCRIPTED_ENTITY_ID.fetch_add(1, atomic::Ordering::SeqCst) + 1;
|
let internal_id = GLOBAL_SCRIPTED_ENTITY_ID.fetch_add(1, atomic::Ordering::SeqCst) + 1;
|
||||||
|
@ -68,69 +66,8 @@ impl ScriptedEntity {
|
||||||
internal_id,
|
internal_id,
|
||||||
status: ScriptedEntityStatus::QueuedForCreation(components),
|
status: ScriptedEntityStatus::QueuedForCreation(components),
|
||||||
table,
|
table,
|
||||||
cls,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_metatable(
|
|
||||||
&self,
|
|
||||||
lua: &mlua::Lua,
|
|
||||||
world: &ecs::World,
|
|
||||||
) -> mlua::Result<()>
|
|
||||||
{
|
|
||||||
// (meta)table tree for entity objects:
|
|
||||||
//
|
|
||||||
// table: { }
|
|
||||||
// | metatable
|
|
||||||
// V
|
|
||||||
// metatable: { __index }
|
|
||||||
// |
|
|
||||||
// .-------------'
|
|
||||||
// V
|
|
||||||
// dispatch: { components.{...}, ... }
|
|
||||||
// | metadata
|
|
||||||
// V
|
|
||||||
// metametatable: { __index }
|
|
||||||
// |
|
|
||||||
// .-----------------'
|
|
||||||
// V
|
|
||||||
// cls: { init, tick, ... }
|
|
||||||
|
|
||||||
let table: mlua::Table = lua.registry_value(&self.table)?;
|
|
||||||
let cls: mlua::Table = lua.registry_value(&self.cls)?;
|
|
||||||
|
|
||||||
let meta = lua.create_table()?;
|
|
||||||
let dispatch = lua.create_table()?;
|
|
||||||
let metameta = lua.create_table()?;
|
|
||||||
|
|
||||||
table.set_metatable(Some(meta.clone()));
|
|
||||||
meta.set("__index", dispatch.clone())?;
|
|
||||||
dispatch.set_metatable(Some(metameta.clone()));
|
|
||||||
metameta.set("__index", cls)?;
|
|
||||||
|
|
||||||
table.set("__sent_id", ScriptedEntityID {
|
|
||||||
internal_id: self.internal_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
let components = lua.create_table()?;
|
|
||||||
dispatch.set("components", components.clone())?;
|
|
||||||
|
|
||||||
let componentsmeta = lua.create_table()?;
|
|
||||||
componentsmeta.set(
|
|
||||||
"__index",
|
|
||||||
lua.globals().get::<_, mlua::Table>("sent")?.get::<_, mlua::Function>("index")?,
|
|
||||||
)?;
|
|
||||||
componentsmeta.set(
|
|
||||||
"__newindex",
|
|
||||||
lua.globals().get::<_, mlua::Table>("sent")?.get::<_, mlua::Function>("newindex")?,
|
|
||||||
)?;
|
|
||||||
components.set_metatable(Some(componentsmeta));
|
|
||||||
components.raw_set("__sent_id", ScriptedEntityID {
|
|
||||||
internal_id: self.internal_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -465,32 +402,31 @@ impl WorldContext {
|
||||||
{
|
{
|
||||||
let classes = self.classes.clone();
|
let classes = self.classes.clone();
|
||||||
let instances = self.instances.clone();
|
let instances = self.instances.clone();
|
||||||
globals.set("__sent_new", scope.create_function(move |lua, args: mlua::AnyUserData| {
|
globals.set("__sent_new", scope.create_function(move |lua, args: (mlua::Table, mlua::AnyUserData)| {
|
||||||
let classes = classes.lock().unwrap();
|
let classes = classes.lock().unwrap();
|
||||||
|
|
||||||
let secid = args.borrow::<ScriptedEntityClassID>()?;
|
let table = args.0;
|
||||||
|
let secid = args.1.borrow::<ScriptedEntityClassID>()?;
|
||||||
|
|
||||||
let sec = match classes.get(&secid.name) {
|
let sec = match classes.get(&secid.name) {
|
||||||
Some(el) => el,
|
Some(el) => el,
|
||||||
None => return Err(RuntimeError(format!("lost secid {:?}", secid.name))),
|
None => return Err(RuntimeError(format!("lost secid {:?}", secid.name))),
|
||||||
};
|
};
|
||||||
|
|
||||||
let cls: mlua::Table = lua.registry_value(&sec.cls)?;
|
|
||||||
let table = lua.create_table()?;
|
|
||||||
|
|
||||||
let components: BTreeMap<String, Box<dyn ecs::Component>> = sec.components.iter().map(|(k, v)| {
|
let components: BTreeMap<String, Box<dyn ecs::Component>> = sec.components.iter().map(|(k, v)| {
|
||||||
(k.clone(), v.clone_dyn())
|
(k.clone(), v.clone_dyn())
|
||||||
}).collect();
|
}).collect();
|
||||||
let sent = ScriptedEntity::new(
|
let sent = ScriptedEntity::new(
|
||||||
secid.name.clone(),
|
secid.name.clone(),
|
||||||
lua.create_registry_value(table.clone())?,
|
lua.create_registry_value(table.clone())?,
|
||||||
lua.create_registry_value(cls.clone())?,
|
|
||||||
components,
|
components,
|
||||||
);
|
);
|
||||||
sent.set_metatable(lua, world)?;
|
let seid = ScriptedEntityID {
|
||||||
|
internal_id: sent.internal_id,
|
||||||
|
};
|
||||||
instances.write().unwrap().queue.push(sent);
|
instances.write().unwrap().queue.push(sent);
|
||||||
|
|
||||||
Ok(table)
|
Ok(seid)
|
||||||
})?)?;
|
})?)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +492,7 @@ where
|
||||||
self.scope_resourcemanager(scope, world)?;
|
self.scope_resourcemanager(scope, world)?;
|
||||||
self.scope_time(scope, world)?;
|
self.scope_time(scope, world)?;
|
||||||
// Copy out functions refs to release lock.
|
// Copy out functions refs to release lock.
|
||||||
let mut to_run: Vec<(ecs::EntityID, mlua::Function)> = vec![];
|
let mut tickers: Vec<(ecs::EntityID, mlua::Function)> = vec![];
|
||||||
{
|
{
|
||||||
let instances = instances.read().unwrap();
|
let instances = instances.read().unwrap();
|
||||||
for (ecsid, sent) in instances.ecs.iter() {
|
for (ecsid, sent) in instances.ecs.iter() {
|
||||||
|
@ -581,10 +517,11 @@ where
|
||||||
continue;
|
continue;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
to_run.push((*ecsid, cb));
|
tickers.push((*ecsid, cb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ecsid, cb) in to_run.into_iter() {
|
|
||||||
|
for (ecsid, cb) in tickers.into_iter() {
|
||||||
match cb.call::<mlua::Value, mlua::Value>(mlua::Value::Nil) {
|
match cb.call::<mlua::Value, mlua::Value>(mlua::Value::Nil) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|
Loading…
Reference in New Issue