// kinematikAgacTopla — mekanizma → Ürün Ağacı düğümleri (ImGui'siz saf dönüşüm). // Ağaç dalı bozulursa mekanizma kullanıcıya GÖRÜNMEZ olur; uzuv düğümünün sahne // bağı (varlik) kopunca ağaçtan seçim sahnede parçayı seçmez. #include #include #include "fiko/kinematik/mekanizma.hpp" #include "fiko_test.hpp" #include "kinematik_agac.hpp" using namespace fiko; namespace { // Sağlayıcı imzası Cekirdek& ister ama kinematik dalı çekirdeğe DOKUNMAZ // (parametre kullanılmıyor) — testte hiç erişilmeyen bir yer tutucu geçilir. Cekirdek& sahteCekirdek() { alignas(8) static unsigned char yer[8]; return *reinterpret_cast(yer); } // Uygulamanın gerçek kurulumu: GÖVDE uzvunu çağıran ekler (fiko.kinematik.sifirla). kinematik::Mekanizma govdeli() { kinematik::Mekanizma m; m.uzuvEkle("Gövde"); return m; } const AgacDugum* cocukBul(const AgacDugum& d, const char* etiket) { for (const AgacDugum& c : d.cocuklar) if (c.etiket == etiket) return &c; return nullptr; } } // namespace FIKO_TEST(kinematik_agac_bos_mekanizma_dal_eklemez) { kinematik::Mekanizma bos; std::vector kok; kinematikAgacTopla(sahteCekirdek(), bos, kok); FIKO_KONTROL(kok.empty()); // ağaç temiz kalmalı kinematik::Mekanizma mek = govdeli(); // yalnız GÖVDE → yine dal yok kinematikAgacTopla(sahteCekirdek(), mek, kok); FIKO_KONTROL(kok.empty()); } FIKO_TEST(kinematik_agac_uzuv_mafsal_dugumleri) { kinematik::Mekanizma mek = govdeli(); const std::size_t uK = mek.uzuvEkle("Krank", 42); const std::size_t uB = mek.uzuvEkle("Biyel", 43); kinematik::Mafsal m1; m1.tip = kinematik::MafsalTip::Doner; m1.ana = 0; m1.cocuk = uK; mek.mafsalEkle(m1); kinematik::Mafsal m2; m2.tip = kinematik::MafsalTip::Doner; m2.ana = uK; m2.cocuk = uB; mek.mafsalEkle(m2); std::vector kok; kinematikAgacTopla(sahteCekirdek(), mek, kok); FIKO_KONTROL(kok.size() == 1u); if (kok.empty()) return; const AgacDugum& g = kok[0]; FIKO_KONTROL(g.etiket.rfind("Mekanizma (DOF ", 0) == 0); FIKO_KONTROL(g.arketip == Arketip::Grup); FIKO_KONTROL(g.cocuklar.size() == 2u); // Uzuvlar + Mafsallar const AgacDugum* gu = cocukBul(g, "Uzuvlar"); FIKO_KONTROL(gu != nullptr); FIKO_KONTROL(gu && gu->cocuklar.size() == 2u); // GÖVDE ağaçta YOK FIKO_KONTROL(gu && gu->cocuklar[0].etiket == "Krank"); FIKO_KONTROL(gu && (u32)gu->cocuklar[0].varlik == 42u); // sahne bağı → seçilebilir FIKO_KONTROL(gu && (u32)gu->cocuklar[1].varlik == 43u); const AgacDugum* gm = cocukBul(g, "Mafsallar"); FIKO_KONTROL(gm != nullptr); FIKO_KONTROL(gm && gm->cocuklar.size() == 2u); FIKO_KONTROL(gm && gm->cocuklar[0].etiket.find("Krank") != std::string::npos); FIKO_KONTROL(gm && gm->cocuklar[0].etiket.find("Gövde") != std::string::npos); FIKO_KONTROL(gm && gm->cocuklar[1].etiket.find("Biyel") != std::string::npos); FIKO_KONTROL(gm && gm->cocuklar[0].camKimlik == 1u); // indeks+1 (0 = "yok" değil) } // GÖVDE uzvunu ÇAĞIRAN ekler; eklemeyi unutan bir kurulumda indeks 0 GERÇEK parçadır // ve ağaçtan SİLİNMEMELİDİR (ölçüldü 07-21: körlemesine "0'ı atla" ilk parçayı yutuyordu). FIKO_TEST(kinematik_agac_govdesiz_kurulumda_ilk_parca_gorunur) { kinematik::Mekanizma mek; mek.uzuvEkle("Krank", 42); // gövde YOK → indeks 0 gerçek parça std::vector kok; kinematikAgacTopla(sahteCekirdek(), mek, kok); FIKO_KONTROL(kok.size() == 1u); if (kok.empty()) return; const AgacDugum* gu = cocukBul(kok[0], "Uzuvlar"); FIKO_KONTROL(gu != nullptr); FIKO_KONTROL(gu && gu->cocuklar.size() == 1u); FIKO_KONTROL(gu && gu->cocuklar[0].etiket == "Krank"); FIKO_KONTROL(gu && (u32)gu->cocuklar[0].varlik == 42u); } FIKO_TEST(kinematik_agac_bagsiz_uzuv_sanal_kalir) { kinematik::Mekanizma mek = govdeli(); mek.uzuvEkle("Serbest", 0); // sahne bağı yok std::vector kok; kinematikAgacTopla(sahteCekirdek(), mek, kok); FIKO_KONTROL(kok.size() == 1u); if (kok.empty()) return; const AgacDugum* gu = cocukBul(kok[0], "Uzuvlar"); FIKO_KONTROL(gu != nullptr); FIKO_KONTROL(gu && gu->cocuklar[0].varlik == VARLIK_YOK); FIKO_KONTROL(gu && gu->cocuklar[0].camKimlik == 1u); // disambiguator = uzuv indeksi } FIKO_TEST(kinematik_agac_adsiz_uzuv_varsayilan_etiket) { kinematik::Mekanizma mek = govdeli(); mek.uzuvEkle("", 7); std::vector kok; kinematikAgacTopla(sahteCekirdek(), mek, kok); FIKO_KONTROL(kok.size() == 1u); if (kok.empty()) return; const AgacDugum* gu = cocukBul(kok[0], "Uzuvlar"); FIKO_KONTROL(gu != nullptr); FIKO_KONTROL(gu && gu->cocuklar[0].etiket == "Uzuv.1"); }