Forum: SDL RSS
HATA YAKALAMA: SDL ile TTF dosyalarını açarken...
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: HATA YAKALAMA: SDL ile TTF dosyalarını açarken...
Merhaba,

Bir süredir SDL ile ilgileniyorum ve sanki buna kendimi kaptırdım. Şunu bir deneyim derken kendimi ilinti ve işlev yazarken buldum. Herhalde programcılık böyle bir şeymiş...:)

Programcılığın eksik olmayan bir konusu da hatalar. İşler karmaşıklaşınca hep aynı hatayı (Parçalama Hatası) alınca kontrollü kod yazma gereği doğuruyor. İşte SDL'de şu an böyle bir durum söz konusu. Başlangıçta TTF_Init() yapmadığım için program göçüyordu. Neyse ki bunu yakalayan TTF_WasInit() isminde başka bir işlev varmış. Ancak yüklenen dosya ismini (aslında aşağıdaki alıntı da comic.ttf) yanlış yazarsanız bunu yakalayamıyorsunuz!
Salih Dinçer:
...dosya hatalarını yakalayamadım. Şöyle denemeler (SDL_RWops ile) de yaptım ama olmadı...:(

class Oyun.this'in içinde =>
        TTF_Init();
        arial_TTF =  TTF_OpenFont("arial.ttf", 40);
        comic_TTF = TTF_OpenFont("comics.ttf", 40);/*
        SDL_RWops *rw = SDL_RWFromFile("comics.ttf", "rb");
        printf("Buraya gelemedim...:(");
        comic_TTF = TTF_OpenFontIndexRW(rw, 1, 40, 0);
        assert(rw != null);//*/
        courier_TTF = TTF_OpenFont("courier.ttf", 40);
Bu arada ekranaYaz() işlevini Oyun sınıfına dahil ettim ve son hali şöyle:

class Oyun içinde =>
public bool ekranaYaz (TTF_Font* xFont, Renk xRenk,
                          int x, int y, const char* metin) {
 
        auto rengi = SDL_Color(xRenk.k, xRenk.y, xRenk.m);
        EkranYüzeyi textSurface = TTF_RenderUTF8_Solid(xFont, metin, rengi);
        SDL_Rect pixelCoordinate;
                 pixelCoordinate.x = cast(short)x;
                 pixelCoordinate.y = cast(short)y;
     
        if(!TTF_WasInit())
        {
            printf("YAZI HATASI: TTF sunucusu ilklendirilemedi!\n");
            return false;
        }
        else if(xFont == null)/*
        else if(TTF_FontHeight(xFont) <= 0)//*/
        {
            printf("YAZI HATASI: TTF dosyası yüklenemedi! %d\n");
            return false;
        }
        else if (textSurface != null)
        {
            pixelCoordinate.x -= cast(short)textSurface.w/2;
            pixelCoordinate.y -= cast(short)textSurface.h/2;
            /* DİKKAT:
             * Parçalama hatası vermemesi için koordinatın
             * ekrana ortalanması burada hesaplanmalı...
             */
            SDL_BlitSurface(textSurface, null, ekran, &  pixelCoordinate);
            SDL_FreeSurface(textSurface);
            return true;
        }
        else  // Hiç biri de değilse ekran'a bir şey yazma...
        {
            printf("YAZI HATASI: Görülebilir (render) hale getirilemedi!\n");
            return false;
        }
    }
Elbette programcılıkta çareler tükenmez. Belki en sağlamı, std.stdio sınıfındaki işlevler ile dosyanın orada var olup olmadığını kontrol edebilirim. Ancak font dosyası orada fakat bozuksa!

Dolayısıyla bir şekilde ekrana yazı yazarken, tıpkı nesnenin boş (null) olup olmadığını kontrol edebilmem gibi xFont nesnesinin de işime yarayıp yaramadığını bilmeliyim. Bunun için dosyanın ilk açıldığı ana (-bknz. SDL_rwops.c dosyası, 438. satır), kadar izledim. Sorun olduğu durumlarda NULL değerleri dönüyor ama ben bunları yakalayamıyorum. Hadi bunun başka bir sebebi var ama SDL_SetError() işlevi ile atılan hatayı SDL_GetError() ile de okuyamıyorum. Çünkü o satıra gelmeden evvel parçalama hatası vermiş oluyor...:)

Bu konuda yardım edebilecek var mı?
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
İftardan sonra, şöyle bir oturdum bilgisayar başına...:)

Meğer render sırasında (ekranaYaz işlevinin başında) program göçüyormuş. O yüzden textSurface nesnesi meydana gelirken xFont'u kontrol etmeliydim! Çünkü render yapan işlevin parametrelerinden biri xFont... :-D  
EkranYüzeyi textSurface;  // Önceden kontrol edilmiyordu ve nesne render olmaya zorlanıyordu!
if(xFont != null) textSurface = TTF_RenderUTF8_Solid(xFont, metin, rengi);
else return false;
/* printf("YAZI HATASI: TTF dosyası yüklenemedi!\n");
 * bu işlev bir döngü içinde sürekli çağrıldığı için
 * hata iletilerini this'e taşıdım, yoksa konsola sürekli hata atıyor...
 */
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
erdem (Moderatör) #3
Üye Tem 2009 tarihinden beri · 980 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Hatta daha iyisi assert(xFont != null) şeklinde kontrol etmek olabilir. D'nin kendi hata yakalama olanaklarının bu konuda daha kullanışlı olabileceğini düşünüyorum.
acehreli (Moderatör) #4
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Ben de Erdem gibi düşünüyorum. Salih, eğer şöyle düşünürsen herşey çok basit oluyor: ekranaYaz() işlevinin işi, parametreleriyle belirtilen iştir. O işi yapabilirse ne güzel, yapamazsa hata ile çıkılır.

Böylece ekranaYaz()'ı çağıranlar da bir de dönüş değerine bakmak zorunda kalmazlar. İstekleri ya gerçekleşmiştir, ya gerçekleşmemiştir. Eğer isteklerinin gerçekleşmediğin tam da o an bilmek istiyorlarsa (sanıldığında çok nadir olarak istenir), o zaman try-catch kullanırlar. Tam o an bilmek istemiyorlarsa hiçbir şey yapmaları gerekmez; hata üst düzeylere doğru gider ve daha üst düzeyde ilgilenen varsa orada yakalanır.

  • O yüzden dönüş türü void olsa daha iyi olur. Sonuçta bu işlev bir değer üretmiyor.

Ben iki geliştirme önereceğim:

  • assert() mü enforce() mu konusu burada da geçerli. Eğer ekranaYaz()'ın bulunduğu kodları bir kütüphane olarak düşünüyorsak, yani bu işlev başka programlar tarafından da çağrılacaksa, o zaman enforce() uygun.

  • Bu kişisel bir konu ama ben açıkça '!= null' yazmayı sevmiyorum. Şu da yeterli:

    enforce(xFont);

Ali
erdem (Moderatör) #5
Üye Tem 2009 tarihinden beri · 980 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
  • Bu kişisel bir konu ama ben açıkça '!= null' yazmayı sevmiyorum. Şu da yeterli:

    enforce(xFont);

Vay bu güzel bir olanakmış. Öğrendiğim iyi oldu :)
Avatar
Salih Dinçer #6
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Maalesef assert()'ler nihai sürümde (release) sürümde kayboldukları için sadece geliştirme aşamasında kullanmamız gerekiyor. Öyle bir tasarım yapmalı ki yüklenen dosyaların olup olmaması veya bozuk olması programın çalışmasını etkilemesin.
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #7
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Salih Dinçer:
Maalesef assert()'ler nihai sürümde (release) sürümde kayboldukları için sadece geliştirme aşamasında kullanmamız gerekiyor.

Programcı olarak bizim için geliştirme aşamasından başka aşama yok zaten. Biz assert()'lerimizi yine de yazacağız; onlar da program mantığının doğru olduğunu denetleyecekler.

Öyle bir tasarım yapmalı ki yüklenen dosyaların olup olmaması veya bozuk olması programın çalışmasını etkilemesin.

Varsayılan bir font kullanılabilir:

    if (!font) {
        font = varsayılanFont;
    }

Ali
Avatar
Salih Dinçer #8
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Evet, varsayılanFont benzeri bir şey düşündüm ama dosyanın kendisi yoksa render işlevi programın çökmesine neden oluyor. Yani dosyalardan bağımsız bir çözüm gerekiyor. Eğer Erdem'in başka başlıkta söz ettiği PPM dosyasını kodlara gömemebilirsem belki ekrana şöyle bir şey gelmesini sağlayabiliriz:
HATALI
FONT
Aslında bu dediğim yaptım ama o da dosyadan okunan bir resimdi...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: SDL RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 09:13:12 (UTC -08:00)