Skip to main content

gizmo_core/world/
mod.rs

1use crate::archetype::index::ArchetypeIndex;
2use crate::archetype::{Archetype, ComponentInfo, EntityLocation};
3use crate::component::Component;
4use crate::entity::Entity;
5
6use std::any::TypeId;
7use std::collections::HashMap;
8use std::marker::PhantomData;
9use std::sync::RwLock;
10
11pub mod hooks;
12pub mod resources;
13
14pub use self::hooks::*;
15pub use self::resources::*;
16pub use crate::entity::allocator::Entities;
17
18pub struct World {
19    // Entity'den bağımsız global veriler (Time, WindowSize, Input vs.)
20    resources: HashMap<TypeId, RwLock<Box<dyn std::any::Any + Send + Sync>>>,
21
22    /// Entity ID → archetype konumu. Hızlı O(1) lookup sağlar.
23    /// entity_id indeks olarak kullanılır.
24    entity_locations: Vec<EntityLocation>,
25
26    /// Archetype tabanlı depolama — tüm component verileri burada tutulur.
27    pub(crate) archetype_index: ArchetypeIndex,
28
29    /// Runtime component metadata cache'i. Archetype sütunları oluşturmak için gereklidir.
30    component_infos: HashMap<TypeId, ComponentInfo>,
31
32    pub(crate) component_hooks: HashMap<TypeId, ComponentHooks>,
33    pub(crate) sparse_sets: HashMap<TypeId, crate::archetype::sparse_set::ComponentSparseSet>,
34
35    despawn_hooks: Vec<DespawnHook>,
36    entities_to_despawn: Vec<Entity>,
37    is_despawning: bool,
38    pub(crate) entity_observers: HashMap<TypeId, Box<dyn std::any::Any + Send + Sync>>,
39    pub tick: u32,
40}
41
42impl World {
43    pub fn new() -> Self {
44        let mut world = Self {
45            resources: HashMap::new(),
46            entity_locations: Vec::new(),
47            archetype_index: ArchetypeIndex::new(),
48            component_infos: HashMap::new(),
49            component_hooks: HashMap::new(),
50            sparse_sets: HashMap::new(),
51            despawn_hooks: Vec::new(),
52            entities_to_despawn: Vec::new(),
53            is_despawning: false,
54            entity_observers: HashMap::new(),
55            tick: 1,
56        };
57        world.insert_resource(crate::commands::CommandQueue::new());
58        world.insert_resource(Entities::new());
59        world.insert_resource(Entities::new());
60        world
61    }
62
63    fn run_hooks<F>(&mut self, type_id: TypeId, mut f: F)
64    where
65        F: FnMut(&mut ComponentHooks, &mut World),
66    {
67        let mut hooks = self.component_hooks.remove(&type_id);
68        if let Some(ref mut h) = hooks {
69            f(h, self);
70        }
71        if let Some(h) = hooks {
72            if let Some(existing) = self.component_hooks.get_mut(&type_id) {
73                existing.on_add.extend(h.on_add);
74                existing.on_set.extend(h.on_set);
75                existing.on_remove.extend(h.on_remove);
76            } else {
77                self.component_hooks.insert(type_id, h);
78            }
79        }
80    }
81
82    /// Increments the local tick counter, guaranteeing it skips 0 on wrap.
83    pub fn increment_tick(&mut self) {
84        self.tick = self.tick.wrapping_add(1);
85        if self.tick == 0 {
86            self.tick = 1;
87        }
88
89        // Apply topological memory alignment for caching locality
90        self.sort_archetype_hierarchy();
91    }
92
93    /// Ertelenmiş komut kuyruğunu (CommandQueue) işler.
94    /// Entity ekleme/çıkarma işlemleri bu sayede kilitlenme (deadlock) yaşamadan batch halinde uygulanır.
95    pub fn apply_commands(&mut self) {
96        let queue_opt = self
97            .get_resource::<crate::commands::CommandQueue>()
98            .map(|q| (*q).clone());
99        if let Some(queue) = queue_opt {
100            queue.apply(self);
101        }
102    }
103}
104
105impl Default for World {
106    fn default() -> Self {
107        Self::new()
108    }
109}
110
111impl World {
112    /// Belirli bir component turunun runtime metadata'sini kaydeder.
113    /// Archetype storage migration asamalarinda column olusturma icin kullanilir.
114    #[inline]
115    pub fn register_component_type<T: Component>(&mut self) {
116        let type_id = TypeId::of::<T>();
117        self.component_infos
118            .entry(type_id)
119            .or_insert_with(ComponentInfo::of::<T>);
120    }
121
122    /// Registers a Component hook (Observer) for `OnInsert`.
123    pub fn add_observer<T: Component, F>(&mut self, mut system: F) -> &mut Self
124    where
125        F: FnMut(crate::observer::On<crate::observer::Insert, T>) + Send + Sync + 'static,
126    {
127        let type_id = TypeId::of::<T>();
128        let mut hooks = self.component_hooks.remove(&type_id).unwrap_or_default();
129        
130        hooks.on_add.push(Box::new(move |_world, entity| {
131            let event = crate::observer::On {
132                event: crate::observer::Insert,
133                entity,
134                _marker: std::marker::PhantomData,
135            };
136            system(event);
137        }));
138        
139        self.component_hooks.insert(type_id, hooks);
140        self
141    }
142
143    /// Özel EntityEvent'ler için Entity bazlı Observer kaydı
144    pub fn observe<E: crate::observer::EntityEvent, F>(&mut self, entity: Entity, listener: F) -> &mut Self
145    where
146        F: FnMut(crate::observer::On<E>) + Send + Sync + 'static,
147    {
148        let type_id = TypeId::of::<E>();
149        let map_any = self.entity_observers.entry(type_id).or_insert_with(|| {
150            Box::new(HashMap::<Entity, Vec<Box<dyn FnMut(crate::observer::On<E>) + Send + Sync + 'static>>>::new())
151        });
152        
153        let map = map_any.downcast_mut::<HashMap<Entity, Vec<Box<dyn FnMut(crate::observer::On<E>) + Send + Sync + 'static>>>>().unwrap();
154        map.entry(entity).or_default().push(Box::new(listener));
155        self
156    }
157
158    /// Bir Event'i tetikler ve hiyerarşide yukarı doğru yayar (bubble-up)
159    pub fn trigger<E: crate::observer::EntityEvent>(&mut self, event: E) {
160        use crate::component::Parent;
161        let mut current_entity = event.target();
162
163        loop {
164            // Observer'ları bu entity için bul ve çalıştır
165            let mut hooks_to_run = Vec::new();
166            
167            if let Some(map_any) = self.entity_observers.get_mut(&TypeId::of::<E>()) {
168                if let Some(map) = map_any.downcast_mut::<HashMap<Entity, Vec<Box<dyn FnMut(crate::observer::On<E>) + Send + Sync + 'static>>>>() {
169                    if let Some(listeners) = map.remove(&current_entity) {
170                        hooks_to_run = listeners;
171                    }
172                }
173            }
174
175            for mut listener in hooks_to_run.drain(..) {
176                let e = crate::observer::On {
177                    event: event.clone(),
178                    entity: current_entity,
179                    _marker: std::marker::PhantomData,
180                };
181                listener(e);
182                
183                // Geri koy
184                if let Some(map_any) = self.entity_observers.get_mut(&TypeId::of::<E>()) {
185                    if let Some(map) = map_any.downcast_mut::<HashMap<Entity, Vec<Box<dyn FnMut(crate::observer::On<E>) + Send + Sync + 'static>>>>() {
186                        map.entry(current_entity).or_default().push(listener);
187                    }
188                }
189            }
190
191            if !event.can_propagate() {
192                break;
193            }
194
195            // Propagate to parent
196            if let Some(parent_ptr) = self.get_component_ptr(current_entity, TypeId::of::<Parent>()) {
197                current_entity = self.reconstruct_entity(unsafe { (*(parent_ptr as *const Parent)).0 }).unwrap();
198            } else {
199                break;
200            }
201        }
202    }
203
204    /// Belirli bir component turu kayitli mi?
205    #[inline]
206    pub fn is_component_registered<T: Component>(&self) -> bool {
207        self.component_infos.contains_key(&TypeId::of::<T>())
208    }
209
210    /// Kayitli component metadata sayisi.
211    #[inline]
212    pub fn registered_component_count(&self) -> usize {
213        self.component_infos.len()
214    }
215
216    pub fn register_on_add<T: Component>(&mut self, hook: AddHook) {
217        self.component_hooks
218            .entry(TypeId::of::<T>())
219            .or_default()
220            .on_add
221            .push(hook);
222    }
223
224    pub fn register_on_remove<T: Component>(&mut self, hook: RemoveHook) {
225        self.component_hooks
226            .entry(TypeId::of::<T>())
227            .or_default()
228            .on_remove
229            .push(hook);
230    }
231
232    pub fn register_on_set<T: Component>(&mut self, hook: SetHook) {
233        self.component_hooks
234            .entry(TypeId::of::<T>())
235            .or_default()
236            .on_set
237            .push(hook);
238    }
239
240    pub fn spawn(&mut self) -> Entity {
241        let entity = {
242            let entities = self
243                .get_resource::<Entities>()
244                .expect("Entities resource not initialized");
245            entities.reserve_entity()
246        };
247
248        self.flush_spawn(entity);
249        entity
250    }
251
252    /// Bir `Bundle`'ı tek seferde spawn eder — entity oluşturur ve tüm
253    /// bileşenleri ekler.
254    ///
255    /// ```ignore
256    /// let player = world.spawn_bundle(MeshBundle {
257    ///     mesh: renderer.create_cube(),
258    ///     material: Material::pbr(Color::BLUE, 0.5, 0.0),
259    ///     name: "Oyuncu",
260    ///     ..default()
261    /// });
262    /// ```
263    pub fn spawn_bundle<B: crate::component::Bundle>(&mut self, bundle: B) -> Entity {
264        let entity = self.spawn();
265        bundle.apply(self, entity);
266        entity
267    }
268
269    pub fn flush_spawn(&mut self, entity: Entity) {
270        // Yeni entity'yi boş archetype'a kaydet
271        self.archetype_index.on_spawn(entity.id());
272
273        // Entity location tracking — boş archetype (id=0), row = entity'nin sırası
274        let eid = entity.id();
275        let loc_idx = eid as usize;
276        let row = self.archetype_index.archetypes[0].len() as u32 - 1;
277
278        if loc_idx >= self.entity_locations.len() {
279            self.entity_locations
280                .resize(loc_idx + 1, EntityLocation::INVALID);
281        }
282        self.entity_locations[loc_idx] = EntityLocation {
283            archetype_id: 0,
284            row,
285        };
286    }
287
288    // Eski A3 bridge ve rebuild metodları silindi (Archetype artık authoritative).
289
290    pub fn get_entity(&self, id: u32) -> Option<Entity> {
291        let entities = self
292            .get_resource::<Entities>()
293            .expect("Entities resource not initialized");
294        let state = entities.state.lock().expect("Entities mutex poisoned");
295        if (id as usize) < state.generations.len() && !state.free_set.contains(&id) {
296            return Some(Entity::new(id, state.generations[id as usize]));
297        }
298        None
299    }
300
301    /// Derin kopyalama (O(1) Prefab Splicing) işlemi.
302    /// Var olan bir Entity'nin bulunduğu archetype tablosunda tamamen bitişik olarak N adet yeni kopyasını çıkarır.
303    pub fn clone_entity(&mut self, source_id: u32, count: usize) -> Option<Vec<Entity>> {
304        if count == 0 {
305            return Some(Vec::new());
306        }
307
308        let loc = self.entity_locations.get(source_id as usize).copied()?;
309        if !loc.is_valid() {
310            return None;
311        }
312
313        let arch_id = loc.archetype_id as usize;
314        let row = loc.row as usize;
315
316        // Kilitlenmeleri engellemek için önce ID'leri üretelim
317        let mut new_entities = Vec::with_capacity(count);
318        let mut new_eids = Vec::with_capacity(count);
319
320        {
321            let entities_res = self
322                .get_resource::<Entities>()
323                .expect("Entities resource not initialized");
324            for _ in 0..count {
325                let e = entities_res.reserve_entity();
326                new_eids.push(e.id());
327                new_entities.push(e);
328            }
329        }
330
331        // Seçilen Archetype içinde kopyalamayı batch halinde yapıyoruz
332        let arch = &mut self.archetype_index.archetypes[arch_id];
333        let tick = self.tick;
334        let new_rows = unsafe { arch.batch_clone_row(row, count, &new_eids, tick) };
335
336        // Location güncellemeleri
337        for (i, &id) in new_eids.iter().enumerate() {
338            let row = new_rows[i];
339            let idx = id as usize;
340            if idx >= self.entity_locations.len() {
341                self.entity_locations
342                    .resize(idx + 1, EntityLocation::INVALID);
343            }
344            self.entity_locations[idx] = EntityLocation {
345                archetype_id: arch_id as u32,
346                row,
347            };
348            self.archetype_index.entity_archetype.insert(id, arch_id);
349            // NOT: on_spawn çağırmıyoruz çünkü batch_clone_row zaten entity'yi
350            // doğru archetype'a ekledi. on_spawn boş archetype'a (0) tekrar eklerdi.
351        }
352
353        Some(new_entities)
354    }
355
356    pub fn register_despawn_hook(&mut self, hook: DespawnHook) {
357        self.despawn_hooks.push(hook);
358    }
359
360    
361    pub fn spawn_batch<I>(&mut self, iter: I) -> impl Iterator<Item = Entity>
362    where
363        I: IntoIterator,
364        I::Item: crate::component::Bundle,
365    {
366        let mut iter = iter.into_iter();
367        let mut entities = Vec::new();
368
369        let first_bundle = match iter.next() {
370            Some(b) => b,
371            None => return entities.into_iter(),
372        };
373
374        let first_entity = self.spawn_bundle(first_bundle);
375        entities.push(first_entity);
376
377        let loc = self.entity_locations[first_entity.id() as usize];
378        let target_arch_id = loc.archetype_id as usize;
379
380        for bundle in iter {
381            let entity = {
382                let e_res = self.get_resource::<crate::entity::allocator::Entities>().expect("Entities not init");
383                e_res.reserve_entity()
384            };
385            let eid = entity.id();
386
387            let new_row = {
388                let arch = &mut self.archetype_index.archetypes[target_arch_id];
389                let row = arch.push_entity(eid);
390                unsafe { crate::component::Bundle::write_to_archetype(bundle, arch, row as usize, self.tick); }
391                row
392            };
393
394            let loc_idx = eid as usize;
395            if loc_idx >= self.entity_locations.len() {
396                self.entity_locations.resize(loc_idx + 1, crate::archetype::EntityLocation::INVALID);
397            }
398            self.entity_locations[loc_idx] = crate::archetype::EntityLocation {
399                archetype_id: target_arch_id as u32,
400                row: new_row,
401            };
402            self.archetype_index.entity_archetype.insert(eid, target_arch_id);
403
404            entities.push(entity);
405        }
406
407        entities.into_iter()
408    }
409
410    /// Tüm entityleri temizler.
411    pub fn clear_entities(&mut self) {
412        self.archetype_index.clear_entities();
413        self.entity_locations.clear();
414        self.entities_to_despawn.clear();
415        
416        // Entities resource'unu temizle (allocator state)
417        if let Some(entities) = self.get_resource::<Entities>() {
418            entities.clear();
419        }
420    }
421
422    pub fn despawn(&mut self, entity: Entity) {
423        self.entities_to_despawn.push(entity);
424        if self.is_despawning {
425            return;
426        }
427        self.is_despawning = true;
428
429        while let Some(e) = self.entities_to_despawn.pop() {
430            if !self.is_alive(e) {
431                continue;
432            }
433
434            let mut hooks = std::mem::take(&mut self.despawn_hooks);
435            for hook in &mut hooks {
436                hook(self, e);
437            }
438            self.despawn_hooks.extend(hooks);
439
440            let id = e.id();
441            let loc = self.entity_locations[id as usize];
442
443            if loc.is_valid() {
444                // Call OnRemove hooks for all currently held components
445                let comp_types = {
446                    let arch = &self.archetype_index.archetypes[loc.archetype_id as usize];
447                    arch.component_types()
448                };
449                for t in comp_types {
450                    self.run_hooks(t, |h, w| {
451                        for hook in &mut h.on_remove {
452                            hook(w, e);
453                        }
454                    });
455                }
456
457                // Re-fetch location safely after hooks might have mutated state
458                let loc = self.entity_locations[id as usize];
459                if loc.is_valid() {
460                    // Archetype'tan verileri temizle
461                    if let Some(moved_eid) = self.archetype_index.archetypes
462                        [loc.archetype_id as usize]
463                        .swap_remove_entity(loc.row as usize)
464                    {
465                        // Kayan entity'nin location bilgisini güncelle
466                        self.entity_locations[moved_eid as usize].row = loc.row;
467                    }
468                }
469            }
470
471            {
472                let entities = self
473                    .get_resource::<Entities>()
474                    .expect("Entities resource not initialized");
475                entities.free(e);
476            }
477
478            self.archetype_index.entity_archetype.remove(&id);
479            self.entity_locations[id as usize] = EntityLocation::INVALID;
480        }
481        self.is_despawning = false;
482    }
483
484    /// Hafızadaki boşlukları sıkıştırır ve kullanılmayan (boş) Archetype tablolarını silerek
485    /// RAM'i ve sistem performansını ilk baştaki defregmante (temiz) haline getirir.
486    /// Yükleme (Loading) ekranlarında veya düşük yoğunluklu anlarda çağrılması önerilir.
487    pub fn compact(&mut self) {
488        // 1. Önce eski, kullanılmayan boş archetype'ları silelim (GC)
489        self.archetype_index
490            .gc_empty_archetypes(&mut self.entity_locations);
491
492        // 2. Kalan archetype'ların kapasitelerini minimuma indirelim (Shrink To Fit)
493        for arch in &mut self.archetype_index.archetypes {
494            arch.shrink_to_fit();
495        }
496
497        self.archetype_index.archetypes.shrink_to_fit();
498
499        // 3. World seviyesindeki listeleri daraltalım.
500        self.entities_to_despawn.shrink_to_fit();
501        self.entity_locations.shrink_to_fit();
502
503        let entities = self
504            .get_resource::<Entities>()
505            .expect("Entities resource not initialized");
506        let mut state = entities.state.lock().expect("Entities mutex poisoned");
507        state.generations.shrink_to_fit();
508        state.free_ids.shrink_to_fit();
509        state.free_set.shrink_to_fit();
510    }
511
512    pub fn despawn_by_id(&mut self, id: u32) {
513        if let Some(entity) = self.get_entity(id) {
514            self.despawn(entity);
515        }
516    }
517
518    /// Yaşayan (despawn olmamış) tüm Entity'leri döndüren iterator.
519    /// Uyarı: İterasyon boyunca Entities mutex kilidi tutulur!
520    pub fn iter_alive_entities(&self) -> Vec<Entity> {
521        let entities = self
522            .get_resource::<Entities>()
523            .expect("Entities resource not initialized");
524        let state = entities.state.lock().expect("Entities mutex poisoned");
525        let mut alive = Vec::new();
526        for id in 0..state.next_entity_id {
527            if !state.free_set.contains(&id) {
528                alive.push(Entity::new(id, state.generations[id as usize]));
529            }
530        }
531        alive
532    }
533
534    #[inline]
535    pub fn is_alive(&self, entity: Entity) -> bool {
536        self.get_resource::<Entities>()
537            .expect("Entities resource not initialized")
538            .is_alive(entity)
539    }
540
541    /// Sisteme component ekleme — Veriyi archetype sütununa taşır.
542    
543    pub fn add_bundle<B: crate::component::Bundle>(&mut self, entity: Entity, bundle: B) {
544        if !self.is_alive(entity) { return; }
545        let eid = entity.id();
546        let infos = B::get_infos();
547        
548        for info in &infos {
549            self.component_infos.entry(info.type_id).or_insert_with(|| *info);
550        }
551        
552        // Şimdilik SparseSet desteklemiyor (bundle içi SparseSet olursa ayrıştırmak zor, future work)
553        // Table bazlı block move:
554        let old_arch_id = match self.archetype_index.entity_archetype.get(&eid) {
555            Some(&id) => id,
556            None => {
557                // Eğer entity önceden bomboşsa (sadece spawn edilmişse)
558                let _arch = &mut self.archetype_index.archetypes[0];
559                0
560            }
561        };
562
563        let mut new_types = self.archetype_index.archetypes[old_arch_id as usize].sorted_component_types();
564        for info in &infos {
565            if let Err(pos) = new_types.binary_search(&info.type_id) {
566                new_types.insert(pos, info.type_id);
567            }
568        }
569
570        let target_arch_id = if let Some(&id) = self.archetype_index.set_to_id.get(&new_types) {
571            id
572        } else {
573            let id = self.archetype_index.archetypes.len();
574            let mut new_infos = Vec::new();
575            for &t in &new_types {
576                new_infos.push(self.component_infos.get(&t).cloned().unwrap());
577            }
578            self.archetype_index.archetypes.push(crate::archetype::Archetype::new(id as u32, &new_infos));
579            self.archetype_index.set_to_id.insert(new_types, id);
580            id
581        };
582
583        if old_arch_id == target_arch_id {
584            // Sadece override
585            let loc = self.entity_locations[eid as usize];
586            let arch = &mut self.archetype_index.archetypes[target_arch_id];
587            unsafe { bundle.write_to_archetype(arch, loc.row as usize, self.tick); }
588            return;
589        }
590
591        let old_loc = self.entity_locations[eid as usize];
592        let (new_row, moved_eid) = unsafe {
593            let old_arch_ptr = &mut self.archetype_index.archetypes[old_arch_id] as *mut crate::archetype::Archetype;
594            let target_arch_ptr = &mut self.archetype_index.archetypes[target_arch_id] as *mut crate::archetype::Archetype;
595            (&mut *old_arch_ptr).move_entity_to(old_loc.row as usize, &mut *target_arch_ptr)
596        };
597
598        if let Some(moved) = moved_eid {
599            self.entity_locations[moved as usize].row = old_loc.row;
600        }
601
602        let arch = &mut self.archetype_index.archetypes[target_arch_id];
603        unsafe { bundle.write_to_archetype(arch, new_row as usize, self.tick); }
604
605        self.entity_locations[eid as usize] = EntityLocation {
606            archetype_id: target_arch_id as u32,
607            row: new_row,
608        };
609        self.archetype_index.entity_archetype.insert(eid, target_arch_id);
610    }
611
612    pub fn remove_bundle<B: crate::component::Bundle>(&mut self, entity: Entity) {
613        if !self.is_alive(entity) { return; }
614        let eid = entity.id();
615        let infos = B::get_infos();
616
617        let old_arch_id = match self.archetype_index.entity_archetype.get(&eid) {
618            Some(&id) => id,
619            None => return,
620        };
621
622        let mut new_types = self.archetype_index.archetypes[old_arch_id as usize].sorted_component_types();
623        for info in &infos {
624            if let Ok(pos) = new_types.binary_search(&info.type_id) {
625                new_types.remove(pos);
626            }
627        }
628
629        let target_arch_id = if let Some(&id) = self.archetype_index.set_to_id.get(&new_types) {
630            id
631        } else {
632            let id = self.archetype_index.archetypes.len();
633            let mut new_infos = Vec::new();
634            for &t in &new_types {
635                new_infos.push(self.component_infos.get(&t).cloned().unwrap());
636            }
637            self.archetype_index.archetypes.push(crate::archetype::Archetype::new(id as u32, &new_infos));
638            self.archetype_index.set_to_id.insert(new_types, id);
639            id
640        };
641
642        if old_arch_id == target_arch_id { return; }
643
644        let old_loc = self.entity_locations[eid as usize];
645        let (new_row, moved_eid) = unsafe {
646            let old_arch_ptr = &mut self.archetype_index.archetypes[old_arch_id] as *mut crate::archetype::Archetype;
647            let target_arch_ptr = &mut self.archetype_index.archetypes[target_arch_id] as *mut crate::archetype::Archetype;
648            (&mut *old_arch_ptr).move_entity_to(old_loc.row as usize, &mut *target_arch_ptr)
649        };
650
651        if let Some(moved) = moved_eid {
652            self.entity_locations[moved as usize].row = old_loc.row;
653        }
654
655        self.entity_locations[eid as usize] = EntityLocation {
656            archetype_id: target_arch_id as u32,
657            row: new_row,
658        };
659        self.archetype_index.entity_archetype.insert(eid, target_arch_id);
660    }
661
662    pub fn add_component<T: Component>(&mut self, entity: Entity, component: T) {
663        if !self.is_alive(entity) { return; }
664        let eid = entity.id();
665        self.register_component_type::<T>();
666        let type_id = TypeId::of::<T>();
667
668        if T::storage_type() == crate::component::StorageType::SparseSet {
669            let info = self.component_infos.get(&type_id).copied().unwrap_or_else(|| ComponentInfo::of::<T>());
670            let set = self.sparse_sets.entry(type_id).or_insert_with(|| {
671                crate::archetype::sparse_set::ComponentSparseSet::new(info)
672            });
673            let ptr = &component as *const T as *const u8;
674            set.insert(eid, ptr, self.tick);
675            std::mem::forget(component);
676
677            self.run_hooks(type_id, |h, w| {
678                for hook in &mut h.on_add { hook(w, entity); }
679                for hook in &mut h.on_set { hook(w, entity); }
680            });
681            return;
682        }
683
684        // Original logic follows but skip register and eid assignments
685
686
687
688        // 1. Hedef archetype'ı belirle
689        let target_arch_id =
690            match self
691                .archetype_index
692                .get_add_component_target(eid, type_id, &self.component_infos)
693            {
694                Some(id) => id,
695                None => return,
696            };
697        let old_loc = self.entity_locations[eid as usize];
698
699        if old_loc.archetype_id == target_arch_id as u32 {
700            // Zaten bu archetype'ta (aynı tip tekrar eklenmiş olabilir) — sadece üzerine yaz
701            {
702                let arch = &self.archetype_index.archetypes[target_arch_id];
703                let col = arch
704                    .get_column_mut(type_id)
705                    .expect("component column missing in current archetype");
706                unsafe {
707                    let ptr = col.get_ptr(old_loc.row as usize) as *mut T;
708                    *ptr = component;
709                    col.ticks_ptr_mut()
710                        .add(old_loc.row as usize)
711                        .write(crate::archetype::ComponentTicks::new(self.tick));
712                }
713            }
714            // Trigger OnSet hooks
715            let mut hooks = self.component_hooks.remove(&type_id);
716            if let Some(ref mut h) = hooks {
717                for hook in &mut h.on_set {
718                    hook(self, entity);
719                }
720            }
721            if let Some(h) = hooks {
722                if let Some(existing) = self.component_hooks.get_mut(&type_id) {
723                    existing.on_add.extend(h.on_add);
724                    existing.on_set.extend(h.on_set);
725                    existing.on_remove.extend(h.on_remove);
726                } else {
727                    self.component_hooks.insert(type_id, h);
728                }
729            }
730            return;
731        }
732
733        // 2. Migration: Verileri eski archetype'tan hedef archetype'a taşı
734        let (eid, old_arch_id, old_row) = (
735            entity.id(),
736            old_loc.archetype_id as usize,
737            old_loc.row as usize,
738        );
739
740        let (new_row, moved_eid) = unsafe {
741            // Raw pointer ile iki archetype'ı ödünç alıyoruz (farklı indeksler olduğu garantidir)
742            let old_arch_ptr = &mut self.archetype_index.archetypes[old_arch_id] as *mut Archetype;
743            let target_arch_ptr =
744                &mut self.archetype_index.archetypes[target_arch_id] as *mut Archetype;
745
746            (&mut *old_arch_ptr).move_entity_to(old_row, &mut *target_arch_ptr)
747        };
748
749        if let Some(moved) = moved_eid {
750            self.entity_locations[moved as usize].row = old_row as u32;
751        }
752
753        // 3. Yeni component'ı hedef archetype'a ekle
754        {
755            let arch = &self.archetype_index.archetypes[target_arch_id];
756            let col = arch
757                .get_column_mut(type_id)
758                .expect("Mandatory component column missing");
759            unsafe {
760                let ptr = col.get_ptr(new_row as usize) as *mut T;
761                std::ptr::write(ptr, component);
762                col.ticks_ptr_mut()
763                    .add(new_row as usize)
764                    .write(crate::archetype::ComponentTicks::new(self.tick));
765            }
766        }
767
768        // 4. Location güncellemeleri
769        self.entity_locations[eid as usize] = EntityLocation {
770            archetype_id: target_arch_id as u32,
771            row: new_row,
772        };
773        self.archetype_index
774            .entity_archetype
775            .insert(eid, target_arch_id);
776
777        let mut hooks = self.component_hooks.remove(&type_id);
778        if let Some(ref mut h) = hooks {
779            for hook in &mut h.on_add {
780                hook(self, entity);
781            }
782            for hook in &mut h.on_set {
783                hook(self, entity);
784            }
785        }
786        if let Some(h) = hooks {
787            if let Some(existing) = self.component_hooks.get_mut(&type_id) {
788                existing.on_add.extend(h.on_add);
789                existing.on_set.extend(h.on_set);
790                existing.on_remove.extend(h.on_remove);
791            } else {
792                self.component_hooks.insert(type_id, h);
793            }
794        }
795    }
796
797    /// Entity üzerindeki tüm bileşenlerin TypeId'lerini döndürür.
798    pub fn get_entity_component_types(&self, entity: Entity) -> Vec<TypeId> {
799        if !self.is_alive(entity) {
800            return Vec::new();
801        }
802        if let Some(&loc) = self.entity_locations.get(entity.id() as usize) {
803            if loc.is_valid() {
804                let arch = &self.archetype_index.archetypes[loc.archetype_id as usize];
805                return arch.component_types();
806            }
807        }
808        Vec::new()
809    }
810
811    /// Raw Component Pointer alma (Reflection/Editor için)
812    pub fn get_component_ptr(&self, entity: Entity, type_id: TypeId) -> Option<*const u8> {
813        let loc = self.entity_locations.get(entity.id() as usize).copied()?;
814        if !loc.is_valid() {
815            return None;
816        }
817        let arch = &self.archetype_index.archetypes[loc.archetype_id as usize];
818        let col = arch.get_column(type_id)?;
819        Some(unsafe { col.get_ptr(loc.row as usize) })
820    }
821
822    /// Mut mutable Component pointer alma (HierarchyExt vs için)
823    pub fn get_component_mut_ptr(&mut self, entity: Entity, type_id: TypeId) -> Option<*mut u8> {
824        let loc = self.entity_locations.get(entity.id() as usize).copied()?;
825        if !loc.is_valid() {
826            return None;
827        }
828        let arch = &mut self.archetype_index.archetypes[loc.archetype_id as usize];
829        let col = arch.get_column_mut(type_id)?;
830        Some(unsafe { col.get_mut_ptr(loc.row as usize) })
831    }
832
833    /// Entity ID'sinden geçerli nesneyi tekrar yapılandırır
834    pub fn reconstruct_entity(&self, id: u32) -> Option<Entity> {
835        if id as usize >= self.entity_locations.len() || !self.entity_locations[id as usize].is_valid() {
836            return None;
837        }
838        let entities = self.get_resource::<Entities>()?;
839        let state = entities.state.lock().unwrap();
840        if id as usize >= state.generations.len() || state.free_set.contains(&id) {
841            return None;
842        }
843        Some(Entity::new(id, state.generations[id as usize]))
844    }
845
846    /// Sistemden component silme
847    pub fn remove_component<T: Component>(&mut self, entity: Entity) {
848        if !self.is_alive(entity) { return; }
849        let eid = entity.id();
850        let type_id = TypeId::of::<T>();
851
852        if T::storage_type() == crate::component::StorageType::SparseSet {
853            if let Some(set) = self.sparse_sets.get_mut(&type_id) {
854                if set.remove(eid) {
855                    self.run_hooks(type_id, |h, w| {
856                        for hook in &mut h.on_remove { hook(w, entity); }
857                    });
858                }
859            }
860            return;
861        }
862
863
864        let old_loc = self.entity_locations[eid as usize];
865
866        // 1. Hedef archetype'ı belirle
867        let target_arch_id_opt =
868            self.archetype_index
869                .get_remove_component_target(eid, type_id, &self.component_infos);
870        let target_arch_id = match target_arch_id_opt {
871            Some(id) => id,
872            None => return, // Zaten yok veya hata
873        };
874
875        if old_loc.archetype_id == target_arch_id as u32 {
876            return; // Zaten yok
877        }
878
879        // 2. Migration
880        let (new_row, moved_eid) = unsafe {
881            let old_arch_ptr = &mut self.archetype_index.archetypes[old_loc.archetype_id as usize]
882                as *mut Archetype;
883            let target_arch_ptr =
884                &mut self.archetype_index.archetypes[target_arch_id] as *mut Archetype;
885            (&mut *old_arch_ptr).move_entity_to(old_loc.row as usize, &mut *target_arch_ptr)
886        };
887
888        if let Some(moved) = moved_eid {
889            self.entity_locations[moved as usize].row = old_loc.row;
890        }
891
892        // 3. Location güncelle
893        self.entity_locations[eid as usize] = EntityLocation {
894            archetype_id: target_arch_id as u32,
895            row: new_row,
896        };
897        self.archetype_index
898            .entity_archetype
899            .insert(eid, target_arch_id);
900
901        self.run_hooks(type_id, |h, w| {
902            for hook in &mut h.on_remove {
903                hook(w, entity);
904            }
905        });
906    }
907
908
909
910    // ==========================================================
911    // ERGONOMİK SORGULAR (QUERY API)
912    // ==========================================================
913
914    pub fn query<'w, Q: crate::query::WorldQuery>(&'w self) -> Option<crate::query::Query<'w, Q>> {
915        crate::query::Query::new(self)
916    }
917
918    /// Geriye uyumluluk için StorageView alternatifi
919    #[inline]
920    pub fn borrow<'w, T: Component>(&'w self) -> crate::query::Query<'w, &'w T> {
921        self.query::<&T>().expect("Failed to create borrow Query")
922    }
923
924    /// Geriye uyumluluk için StorageViewMut alternatifi
925    #[inline]
926    pub fn borrow_mut<'w, T: Component>(&'w self) -> crate::query::Query<'w, crate::query::Mut<'w, T>> {
927        self.query::<crate::query::Mut<T>>().expect("Failed to create borrow_mut Query")
928    }
929
930    /// Cache'li query — archetype indeks cache'ini kullanır.
931    /// &mut self gerektirdiği için sadece World sahibiyken çağrılabilir.
932    pub fn query_cached<'w, Q: crate::query::WorldQuery>(
933        &'w mut self,
934    ) -> Option<crate::query::Query<'w, Q>> {
935        crate::query::Query::new_cached(self)
936    }
937
938    /// Tek bir entity üzerinde `Query` çalıştırıp anında sonuç almanızı sağlar.
939    ///
940    /// # Örnek
941    /// ```ignore
942    /// if let Some((mut t, mut v)) = world.query_entity_mut::<(Mut<Transform>, Mut<Velocity>)>(id) {
943    ///     t.position += v.linear * dt;
944    /// }
945    /// ```
946    
947    /// Toplu (Batch) component ekleme. O(N) archetype lookup maliyetini O(1)'e düşürür.
948    pub fn insert_batch<T: Component + Clone>(&mut self, entities: &[Entity], component: T) {
949        if T::storage_type() == crate::component::StorageType::SparseSet {
950            for &e in entities {
951                self.add_component(e, component.clone());
952            }
953            return;
954        }
955
956        self.register_component_type::<T>();
957        let type_id = TypeId::of::<T>();
958
959        // 1. Gruplama: source_arch_id -> Vec<Entity>
960        let mut groups: std::collections::HashMap<u32, Vec<Entity>> = std::collections::HashMap::new();
961        
962        for &e in entities {
963            if !self.is_alive(e) { continue; }
964            let loc = self.entity_locations[e.id() as usize];
965            if !loc.is_valid() { continue; }
966            groups.entry(loc.archetype_id).or_default().push(e);
967        }
968
969        for (source_arch_id, group_entities) in groups {
970            let target_arch_id = match self.archetype_index.get_add_component_target(
971                group_entities[0].id(), type_id, &self.component_infos
972            ) {
973                Some(id) => id,
974                None => continue,
975            };
976
977            if source_arch_id == target_arch_id as u32 {
978                let arch = &self.archetype_index.archetypes[target_arch_id];
979                let col = arch.get_column_mut(type_id).unwrap();
980                for e in &group_entities {
981                    let row = self.entity_locations[e.id() as usize].row as usize;
982                    unsafe {
983                        std::ptr::write(col.get_ptr(row) as *mut T, component.clone());
984                        col.ticks_ptr_mut().add(row).write(crate::archetype::ComponentTicks::new(self.tick));
985                    }
986                }
987                self.run_hooks(type_id, |h, w| {
988                    for e in &group_entities {
989                        for hook in &mut h.on_set {
990                            hook(w, *e);
991                        }
992                    }
993                });
994                continue;
995            }
996
997            for e in &group_entities {
998                let eid = e.id();
999                let old_loc = self.entity_locations[eid as usize];
1000                let old_row = old_loc.row as usize;
1001
1002                let (new_row, moved_eid) = unsafe {
1003                    let old_arch_ptr = &mut self.archetype_index.archetypes[source_arch_id as usize] as *mut Archetype;
1004                    let target_arch_ptr = &mut self.archetype_index.archetypes[target_arch_id] as *mut Archetype;
1005                    (&mut *old_arch_ptr).move_entity_to(old_row, &mut *target_arch_ptr)
1006                };
1007
1008                if let Some(moved) = moved_eid {
1009                    self.entity_locations[moved as usize].row = old_row as u32;
1010                }
1011
1012                {
1013                    let arch = &self.archetype_index.archetypes[target_arch_id];
1014                    let col = arch.get_column_mut(type_id).unwrap();
1015                    unsafe {
1016                        std::ptr::write(col.get_ptr(new_row as usize) as *mut T, component.clone());
1017                        col.ticks_ptr_mut().add(new_row as usize).write(crate::archetype::ComponentTicks::new(self.tick));
1018                    }
1019                }
1020
1021                self.entity_locations[eid as usize] = EntityLocation {
1022                    archetype_id: target_arch_id as u32,
1023                    row: new_row,
1024                };
1025                self.archetype_index.entity_archetype.insert(eid, target_arch_id);
1026            }
1027
1028            self.run_hooks(type_id, |h, w| {
1029                for e in &group_entities {
1030                    for hook in &mut h.on_add { hook(w, *e); }
1031                    for hook in &mut h.on_set { hook(w, *e); }
1032                }
1033            });
1034        }
1035    }
1036
1037    /// Toplu (Batch) component çıkarma
1038    pub fn remove_batch<T: Component>(&mut self, entities: &[Entity]) {
1039        if T::storage_type() == crate::component::StorageType::SparseSet {
1040            for &e in entities {
1041                self.remove_component::<T>(e);
1042            }
1043            return;
1044        }
1045
1046        let type_id = TypeId::of::<T>();
1047        let mut groups: std::collections::HashMap<u32, Vec<Entity>> = std::collections::HashMap::new();
1048        
1049        for &e in entities {
1050            if !self.is_alive(e) { continue; }
1051            let loc = self.entity_locations[e.id() as usize];
1052            if !loc.is_valid() { continue; }
1053            groups.entry(loc.archetype_id).or_default().push(e);
1054        }
1055
1056        for (source_arch_id, group_entities) in groups {
1057            let target_arch_id = match self.archetype_index.get_remove_component_target(
1058                group_entities[0].id(), type_id, &self.component_infos
1059            ) {
1060                Some(id) => id,
1061                None => continue,
1062            };
1063
1064            if source_arch_id == target_arch_id as u32 {
1065                continue;
1066            }
1067
1068            for e in &group_entities {
1069                let eid = e.id();
1070                let old_loc = self.entity_locations[eid as usize];
1071                
1072                let (new_row, moved_eid) = unsafe {
1073                    let old_arch_ptr = &mut self.archetype_index.archetypes[source_arch_id as usize] as *mut Archetype;
1074                    let target_arch_ptr = &mut self.archetype_index.archetypes[target_arch_id] as *mut Archetype;
1075                    (&mut *old_arch_ptr).move_entity_to(old_loc.row as usize, &mut *target_arch_ptr)
1076                };
1077
1078                if let Some(moved) = moved_eid {
1079                    self.entity_locations[moved as usize].row = old_loc.row;
1080                }
1081
1082                self.entity_locations[eid as usize] = EntityLocation {
1083                    archetype_id: target_arch_id as u32,
1084                    row: new_row,
1085                };
1086                self.archetype_index.entity_archetype.insert(eid, target_arch_id);
1087            }
1088
1089            self.run_hooks(type_id, |h, w| {
1090                for e in &group_entities {
1091                    for hook in &mut h.on_remove { hook(w, *e); }
1092                }
1093            });
1094        }
1095    }
1096
1097    pub fn query_entity_mut<'w, Q: crate::query::WorldQuery>(
1098        &'w mut self,
1099        entity_id: u32,
1100    ) -> Option<Q::Item<'w>> {
1101        let loc = self.entity_location(entity_id);
1102        if !loc.is_valid() {
1103            return None;
1104        }
1105        let arch = &self.archetype_index.archetypes[loc.archetype_id as usize];
1106        if !Q::matches_archetype(arch) {
1107            return None;
1108        }
1109        unsafe {
1110            let fetch = Q::fetch_raw(self, arch, self.tick)?;
1111            if !Q::filter_row(fetch, loc.row as usize, entity_id, self.tick) {
1112                return None;
1113            }
1114            Some(Q::get_item(fetch, loc.row as usize, entity_id))
1115        }
1116    }
1117
1118    /// Tek bir entity üzerinde read-only `Query` çalıştırıp anında sonuç almanızı sağlar.
1119    pub fn query_entity<'w, Q: crate::query::WorldQuery>(
1120        &'w self,
1121        entity_id: u32,
1122    ) -> Option<Q::Item<'w>> {
1123        let loc = self.entity_location(entity_id);
1124        if !loc.is_valid() {
1125            return None;
1126        }
1127        let arch = &self.archetype_index.archetypes[loc.archetype_id as usize];
1128        if !Q::matches_archetype(arch) {
1129            return None;
1130        }
1131        unsafe {
1132            let fetch = Q::fetch_raw(self, arch, self.tick)?;
1133            if !Q::filter_row(fetch, loc.row as usize, entity_id, self.tick) {
1134                return None;
1135            }
1136            Some(Q::get_item(fetch, loc.row as usize, entity_id))
1137        }
1138    }
1139
1140    /// Entity'nin archetype konumunu döndürür — O(1) lookup.
1141    #[inline]
1142    pub fn entity_location(&self, entity_id: u32) -> EntityLocation {
1143        let loc_idx = entity_id as usize;
1144        if loc_idx < self.entity_locations.len() {
1145            self.entity_locations[loc_idx]
1146        } else {
1147            EntityLocation::INVALID
1148        }
1149    }
1150
1151    /// Toplam yaşayan entity sayısı
1152    #[inline]
1153    pub fn entity_count(&self) -> u32 {
1154        let entities = self
1155            .get_resource::<Entities>()
1156            .expect("Entities resource not initialized");
1157        let state = entities.state.lock().expect("Entities mutex poisoned");
1158        state
1159            .next_entity_id
1160            .saturating_sub(state.free_ids.len() as u32)
1161    }
1162
1163    // ==========================================================
1164    // RESOURCE SİSTEMİ (GLOBAL VERİLER)
1165    // ==========================================================
1166
1167    /// Sisteme global bir Resource ekler veya üzerine yazar.
1168    pub fn insert_resource<T: Send + Sync + 'static>(&mut self, resource: T) {
1169        let type_id = TypeId::of::<T>();
1170        self.resources
1171            .insert(type_id, RwLock::new(Box::new(resource)));
1172    }
1173
1174    /// Global bir Resource'u okumak için çağrılır (Immutable Borrow)
1175    pub fn get_resource<T: 'static>(&self) -> Option<ResourceReadGuard<'_, T>> {
1176        self.try_get_resource::<T>().ok()
1177    }
1178
1179    /// Global bir Resource'u değiştirmek için çağrılır (Mutable Borrow)
1180    pub fn get_resource_mut<T: 'static>(&self) -> Option<ResourceWriteGuard<'_, T>> {
1181        self.try_get_resource_mut::<T>().ok()
1182    }
1183
1184    /// `get_resource` ile aynı işlev, ama hata sebebini `Result` ile taşır.
1185    pub fn try_get_resource<T: 'static>(
1186        &self,
1187    ) -> Result<ResourceReadGuard<'_, T>, ResourceFetchError> {
1188        let type_id = TypeId::of::<T>();
1189        let storage = self
1190            .resources
1191            .get(&type_id)
1192            .ok_or(ResourceFetchError::NotFound(type_id))?;
1193        let guard = storage
1194            .try_read()
1195            .map_err(|_| ResourceFetchError::BorrowConflict(type_id))?;
1196        Ok(ResourceReadGuard {
1197            guard,
1198            _marker: PhantomData,
1199        })
1200    }
1201
1202    /// `get_resource_mut` ile aynı işlev, ama hata sebebini `Result` ile taşır.
1203    pub fn try_get_resource_mut<T: 'static>(
1204        &self,
1205    ) -> Result<ResourceWriteGuard<'_, T>, ResourceFetchError> {
1206        let type_id = TypeId::of::<T>();
1207        let storage = self
1208            .resources
1209            .get(&type_id)
1210            .ok_or(ResourceFetchError::NotFound(type_id))?;
1211        let guard = storage
1212            .try_write()
1213            .map_err(|_| ResourceFetchError::BorrowConflict(type_id))?;
1214        Ok(ResourceWriteGuard {
1215            guard,
1216            _marker: PhantomData,
1217        })
1218    }
1219
1220    /// Global bir Resource yoksa Default olarak oluşturur, ardından Mutable Borrow döndürür.
1221    /// World mutable borrow gerektirir, böylece hashmap'e güvenle kayıt yapılabilir.
1222    pub fn get_resource_mut_or_default<T: Default + Send + Sync + 'static>(
1223        &mut self,
1224    ) -> ResourceWriteGuard<'_, T> {
1225        let type_id = TypeId::of::<T>();
1226        self.resources
1227            .entry(type_id)
1228            .or_insert_with(|| RwLock::new(Box::new(T::default())));
1229
1230        let storage = self
1231            .resources
1232            .get(&type_id)
1233            .expect("resource just inserted");
1234        let guard = storage.write().expect("resource write lock poisoned");
1235        ResourceWriteGuard {
1236            guard,
1237            _marker: PhantomData,
1238        }
1239    }
1240
1241    /// Global bir Resource'u ECS'ten tamamen çıkartır ve sahipliğini döndürür
1242    pub fn remove_resource<T: 'static>(&mut self) -> Option<T> {
1243        let type_id = TypeId::of::<T>();
1244        let cell = self.resources.remove(&type_id)?;
1245        let boxed_any = cell.into_inner().ok()?;
1246        match boxed_any.downcast::<T>() {
1247            Ok(boxed_t) => Some(*boxed_t),
1248            Err(_) => None,
1249        }
1250    }
1251
1252    /// Bir resource'u geçici olarak world'den çıkarıp closure'a geçirir ve sonra geri koyar.
1253    /// Bu, resource'un içindeyken `&mut World` kullanmanız gerektiğinde borrow checker'ı
1254    /// mutlu etmenin en temiz yoludur (Bevy'deki `resource_scope` benzeri).
1255    ///
1256    /// # Örnek
1257    /// ```ignore
1258    /// world.resource_scope::<PoolManager, ()>(|world, pool| {
1259    ///     pool.instantiate(world, "enemy");
1260    /// });
1261    /// ```
1262    pub fn resource_scope<T: Send + Sync + 'static, U, F>(&mut self, f: F) -> Option<U>
1263    where
1264        F: FnOnce(&mut World, &mut T) -> U,
1265    {
1266        let resource = self.remove_resource::<T>()?;
1267
1268        // Panic güvenliği: Closure panic yaparsa bile resource geri yerleştirilir.
1269        // Drop guard, stack unwind sırasında resource'u tekrar world'e koyar.
1270        struct Guard<'a, T: Send + Sync + 'static> {
1271            world: *mut World,
1272            resource: Option<T>,
1273            _marker: std::marker::PhantomData<&'a mut World>,
1274        }
1275        impl<'a, T: Send + Sync + 'static> Drop for Guard<'a, T> {
1276            fn drop(&mut self) {
1277                if let Some(resource) = self.resource.take() {
1278                    // SAFETY: self.world is valid for the lifetime of the Guard.
1279                    unsafe { &mut *self.world }.insert_resource(resource);
1280                }
1281            }
1282        }
1283
1284        let mut guard = Guard::<T> {
1285            world: self as *mut World,
1286            resource: Some(resource),
1287            _marker: std::marker::PhantomData,
1288        };
1289
1290        let result = f(self, guard.resource.as_mut().unwrap());
1291
1292        // Normal dönüş: guard.drop() resource'u geri koyacak.
1293        Some(result)
1294    }
1295
1296    /// Belirli bir Archetype içindeki iki satırı güvenli bir şekilde takaslar ve entity lokasyonlarını günceller.
1297    pub fn swap_archetype_rows(&mut self, arch_id: u32, row_a: usize, row_b: usize) {
1298        if row_a == row_b {
1299            return;
1300        }
1301
1302        let arch = &self.archetype_index.archetypes[arch_id as usize];
1303        if row_a >= arch.len() || row_b >= arch.len() {
1304            return;
1305        }
1306
1307        let entity_a = arch.entities()[row_a];
1308        let entity_b = arch.entities()[row_b];
1309
1310        unsafe {
1311            let mut_arch = &mut self.archetype_index.archetypes[arch_id as usize];
1312            mut_arch.swap_rows(row_a, row_b);
1313        }
1314
1315        self.entity_locations[entity_a as usize].row = row_b as u32;
1316        self.entity_locations[entity_b as usize].row = row_a as u32;
1317    }
1318
1319    /// Aynı archetype'da bulunan ebeveyn ve çocuk düğümleri bellekte sırt sırta verecek şekilde kümelendirir. O(N) cache swap.
1320    pub fn sort_archetype_hierarchy(&mut self) {
1321        let type_id = std::any::TypeId::of::<crate::component::Children>();
1322        let mut arches_to_sort: Vec<usize> = Vec::new();
1323
1324        for (idx, arch) in self.archetype_index.archetypes.iter().enumerate() {
1325            if arch.has_component(type_id) {
1326                arches_to_sort.push(idx);
1327            }
1328        }
1329
1330        for arch_idx in arches_to_sort {
1331            let arch_len = self.archetype_index.archetypes[arch_idx].len();
1332            if arch_len <= 1 {
1333                continue;
1334            }
1335
1336            let mut visited = std::collections::HashSet::new();
1337
1338            for row in 0..arch_len {
1339                let parent_entity_id = self.archetype_index.archetypes[arch_idx].entities()[row];
1340
1341                if visited.contains(&parent_entity_id) {
1342                    continue;
1343                }
1344                visited.insert(parent_entity_id);
1345
1346                let children_opt = {
1347                    let fetch = unsafe {
1348                        <&crate::component::Children as crate::query::FetchComponent>::fetch_raw(self, &self.archetype_index.archetypes[arch_idx], self.tick)
1349                    };
1350                    fetch.map(|f| unsafe {
1351                        <&crate::component::Children as crate::query::FetchComponent>::get_item(f, row, parent_entity_id)
1352                    })
1353                };
1354
1355                let children_list = match children_opt {
1356                    Some(c) => c.0.clone(),
1357                    None => continue,
1358                };
1359
1360                let mut current_insert_row = row + 1;
1361                for child_id in children_list {
1362                    let loc = self.entity_location(child_id);
1363                    if loc.is_valid() && loc.archetype_id == arch_idx as u32 {
1364                        let child_row = loc.row as usize;
1365                        if child_row > current_insert_row {
1366                            self.swap_archetype_rows(
1367                                arch_idx as u32,
1368                                current_insert_row,
1369                                child_row,
1370                            );
1371                            visited.insert(child_id);
1372                            current_insert_row += 1;
1373                        } else if child_row == current_insert_row {
1374                            visited.insert(child_id);
1375                            current_insert_row += 1;
1376                        }
1377                    }
1378                }
1379            }
1380        }
1381    }
1382}
1383
1384#[cfg(test)]
1385mod tests {
1386    use super::*;
1387    use crate::component::Children;
1388
1389    #[derive(Clone, PartialEq, Debug)]
1390    struct Transform(f32);
1391    impl crate::component::Component for Transform {}
1392
1393    #[test]
1394    fn test_sort_archetype_hierarchy() {
1395        let mut world = World::new();
1396
1397        // 5 entity oluşturalım: e0, e1, e2, e3, e4
1398        let e0 = world.spawn();
1399        let e1 = world.spawn();
1400        let e2 = world.spawn();
1401        let e3 = world.spawn();
1402        let e4 = world.spawn();
1403
1404        // Hepsi aynı bileşenlere sahip olsun (aynı archetype'a girmeleri için)
1405        // Sırasıyla Transform ekliyoruz:
1406        world.add_component(e0, Transform(0.0));
1407        world.add_component(e1, Transform(1.0));
1408        world.add_component(e2, Transform(2.0));
1409        world.add_component(e3, Transform(3.0));
1410        world.add_component(e4, Transform(4.0));
1411
1412        // Hiyerarşi kuralım: e0'ın çocukları e3 ve e4 olsun.
1413        // Başlangıçta e0(0), e1(1), e2(2), e3(3), e4(4) sırasıyla dizilidir.
1414        world.add_component(e0, Children(vec![e3.id(), e4.id()]));
1415
1416        // Sadece e0'da Children olunca farklı archetype'a geçer (Archetype değişimi).
1417        // Bu yüzden hepsine Children eklemeliyiz ki AYNI archetype'da kalsınlar.
1418        world.add_component(e1, Children(vec![]));
1419        world.add_component(e2, Children(vec![]));
1420        world.add_component(e3, Children(vec![]));
1421        world.add_component(e4, Children(vec![]));
1422
1423        // Şu an hepsi (Transform, Children) archetype'ında.
1424        // Beklenen indeksler: e0, e1, e2, e3, e4.
1425
1426        // Hiyerarşi kaydırmasını çalıştır!
1427        world.sort_archetype_hierarchy();
1428
1429        // Kontrol edelim. e0'dan hemen sonra e3 ve e4 gelmeli.
1430        let loc0 = world.entity_location(e0.id());
1431        let loc3 = world.entity_location(e3.id());
1432        let loc4 = world.entity_location(e4.id());
1433
1434        assert_eq!(
1435            loc0.row + 1,
1436            loc3.row,
1437            "e3 (child), e0 (parent)'dan hemen sonra gelmeli"
1438        );
1439        assert_eq!(
1440            loc0.row + 2,
1441            loc4.row,
1442            "e4 (child), e3'ten hemen sonra gelmeli"
1443        );
1444
1445        // Diğerleri (e1 ve e2) kaydırılmış olmalı.
1446        let loc1 = world.entity_location(e1.id());
1447        let loc2 = world.entity_location(e2.id());
1448        assert!(
1449            loc1.row > loc4.row || loc2.row > loc4.row,
1450            "Bağımsız entityler sona itilmeli"
1451        );
1452    }
1453
1454    #[test]
1455    fn test_sort_archetype_hierarchy_deep() {
1456        let mut world = World::new();
1457
1458        let e0 = world.spawn();
1459        let e1 = world.spawn();
1460        let e2 = world.spawn();
1461        let e3 = world.spawn();
1462
1463        world.add_component(e0, Transform(0.0));
1464        world.add_component(e1, Transform(1.0));
1465        world.add_component(e2, Transform(2.0));
1466        world.add_component(e3, Transform(3.0));
1467
1468        // e0 -> e1 -> e2 -> e3 zinciri
1469        world.add_component(e0, Children(vec![e1.id()]));
1470        world.add_component(e1, Children(vec![e2.id()]));
1471        world.add_component(e2, Children(vec![e3.id()]));
1472        world.add_component(e3, Children(vec![]));
1473
1474        world.sort_archetype_hierarchy();
1475
1476        let l0 = world.entity_location(e0.id());
1477        let l1 = world.entity_location(e1.id());
1478        let l2 = world.entity_location(e2.id());
1479        let l3 = world.entity_location(e3.id());
1480
1481        assert_eq!(l0.row + 1, l1.row);
1482        // Not: Algoritma şu an sadece doğrudan çocukları hemen arkasına koyar.
1483        // e1 işlendiğinde e2 onun arkasına geçer, e2 işlendiğinde e3 onun arkasına geçer.
1484        // Sonuçta e0, e1, e2, e3 dizilimi kendiliğinden oluşur (visited mantığı).
1485        assert_eq!(l1.row + 1, l2.row);
1486        assert_eq!(l2.row + 1, l3.row);
1487    }
1488
1489
1490    #[test]
1491    fn spawn_despawn_generation() {
1492        let mut world = World::new();
1493        let e1 = world.spawn();
1494        world.despawn(e1);
1495        
1496        let e2 = world.spawn(); // aynı id, farklı generation
1497        assert_eq!(e1.id(), e2.id());
1498        assert_ne!(e1.generation(), e2.generation());
1499        
1500        // Eski handle artık geçersiz
1501        assert!(!world.is_alive(e1));
1502        assert!(world.is_alive(e2));
1503    }
1504
1505    #[test]
1506    fn despawn_updates_swapped_entity_location() {
1507        #[derive(Clone)]
1508        struct TestComp(i32);
1509        impl crate::component::Component for TestComp {}
1510
1511        let mut world = World::new();
1512        world.register_component_type::<TestComp>();
1513        
1514        let e1 = world.spawn(); world.add_component(e1, TestComp(1));
1515        let e2 = world.spawn(); world.add_component(e2, TestComp(2));
1516        let e3 = world.spawn(); world.add_component(e3, TestComp(3));
1517        
1518        // e2'yi despawn et — e3 onun yerine swap_remove ile gelir
1519        world.despawn(e2);
1520        
1521        // e3 hâlâ erişilebilir olmalı
1522        let comps = world.borrow::<TestComp>();
1523        let val = comps.get(e3.id()).unwrap();
1524        assert_eq!(val.0, 3);
1525    }
1526
1527    #[test]
1528    fn add_component_migrates_archetype() {
1529        #[derive(Clone, Debug, PartialEq)]
1530        struct TestCompI32(i32);
1531        impl crate::component::Component for TestCompI32 {}
1532
1533        #[derive(Clone, Debug, PartialEq)]
1534        struct TestCompF32(f32);
1535        impl crate::component::Component for TestCompF32 {}
1536
1537        let mut world = World::new();
1538        world.register_component_type::<TestCompI32>();
1539        world.register_component_type::<TestCompF32>();
1540        
1541        let e = world.spawn();
1542        world.add_component(e, TestCompI32(10));
1543        
1544        let loc1 = world.entity_location(e.id());
1545        
1546        world.add_component(e, TestCompF32(3.14));
1547        
1548        let loc2 = world.entity_location(e.id());
1549        assert_ne!(loc1.archetype_id, loc2.archetype_id);
1550        
1551        assert_eq!(world.borrow::<TestCompI32>().get(e.id()).unwrap().0, 10);
1552        assert_eq!(world.borrow::<TestCompF32>().get(e.id()).unwrap().0, 3.14);
1553    }
1554
1555    #[test]
1556    fn add_same_component_overwrites() {
1557        #[derive(Clone, Debug, PartialEq)]
1558        struct TestCompI32(i32);
1559        impl crate::component::Component for TestCompI32 {}
1560
1561        let mut world = World::new();
1562        world.register_component_type::<TestCompI32>();
1563        
1564        let e = world.spawn();
1565        world.add_component(e, TestCompI32(1));
1566        world.add_component(e, TestCompI32(99)); // overwrite
1567        
1568        assert_eq!(world.borrow::<TestCompI32>().get(e.id()).unwrap().0, 99);
1569    }
1570
1571    #[test]
1572    fn archetype_graph_reuses_archetypes() {
1573        #[derive(Clone, Debug, PartialEq)]
1574        struct TestCompI32(i32);
1575        impl crate::component::Component for TestCompI32 {}
1576
1577        #[derive(Clone, Debug, PartialEq)]
1578        struct TestCompF32(f32);
1579        impl crate::component::Component for TestCompF32 {}
1580
1581        let mut world = World::new();
1582        world.register_component_type::<TestCompI32>();
1583        world.register_component_type::<TestCompF32>();
1584        
1585        let e1 = world.spawn(); world.add_component(e1, TestCompI32(1)); world.add_component(e1, TestCompF32(1.0));
1586        let e2 = world.spawn(); world.add_component(e2, TestCompI32(2)); world.add_component(e2, TestCompF32(2.0));
1587        
1588        let loc1 = world.entity_location(e1.id());
1589        let loc2 = world.entity_location(e2.id());
1590        assert_eq!(loc1.archetype_id, loc2.archetype_id);
1591        
1592        assert!(world.archetype_index.archetypes.len() < 5);
1593    }
1594
1595    #[test]
1596    fn query_finds_matching_archetypes() {
1597        #[derive(Clone)]
1598        struct TestCompI32(i32);
1599        impl crate::component::Component for TestCompI32 {}
1600
1601        #[derive(Clone)]
1602        struct TestCompF32(f32);
1603        impl crate::component::Component for TestCompF32 {}
1604
1605        #[derive(Clone)]
1606        struct TestCompBool(bool);
1607        impl crate::component::Component for TestCompBool {}
1608
1609        let mut world = World::new();
1610        world.register_component_type::<TestCompI32>();
1611        world.register_component_type::<TestCompF32>();
1612        world.register_component_type::<TestCompBool>();
1613        
1614        let e1 = world.spawn(); world.add_component(e1, TestCompI32(1)); world.add_component(e1, TestCompF32(1.0));
1615        let e2 = world.spawn(); world.add_component(e2, TestCompI32(2)); world.add_component(e2, TestCompBool(true));
1616        let e3 = world.spawn(); world.add_component(e3, TestCompI32(3)); // sadece i32
1617        
1618        // i32 query'si 3 entity'yi de bulmalı
1619        let count = world.query::<&TestCompI32>().unwrap().iter().count();
1620        assert_eq!(count, 3);
1621        
1622        // (i32, f32) query'si sadece e1'i bulmalı
1623        let count = world.query::<(&TestCompI32, &TestCompF32)>().unwrap().iter().count();
1624        assert_eq!(count, 1);
1625    }
1626
1627    #[test]
1628    fn query_mut_modifies_data() {
1629        #[derive(Clone)]
1630        struct TestCompI32(i32);
1631        impl crate::component::Component for TestCompI32 {}
1632
1633        let mut world = World::new();
1634        world.register_component_type::<TestCompI32>();
1635        
1636        let e1 = world.spawn(); world.add_component(e1, TestCompI32(1));
1637        let e2 = world.spawn(); world.add_component(e2, TestCompI32(2));
1638        
1639        // Query ile tüm i32'leri iki katına çıkar
1640        if let Some(mut q) = world.query::<crate::query::Mut<TestCompI32>>() {
1641            for (_, mut val) in q.iter_mut() {
1642                val.0 *= 2;
1643            }
1644        }
1645        
1646        assert_eq!(world.borrow::<TestCompI32>().get(e1.id()).unwrap().0, 2);
1647        assert_eq!(world.borrow::<TestCompI32>().get(e2.id()).unwrap().0, 4);
1648    }
1649
1650    #[test]
1651    fn query_skips_non_matching() {
1652        #[derive(Clone)]
1653        struct CompA;
1654        impl crate::component::Component for CompA {}
1655        #[derive(Clone)]
1656        struct CompB;
1657        impl crate::component::Component for CompB {}
1658
1659        let mut world = World::new();
1660        world.register_component_type::<CompA>();
1661        world.register_component_type::<CompB>();
1662
1663        for _ in 0..100 {
1664            let e = world.spawn();
1665            world.add_component(e, CompA);
1666        }
1667
1668        for _ in 0..50 {
1669            let e = world.spawn();
1670            world.add_component(e, CompB);
1671        }
1672
1673        let a_count = world.query::<&CompA>().unwrap().iter().count();
1674        let b_count = world.query::<&CompB>().unwrap().iter().count();
1675        let both_count = world.query::<(&CompA, &CompB)>().unwrap().iter().count();
1676
1677        assert_eq!(a_count, 100);
1678        assert_eq!(b_count, 50);
1679        assert_eq!(both_count, 0);
1680    }
1681
1682    #[test]
1683    fn spawn_despawn_10k_entities_archetype_stability() {
1684        #[derive(Clone)]
1685        struct CompA(i32);
1686        impl crate::component::Component for CompA {}
1687        #[derive(Clone)]
1688        struct CompB(f32);
1689        impl crate::component::Component for CompB {}
1690
1691        let mut world = World::new();
1692        world.register_component_type::<CompA>();
1693        world.register_component_type::<CompB>();
1694
1695        let initial_archetypes = world.archetype_index.archetypes.len();
1696
1697        // Spawn 10k entities
1698        let mut entities = Vec::new();
1699        for i in 0..10_000 {
1700            let e = world.spawn();
1701            world.add_component(e, CompA(i as i32));
1702            if i % 2 == 0 {
1703                world.add_component(e, CompB(i as f32));
1704            }
1705            entities.push(e);
1706        }
1707
1708        // Despawn all
1709        for e in entities {
1710            world.despawn(e);
1711        }
1712
1713        // Archetype sayısı aynı kalmalı
1714        let final_archetypes = world.archetype_index.archetypes.len();
1715        // 1 empty, 1 for CompA, 1 for (CompA, CompB) = 3 total usually.
1716        assert!(final_archetypes <= initial_archetypes + 2);
1717    }
1718}