Plazma sayı 3, sayfa 78

Bu sayfadaki yazılar

Sayfanın metni

Sayfa 78

Timer() ;

~Timer() ;

void Start() ;

void Stop() ;

double GetTime() const ;

private:

bool counting_ ;

LARGE_INTEGER frequency_ ;

LARGE_INTEGER zero_ ;

Timerımız için Windows’un yüksek hassaslıklı zamanlayıcılarını kullanacağız. Bunun için işlemciye özgü bir saatin frekansını (frequency_) ve başla dediğimiz anın zamanını (zero_) tutmamız gerekiyor. GetTime dediğimizde de kronometre çalışıyorsa (counting_) timerımız o anki süreye bakıp, başlangıç süresini çıkarıp, frekansı da kullanarak saniye cinsinden kronometre değerini dönüyor. Kronometre durmuşsa da en son durulan uzaklığı zero_‘ya atmış olmamıza güvenip bu değeri veriyor.

(Not: Burada basit bir yapı olacak, kronometre her zaman sıfırdan başlayacak. Olayı kavradıktan sonra pause ve hız ayarı gibi özellikler ekleyebilirsiniz.)

Tabii bu timer'ı kullanmak isteyenlerin LARGE_INTEGER'ın ne olduğunu bilmeleri, bu yüzden windows.h'ı kullanmaları gerekiyor. Bir diğer seçenek de Timer.h'ın tepesinde bu işi kendimiz yaparak sınıf kullanıcılarını bu dertten kurtarmamız. Her iki durumda da istenmeyen header'lardan kurtulamıyoruz.

Çözüm yöntemlerimiz neler olabilir?

LARGE_INTEGER'ın 64 bitlik tamsayı olduğunu varsayıp yerine favori 64 bitlik tipimizi koymak ve gereken her yerde tip geçişi yapmak? Sakın! Asla diğer tiplerin yapıları hakkında varsayımlarda bulunmayın. LARGE_INTEGER'ın ya da onu oluşturan parçaların en ufak değişikliğinde kendinizi milyonlarca satır düzeltmeye çalışırken buluyor olabilirsiniz.

Hassas saatler yerine standart kütüphanenin clock'unu kullanmak? Belki. Hassaslıkta epey bir kaybınız olacak ama en azından daha kolay port edilebilir bir kod elde edeceksiniz. Eksi olarak ise, kullanıcı istemeden ctime'ı eklemiş olacaksınız ve bu mantıkla devam ederseniz platforma özgü çok iyi özelliklerden mahrum kalacaksınız.

Benim istediğim ise hiçbir header eklemeye gerek bırakmayan, üzerinde çalıştığı platformun en iyi çözümünü kullanan ve bunu yaparken kullanıcıya herhangi bir şey yansıtmayan bir yöntem.

Opak Pointer Yöntemi

Sorunumuz LARGE_INTEGER'ı kullanabilmek için tanımına ihtiyacımız olması idi. Bu yöntem soruna çok basit yaklaşım sergiliyor. Tanıma ihtiyacımız var çünkü Timer objeleri oluşturabilmek için Timer objelerinin boyunu bilmeliyiz. Timer objelerinin boyunu hesaplamak için de LARGE_INTEGER'ların boyunu bilmeliyiz. Ama anahtar şu ki, kullanıcı asla zero_ ya da frequency_'yi kullanmayacak. Dolayısıyla onun bunların boyunu başka bir amaçla bilmesine gerek yok. Timer bu elemanların boyunu kullanıcıya göstermeden onları nasıl kullanabilir?

Klavyeyle gezinmek için ← ve → tuşları.