diff --git a/Cargo.lock b/Cargo.lock index 47e404a..487606b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -309,6 +309,7 @@ dependencies = [ "bevy", "include_dir", "mlua", + "nameof", ] [[package]] @@ -2933,6 +2934,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "nameof" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae5794a00611c89e072a2d8bd5164c410a96181f1f7f40676c94293d44af1401" + [[package]] name = "ndk" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index ae78fc8..f281755 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" bevy = { version = "0.16", features = ["file_watcher"] } include_dir = "0.7.4" mlua = { version = "0.11.5", features = ["luau","luau-jit","luau-vector4","serde","send"] } +nameof = "1.3.0" [profile.dev.package."*"] opt-level = 3 diff --git a/src/duck.rs b/src/duck.rs index d5618ed..b9d5db2 100644 --- a/src/duck.rs +++ b/src/duck.rs @@ -1,76 +1,166 @@ use mlua::UserData; use mlua::Lua; use bevy::prelude::*; +use mlua::UserDataFields; +use mlua::UserDataMethods; +use nameof::name_of_type; +use std::ops::Deref; +use std::ops::DerefMut; use include_dir::{include_dir, Dir}; static DATA_DIR: Dir<'_> = include_dir!("data"); -/* -In lieu of the old Roblox instances. -Instances, at least for the sake of bevy's design, -are helper components that also implement a lua userdata wrapper. - -I'm sure storing the Entity in the component is bad practice, -but I can't find a cleaner way of integrating with Bevy's ECS like this. -*/ - -trait Instance: UserData { - +struct BevyContext<'a> { + commands: Commands<'a, 'a> +} +impl<'a> BevyContext<'a> { + fn from_raw(commands: Commands<'a,'a>) -> Self { + BevyContext { commands: commands } + } + /*fn get_instance(&self, entity: Entity) -> &T { + self.commands.entity(entity). + }*/ } -struct Script { - name: String -} - -impl Instance for Script { +// Id for this object to the server +struct Netlink { } - -struct Context { - name: String, - lua: Lua -} - -impl Instance for Context { - -} - -struct Part { - name: String -} - -impl Instance for Part { - -} - -struct Folder { - name: String -} - -impl Instance for Folder { - +trait Class { + // Class name for filtering + fn class_name() -> String { name_of_type!(Self).into() } + // Create a default object + fn new_entity<'a>(context: &BevyContext) -> (EntityCommands<'a>, Self); + // fn clone(&self) -> Self; + fn add_fields>(_fields: &mut F) {} + fn add_methods>(_methods: &mut F) {} } +#[derive(Component)] +struct Instance { + name: String, + class: S, + entity: Entity, + netlink: Netlink +} +impl UserData for Instance { + fn add_fields>(fields: &mut F) { + S::add_fields::(fields); + } + fn add_methods>(methods: &mut M) { + S::add_methods::(methods); + } +} +impl Instance { + fn new(context: &BevyContext) -> Self { + let (entity,sub) = S::new_entity(context); + Instance { + name: S::class_name(), + class: sub, + entity: entity.id(), + netlink: Netlink {}, + } + } +} + +struct Constructor; + +impl UserData for Constructor { + fn add_methods>(methods: &mut M) { + methods.add_method("part", |lua, this, ()| { + let part = IPart::new() + + }); + } +} + +#[derive(Resource)] +struct ScriptContext { + lua: Lua +} +impl Class for ScriptContext { + fn new_entity(context: &BevyContext) -> (EntityCommands<'_>,Self) { + ( context.commands.spawn_empty(), ScriptContext::new() ) + } +} +impl ScriptContext { + fn new() -> Self { + let lua = Lua::new(); + lua.sandbox(true); + let globals = lua.globals(); + globals.set("new",Constructor); + ScriptContext { lua: lua } + } +} + +struct Script { + context: Entity +} +impl Class for Script { + fn new_entity(context: &BevyContext) -> (Entity, Self) { + ( context.) + } +} + +// Attachment +struct Node; +impl Class for Node {} + +struct Part { + +} +impl Class for Part { + fn new_entity(context: &BevyContext) -> Self { + commands.spawn() + } +} +impl UserData for Part {} + +struct Located { + class: S +} +impl UserData for Located { + fn add_fields>(fields: &mut F) { + S::add_fields(fields); + } + fn add_methods>(methods: &mut M) { + S::add_methods(methods); + } +} +impl Class for Located { + fn new_entity(context: &BevyContext) -> Self { + let (entity,sub) = S::new_entity(context); + Located { class: S::new_entity(context), } + } +} + +type IAttachment = Instance>; +type IModel = Instance>; +type IPart = Instance>; +type IContext = Instance; +type IScript = Instance