// Pafta (teknik resim) sahne düğümü — Vulkan gerektirmez: Dunya + Dugum/NesneKok // üzerinden veri erişimi, ağaç sağlayıcı çıktısı ve bağımlılık (recompute DAG) doğrulanır. #include #include #include "fiko/cekirdek/nesne.hpp" #include "fiko/sahne/pafta_nesne.hpp" #include "fiko/sahne/sahne_islem.hpp" #include "fiko_test.hpp" using namespace fiko; namespace { bool icerir(const std::string& s, const char* alt) { return s.find(alt) != std::string::npos; } // Pafta düğümünü Sahne'siz kur (Sahne::paftaEkle ile aynı bileşen kümesi). Varlik paftaDugumEkle(Dunya& d) { const Varlik v = d.olustur(); Dugum dg; dg.kimlik = (u32)v; dg.tip = DugumTip::Pafta; dg.ad = "Teknik Resim"; dg.gorunur = false; d.ekle(v, std::move(dg)); d.ekle(v, std::make_unique(v, &d)); d.ekle(v, std::make_unique(v, &d)); return v; } } // namespace FIKO_TEST(pafta_dugum_veri_erisimi) { Dunya d; const Varlik p = paftaDugumEkle(d); pafta::Pafta* v = paftaVerisi(d, p); FIKO_KONTROL(v != nullptr); FIKO_KONTROL(v->sayi() == 0); // Pafta olmayan düğümde nullptr (yanlış dynamic_cast çökmez). const Varlik bos = d.olustur(); FIKO_KONTROL(paftaVerisi(d, bos) == nullptr); } FIKO_TEST(pafta_dugum_agac_bilgisi) { Dunya d; const Varlik p = paftaDugumEkle(d); PaftaGorunum g(p, &d); FIKO_KONTROL(!g.gorunur()); // 3B sahnede çizilmez FIKO_KONTROL(std::string(g.agacSimgesi()) == "📐"); // Boş pafta: "boş" rozeti + mini bilgide sayfa/ölçek. std::vector roz; g.agacRozetleri(d, roz); FIKO_KONTROL(roz.size() == 1 && roz[0].metin == "boş"); const std::string mini = g.agacMiniBilgi(d); FIKO_KONTROL(icerir(mini, "A3") && icerir(mini, "1:1") && icerir(mini, "0 görünüm")); // Üç görünüm kurulunca: sanal çocuklar + ölçek rozeti. paftaVerisi(d, p)->ucGorunumKur(7, 100, 60, 40); std::vector cocuk; g.agacSanalCocuklar(d, cocuk); FIKO_KONTROL(cocuk.size() == 3); FIKO_KONTROL(icerir(cocuk[0].etiket, "Ön")); FIKO_KONTROL(cocuk[0].camKimlik == p); roz.clear(); g.agacRozetleri(d, roz); FIKO_KONTROL(roz.size() == 1 && roz[0].metin != "boş"); FIKO_KONTROL(icerir(g.agacMiniBilgi(d), "3 görünüm")); } FIKO_TEST(pafta_dugum_bagimliliklar_tekil) { Dunya d; const Varlik p = paftaDugumEkle(d); pafta::Pafta* v = paftaVerisi(d, p); v->ucGorunumKur(9, 50, 40, 30); // üç görünüm AYNI gövdeden NesneKok* nk = d.bul(p); auto* pn = dynamic_cast(nk->get()); FIKO_KONTROL(pn != nullptr); // Recompute DAG kenarı: aynı kaynak bir kez (üç kez tetiklenmesin). FIKO_KONTROL(pn->bagimliliklar().size() == 1); FIKO_KONTROL(pn->bagimliliklar()[0] == (Varlik)9); // Kaynaksız görünüm bağımlılık üretmez. pafta::Gorunum bagimsiz; v->gorunumEkle(bagimsiz); FIKO_KONTROL(pn->bagimliliklar().size() == 1); } FIKO_TEST(pafta_dugum_ad_ve_ozellikler) { Dunya d; const Varlik p = paftaDugumEkle(d); NesneKok* nk = d.bul(p); auto* pn = dynamic_cast(nk->get()); FIKO_KONTROL(std::string(pn->turAdi()) == "Teknik Resim"); pn->adAyarla("Kapak Plakası"); FIKO_KONTROL(pn->ad() == "Kapak Plakası"); OzellikSeti oz = pn->ozellikler(d); FIKO_KONTROL(oz.size() >= 5); // Antet alanı yazılabilir (özellik panelinden düzenlenir). for (Ozellik& o : oz) if (o.ad == "Parça" && o.metinYaz) o.metinYaz("P-1024"); FIKO_KONTROL(paftaVerisi(d, p)->antet.parca == "P-1024"); } FIKO_TEST(pafta_dugum_pusula_veri_korunur) { // Sahne Vulkan ister → anlik/diril kod yolu derlemeyle doğrulanır; burada pusula // taşıyıcısının (PaftaPusulaVeri) veri bütünlüğü çivilenir (sketchEskiz kalıbı). Dunya d; const Varlik v = paftaDugumEkle(d); pafta::Pafta* pv = paftaVerisi(d, v); pv->ucGorunumKur(7, 100, 60, 40); pafta::Olcu o; o.gorunum = pv->gorunumler()[0].kimlik; o.p1 = {0, 0}; o.p2 = {10, 0}; o.sonEk = " ±0,1"; pv->olcuEkle(o); // anlik(): veri pusulaya KOPYALANIR (paylaşım değil — sonrası değişiklik sızmaz). auto pusula = std::make_shared(PaftaPusulaVeri{*pv}); pv->gorunumSil(pv->gorunumler()[0].kimlik); // "silinme" simülasyonu: canlı veri bozulur FIKO_KONTROL(pv->sayi() == 2); // diril(): pusuladan yeni düğüme geri yükle. const Varlik v2 = paftaDugumEkle(d); paftaVerisi(d, v2)->operator=(pusula->veri); const pafta::Pafta* geri = paftaVerisi(d, v2); FIKO_KONTROL(geri->sayi() == 3); FIKO_KONTROL(geri->olculer().size() == 1); FIKO_KONTROL(geri->olculer()[0].sonEk == " ±0,1"); FIKO_KONTROL(geri->gorunumler()[1].hiza == pafta::Gorunum::Hiza::Dikey); // hiza bağı korunur } FIKO_TEST(pafta_duzen_islem_undo_redo) { Dunya d; OlayGunlugu g; const Varlik v = paftaDugumEkle(d); pafta::Pafta* pv = paftaVerisi(d, v); pafta::Pafta once = *pv; // boş durum pv->ucGorunumKur(7, 100, 60, 40); // UI değişikliği zaten uygulandı pafta::Pafta sonra = *pv; PaftaDuzenIslem islem(v, std::move(once), std::move(sonra), "Test"); islem.uygula(d, g); // idempotent: aynı "sonra" tekrar yazılır FIKO_KONTROL(paftaVerisi(d, v)->sayi() == 3); islem.geriAl(d, g); // Ctrl+Z → boş duruma dön FIKO_KONTROL(paftaVerisi(d, v)->sayi() == 0); islem.uygula(d, g); // Ctrl+Y → geri gelir FIKO_KONTROL(paftaVerisi(d, v)->sayi() == 3); // Düğüm yoksa sessiz no-op (çökme yok). PaftaDuzenIslem yok((Varlik)9999, {}, {}, "Yok"); yok.uygula(d, g); yok.geriAl(d, g); }