iToverDose/Yazılım· 1 HAZIRAN 2026 · 12:04

C++ Aktivite İzleyicisine Lua Uzantı Motoru Nasıl Eklendi?

C++23 ile geliştirilen açık kaynaklı bir aktivite izleyici olan HPR’ye Lua tabanlı bir uzantı motoru ekleme hikayesi ve karşılaşılan zorluklar. İşte detaylar.

DEV Community3 dk okuma0 Yorumlar

C++23 ile geliştirilen ve doğal Wayland desteğine sahip olan HPR, açık kaynaklı bir aktivite izleyicisi olarak öne çıkıyor. Bu araç, etkin pencereyi izleyerek zaman geçişinizi kaydediyor ve yerel olarak çalışıyor — hiçbir hesap ya da telemetri gerektirmiyor. AktiviteWatch’a benzer özellikler sunan HPR, zamanla yeteneklerini genişletmek için Lua tabanlı bir uzantı motoruna ihtiyaç duydu. Peki, bu motor nasıl hayata geçirildi ve karşılaşılan en büyük zorluklar nelerdi?

Lua Uzantı Motorunun Temel Tasarımı

HPR’nin Lua uzantı motoru, basit ancak güçlü bir çalışma prensibine sahip. Uzantılar, .lua uzantılı dosyalar olarak tanımlanıyor ve bu dosyalar otomatik olarak tarandığı klasörden yükleniyor. HPR, her uzantıyı kendi sol::state ortamında çalıştırıyor ve ayrı bir iş parçacığına atıyor. Bu sayede, bir uzantının yavaşlaması ya da hatalara yol açması ana uygulamanın çalışmasını etkilemiyor. İzole edilmiş çalışma ortamı, hem performans hem de güvenlik açısından önemli bir avantaj sağlıyor.

Uzantılar, üç temel fonksiyonla tanımlanıyor:

  • init() — Bu fonksiyon, onTick fonksiyonunun ne sıklıkta çağrılacağını belirliyor. Örneğin, return 500 döndürülmesi, her 500 milisaniyede bir onTick fonksiyonunun çalıştırılacağını gösteriyor.
  • onTick(delta) — Belirlenen aralıklarla otomatik olarak çağrılan ve zaman farkını (delta) parametre olarak alan fonksiyon.
  • onExit() — Uzantı kapatılırken çalıştırılan temizlik fonksiyonu.

Herhangi bir zorunlu fonksiyon bulunmuyor; geliştiriciler ihtiyaçlarına göre istedikleri fonksiyonları tanımlayabiliyor.

Lua’dan Erişilebilen Güçlü API Seçenekleri

Uzantı motorunun en önemli yanı, Lua’dan HPR’nin çekirdek işlevlerine erişim sağlaması. Bu sayede, uzantılar sadece basit izleme değil, aynı zamanda gelişmiş özellikler de sunabiliyor. API aracılığıyla yapılabilecekler şunları içeriyor:

  • Aktif pencereyi okuyabilme — HPR.getCurrentWindow_E() fonksiyonu sayesinde.
  • SQLite veritabanına doğrudan sorgulama ve değişiklik yapabilme — HPR.dbQuery_E() ve HPR.dbExecute_E() fonksiyonlarıyla.
  • WINDOW_CHANGED, MIDNIGHT_ROLLOVER veya HISTORY_LOADED_SINGULAR gibi dahili olaylara abone olabilme.
  • HPR’nin desteklemediği pencere sistemleri için özelleştirilmiş algılama yöntemleri ekleyebilme.
  • Slint arayüzüne müdahale edebilme, UI özelliklerini değiştirebilme ve geri çağrılar kaydedebilme.
  • HTTP istekleri yapabilme, HTTP sunucusu başlatabilme, JSON ve CSV dosyalarını okuyup yazabilme.
  • Ana pencere izleme döngüsünü durdurup yeniden başlatabilme — örneğin, AFK (kullanıcıdan uzak kalma) algılama sistemlerinde olduğu gibi.

Bu son özellik, özellikle AFK algılama sistemlerinde kritik bir rol oynuyor. Kullanıcıdan uzak kalındığında izlemeyi durdurmak ve kullanıcı geri döndüğünde yeniden başlatmak, verilerin doğruluğunu artırıyor.

En Büyük Engeller: Deadlocklar ve Döngüsel Tablolar

Projenin en zorlu kısımlarından biri, çekirdek kodun kendisi değil, yaşanan deadlock (kilitlenme) problemleriydi. Lua durumunun thread-safe olmaması, Slint arayüzünün sadece kendi olay döngü iş parçacığından erişilebilir olması ve uygulama durumunun kendi mutex’ine sahip olması, çoklu iş parçacığı yönetimini karmaşık hale getiriyordu. HPR’de, her bir uzantı için ayrı bir recursive_mutex kullanılarak Lua fonksiyonlarına yapılan tüm çağrılar sarıldı. Ayrıca, Slint arayüzüne dokunulması gereken durumlarda slint::invoke_from_event_loop fonksiyonu kullanıldı. Lua’dan gelen geri çağrıların Slint olay döngüsü tarafından tetiklenmesi sırasında Lua mutex’i kilidinin alınması da sorunun çözümüne katkı sağladı.

Bir diğer önemli sorun ise döngüsel tabloların neden olduğu yığın taşmalarıydı. Eğer bir Lua uzantısı, kendine referans veren bir tabloyu UI özelliklerine gönderirse, sonsuz bir özyineleme oluşuyor ve sonuçta program çöküyordu. Bu durumu önlemek için, tablo dönüştürme işlemi sırasında ziyaret edilen tabloların bir listesini tutan bir mekanizma eklendi. Eğer bir döngü tespit edilirse, hata mesajı veriliyor ve işlem durduruluyordu.

Gerçek Bir Örnek: ActivityWatch Benzeri Davranış

HPR’nin sunduğu uzantı motorunun yeteneklerini göstermek için, AW Parasite adı verilen bir uzantı geliştirildi. Bu uzantı, ActivityWatch’in varsayılan olarak kullandığı port olan 5600 numaralı portta bir HTTP sunucusu başlatıyor. aw-watcher-web ve aw-watcher-afk gibi araçlar, ActivityWatch’e bağlandıklarını sanıyorlar. Bu araçlar kalp atışı mesajları gönderiyor, uzantı bu mesajları işliyor ve URL bazlı aktivite süresini ile AFK durumunu HPR’nin SQLite veritabanına kaydediyor. Ayrıca, arayüzü de HPR.setUiProperty_E fonksiyonu aracılığıyla güncelliyor.

Kullanıcıdan uzak kalındığında, uzantı HPR.stopTracking_E() fonksiyonunu çağırarak ana aktivite izleme döngüsünü durduruyor. Kullanıcı geri döndüğünde ise HPR.startTracking_E() fonksiyonuyla izlemeyi yeniden başlatıyor. Bu süreç, hem Wayland hem de Windows üzerinde sorunsuz çalışıyor, çünkü tüm işlemler HTTP protokolü üzerinden gerçekleşiyor. Bu uzantı, yaklaşık 200 satır Lua kodu ile yazılmış durumda.

Sıcak Yeniden Yükleme ve Diğer Özellikler

HPR, kullanıcıların uzantıları sıcak olarak yükleyip kaldırmasına, hatta yeniden yüklemesine olanak tanıyor. Bunun yanı sıra, çalışma sırasında yeni .lua dosyaları eklendiğinde, bir "yeniden tarama" düğmesiyle bu dosyaların algılanmasını sağlıyor. Bir uzantı kaldırıldığında, çalışan iş parçacığına 450 milisaniye süre veriliyor. Eğer uzantı düzgün bir şekilde kapanmazsa, iş parçacığı serbest bırakılıyor ve bir uyarı kaydediliyor. Ayrıca, Lua’nın yetersiz kaldığı durumlar için .dll ya da .so uzantılı yerel uzantılar da destekleniyor, ancak bu uzantılar sandbox dışında çalışıyor.

HPR, tamamen ücretsiz ve açık kaynaklı bir proje olarak geliştiriliyor. İlginizi çektiyse, GitHub deposunu ziyaret ederek daha fazla bilgi edinebilir ve projeye katkıda bulunabilirsiniz.

Uzantı motorları, kullanıcıların araçlarını kişiselleştirmesine olanak tanıyarak, açık kaynaklı projelerin gücünü artırıyor. HPR’nin sunduğu bu esneklik ve izolasyon mekanizmaları, gelecekteki geliştirme süreçlerinde ilham kaynağı olmaya devam edecek gibi görünüyor.

Yapay zeka özeti

C++23 ile geliştirilen açık kaynaklı HPR aktivite izleyicisine nasıl Lua tabanlı bir uzantı motoru eklendi? Ölümcül deadlocklardan kaçınma ve API kullanımı hakkında detaylar.

Yorumlar

00
YORUM BIRAK
ID #OR4GBV

0 / 1200 KARAKTER

İnsan doğrulaması

9 + 3 = ?

Editör onayı sonrası yayına girer

Moderasyon · Spam koruması aktif

Henüz onaylı yorum yok. İlk yorumu sen bırak.