Skip to main content

gizmo_scripting/
api_entity.rs

1//! Entity API — Lua'ya sunulan entity yönetim fonksiyonları
2//!
3//! Lua scriptlerinden entity pozisyon, rotasyon, hız ve ölçek bilgilerine
4//! erişim sağlar. Tüm değişiklikler komut kuyruğuna yazılır.
5
6use crate::commands::{CommandQueue, ScriptCommand};
7use gizmo_core::World;
8use gizmo_math::{Quat, Vec3};
9use mlua::prelude::*;
10use std::sync::Arc;
11
12/// Entity API fonksiyonlarını Lua'ya kaydeder
13pub fn register_entity_api(lua: &Lua, command_queue: Arc<CommandQueue>) -> Result<(), LuaError> {
14    let entity_table = lua.create_table()?;
15
16    // === POSITION ===
17    {
18        let cq = command_queue.clone();
19        entity_table.set(
20            "set_position",
21            lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
22                cq.push(ScriptCommand::SetPosition(id, Vec3::new(x, y, z)));
23                Ok(())
24            })?,
25        )?;
26    }
27
28    // === ROTATION ===
29    {
30        let cq = command_queue.clone();
31        entity_table.set(
32            "set_rotation",
33            lua.create_function(move |_, (id, x, y, z, w): (u32, f32, f32, f32, f32)| {
34                cq.push(ScriptCommand::SetRotation(id, Quat::from_xyzw(x, y, z, w)));
35                Ok(())
36            })?,
37        )?;
38    }
39
40    // === SCALE ===
41    {
42        let cq = command_queue.clone();
43        entity_table.set(
44            "set_scale",
45            lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
46                cq.push(ScriptCommand::SetScale(id, Vec3::new(x, y, z)));
47                Ok(())
48            })?,
49        )?;
50    }
51
52    // === VELOCITY ===
53    {
54        let cq = command_queue.clone();
55        entity_table.set(
56            "set_velocity",
57            lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
58                cq.push(ScriptCommand::SetVelocity(id, Vec3::new(x, y, z)));
59                Ok(())
60            })?,
61        )?;
62    }
63
64    {
65        let cq = command_queue.clone();
66        entity_table.set(
67            "set_angular_velocity",
68            lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
69                cq.push(ScriptCommand::SetAngularVelocity(id, Vec3::new(x, y, z)));
70                Ok(())
71            })?,
72        )?;
73    }
74
75    // === SPAWN ===
76    {
77        let cq = command_queue.clone();
78        entity_table.set(
79            "spawn",
80            lua.create_function(move |_, (name, x, y, z): (String, f32, f32, f32)| {
81                cq.push(ScriptCommand::SpawnEntity {
82                    name,
83                    position: Vec3::new(x, y, z),
84                });
85                Ok(())
86            })?,
87        )?;
88    }
89
90    // === SPAWN PREFAB ===
91    {
92        let cq = command_queue.clone();
93        entity_table.set(
94            "spawn_prefab",
95            lua.create_function(
96                move |_, (name, prefab_type, x, y, z): (String, String, f32, f32, f32)| {
97                    cq.push(ScriptCommand::SpawnPrefab {
98                        name,
99                        prefab_type,
100                        position: Vec3::new(x, y, z),
101                    });
102                    Ok(())
103                },
104            )?,
105        )?;
106    }
107
108    // === DESTROY ===
109    {
110        let cq = command_queue.clone();
111        entity_table.set(
112            "destroy",
113            lua.create_function(move |_, id: u32| {
114                cq.push(ScriptCommand::DestroyEntity(id));
115                Ok(())
116            })?,
117        )?;
118    }
119
120    // === SET NAME ===
121    {
122        let cq = command_queue.clone();
123        entity_table.set(
124            "set_name",
125            lua.create_function(move |_, (id, name): (u32, String)| {
126                cq.push(ScriptCommand::SetEntityName(id, name));
127                Ok(())
128            })?,
129        )?;
130    }
131
132    lua.globals().set("entity", entity_table)?;
133    Ok(())
134}
135
136/// World'den okunan verilerle entity read API'sini günceller (her frame)
137pub fn update_entity_read_api(lua: &Lua, world: &World) -> Result<(), LuaError> {
138    let entity_table: LuaTable = lua.globals().get("entity")?;
139
140    // get_position: World'den doğrudan okunan veriye dayalı closure
141    // Her frame snapshot alarak Lua table'ına yazıyoruz
142    let positions = lua.create_table()?;
143    let velocities = lua.create_table()?;
144    let rotations = lua.create_table()?;
145    let scales = lua.create_table()?;
146    let names = lua.create_table()?;
147
148    let transforms = world.borrow::<gizmo_physics::components::Transform>();
149    for (eid, _) in transforms.iter() {
150        if let Some(t) = transforms.get(eid) {
151            let pos = lua.create_table()?;
152            pos.set("x", t.position.x)?;
153            pos.set("y", t.position.y)?;
154            pos.set("z", t.position.z)?;
155            positions.set(eid, pos)?;
156
157            let rot = lua.create_table()?;
158            rot.set("x", t.rotation.x)?;
159            rot.set("y", t.rotation.y)?;
160            rot.set("z", t.rotation.z)?;
161            rot.set("w", t.rotation.w)?;
162            rotations.set(eid, rot)?;
163
164            let scl = lua.create_table()?;
165            scl.set("x", t.scale.x)?;
166            scl.set("y", t.scale.y)?;
167            scl.set("z", t.scale.z)?;
168            scales.set(eid, scl)?;
169        }
170    }
171
172    let vels = world.borrow::<gizmo_physics::components::Velocity>();
173    for (eid, _) in vels.iter() {
174        if let Some(v) = vels.get(eid) {
175            let vel = lua.create_table()?;
176            vel.set("x", v.linear.x)?;
177            vel.set("y", v.linear.y)?;
178            vel.set("z", v.linear.z)?;
179            velocities.set(eid, vel)?;
180        }
181    }
182
183    let entity_names = world.borrow::<gizmo_core::EntityName>();
184    for (eid, _) in entity_names.iter() {
185        if let Some(n) = entity_names.get(eid) {
186            names.set(eid, n.0.clone())?;
187        }
188    }
189
190    // Snapshot table'ları entity API'sine bağla
191    entity_table.set("_positions", positions)?;
192    entity_table.set("_velocities", velocities)?;
193    entity_table.set("_rotations", rotations)?;
194    entity_table.set("_scales", scales)?;
195    entity_table.set("_names", names)?;
196
197    // Lua tarafı get_position(id) gibi helper fonksiyonları kullanır
198    lua.load(
199        r#"
200        function entity.get_position(id)
201            return entity._positions[id] or {x=0, y=0, z=0}
202        end
203        function entity.get_velocity(id)
204            return entity._velocities[id] or {x=0, y=0, z=0}
205        end
206        function entity.get_rotation(id)
207            return entity._rotations[id] or {x=0, y=0, z=0, w=1}
208        end
209        function entity.get_scale(id)
210            return entity._scales[id] or {x=1, y=1, z=1}
211        end
212        function entity.get_name(id)
213            return entity._names[id] or ""
214        end
215    "#,
216    )
217    .exec()?;
218
219    Ok(())
220}