#include "fiko/cekirdek/urun_agaci.hpp" #include #include #include #include "fiko/cekirdek/cekirdek.hpp" namespace fiko { namespace { // Bir varlik icin rekursif AgacDugum insa eder. cocukHarita: ust -> [cocuklar]. AgacDugum dugumKur(Cekirdek& c, Varlik v, const std::unordered_map>& cocukHarita) { AgacDugum n; n.varlik = v; if (DokumanNesnesi* obj = c.nesne(v)) n.etiket = obj->ad(); auto it = cocukHarita.find(v); if (it != cocukHarita.end()) for (Varlik cv : it->second) n.cocuklar.push_back(dugumKur(c, cv, cocukHarita)); // Sanal alt-öğeler (CATIA sketch: AbsoluteAxis/Geometry/Constraints). View provider // ECS-olmayan sunum düğümlerini ekler; ECS çocuklarından SONRA gelir. if (GorunumSaglayici* gv = c.gorunum(v)) gv->agacSanalCocuklar(c.dunya(), n.cocuklar); return n; } } // namespace void urunAgaciTopla(Cekirdek& c, std::vector& kok) { Dunya& d = c.dunya(); // NesneKok'u olan TUM varliklari dugum adayi say (deterministik: kimlige gore). std::vector adaylar; { const Depo& nesneler = d.depo(); adaylar.reserve(nesneler.boyut()); for (size_t i = 0; i < nesneler.boyut(); ++i) adaylar.push_back(nesneler.varlikAt(i)); } std::sort(adaylar.begin(), adaylar.end()); // Aday uyelik kumesi (O(1) ebeveyn-gecerlilik testi). Bir varligin ust'u bu // kumede DEGILSE ebeveyn ya olu (silinmis grup) ya da agac-disi → YETIM. std::unordered_set gecerli(adaylar.begin(), adaylar.end()); // ust -> [cocuklar] haritasi (O(n)) + kokleri belirle. YETIM toplama kritik: // ust!=YOK ama ust agacta yoksa (silinmis grup / bilesen-siz varlik) dugum eski // kodda SESSIZCE KAYBOLURDU (ne kok ne cocuk). CATIA: sahnedeki hicbir oge agactan // gizli kalamaz → bunlar "Diger" grubu altinda toplanir. std::unordered_map> cocukHarita; std::vector kokler; std::vector yetimler; for (Varlik v : adaylar) { const HiyerarsiBilesen* h = d.bul(v); const Varlik ust = h ? h->ust : VARLIK_YOK; if (ust == VARLIK_YOK) kokler.push_back(v); else if (gecerli.count(ust)) cocukHarita[ust].push_back(v); // gecerli ebeveyn → normal cocuk else yetimler.push_back(v); // ebeveyn olu/agac-disi → yetim } // Kardesleri kullanici-sirasina gore diz: (sira, kimlik). sira=0 varsayilan → // dokunulmamis dugumler eskisi gibi kimlik sirasinda; surukle-birak sira atayinca // o deger belirler. Tie-break kimlik → determinism korunur (ayni sira icinde). auto kardesSirala = [&](std::vector& v) { std::sort(v.begin(), v.end(), [&](Varlik a, Varlik b) { const HiyerarsiBilesen* ha = d.bul(a); const HiyerarsiBilesen* hb = d.bul(b); const int sa = ha ? ha->sira : 0, sb = hb ? hb->sira : 0; return sa != sb ? sa < sb : a < b; }); }; kardesSirala(kokler); for (auto& [ust, cocuklar] : cocukHarita) kardesSirala(cocuklar); for (Varlik v : kokler) kok.push_back(dugumKur(c, v, cocukHarita)); // Yetimler görünür bir "Diğer" grubu altında toplanır (SANAL düğüm: varlik=YOK → // yalnız kap; alt öğeleri gerçek ECS düğümleri, kendi ikon/menü/görünürlüğüyle). // Her yetim kendi alt ağacını da getirir (cocukHarita yetimin altını da içerir). if (!yetimler.empty()) { AgacDugum diger; diger.etiket = "Diğer"; diger.simge = "📦"; diger.arketip = Arketip::Grup; diger.cocuklar.reserve(yetimler.size()); for (Varlik v : yetimler) diger.cocuklar.push_back(dugumKur(c, v, cocukHarita)); kok.push_back(std::move(diger)); } } } // namespace fiko