Bir Olay İşleyicisi Yazma
Olay işleyicileri, eklentilerin ana işlevlerinden biridir. Bir eklentinin sunucunun iç işleyişine dokunmasına ve davranışını değiştirerek başka bir eylem gerçekleştirmesine olanak tanırlar. Basit bir örnek olarak player_join olayı için bir işleyici uygulayacağız.
Pumpkin eklenti olay sistemi, Bukkit/Spigot olay sistemini kopyalamaya çalışır; böylece oradan gelen geliştiriciler Pumpkin'i öğrenirken daha kolay eder. Ancak Rust'ın farklı kavramları ve kuralları vardır, bu yüzden her şey Bukkit/Spigot'taki gibi değildir. Rust'ta kalıtım yoktur; bunun yerine yalnızca bileşim vardır.
Olay sistemi, bazı olayları dinamik olarak ele almak için trait'leri kullanır: Event, Cancellable, PlayerEvent vb. Cancellable bir Event de olabilir, çünkü bir trait'tir. (TODO: verify this)
Katılma Olayını Uygulama
Tekil olay işleyicileri, EventHandler<T> trait'ini uygulayan struct'lardır (T belirli bir olay uygulamasıdır).
Bloklayıcı olaylar nedir?
Pumpkin eklenti olay sistemi iki tür olayı ayırt eder: bloklayıcı ve bloklayıcı olmayan. Her birinin faydaları vardır:
Bloklayıcı olaylar
Pros:
+ Olayı değiştirebilir (ör. katılma mesajını düzenlemek)
+ Olayı iptal edebilir
+ Öncelik sistemi vardır
Cons:
- Sırayla yürütülür
- İyi uygulanmazsa sunucuyu yavaşlatabilirBloklayıcı olmayan olaylar
Pros:
+ Eşzamanlı yürütülür
+ Tüm bloklayıcı olaylar bittikten sonra yürütülür
+ Bazı değişiklikler yine yapılabilir (Mutex veya RwLock arkasındaki her şey)
Cons:
- Olayı iptal edemez
- Öncelik sistemi yoktur
- Olay üzerinde daha az kontrol sağlarBir işleyici yazma
Buradaki temel amacımız oyuncunun sunucuya katıldığında gördüğü hoş geldin mesajını değiştirmek olduğu için, düşük öncelikli bloklayıcı olay türünü seçeceğiz.
Bu kodu on_load yönteminin üstüne ekleyin:
use pumpkin_api_macros::with_runtime;
use pumpkin::{
plugin::{player::player_join::PlayerJoinEvent, Context, EventHandler, EventPriority},
server::Server,
};
use pumpkin_util::text::{color::NamedColor, TextComponent};
struct MyJoinHandler;
#[with_runtime(global)]
impl EventHandler<PlayerJoinEvent> for MyJoinHandler {
fn handle_blocking(&self, _server: &Arc<Server>, event: &mut PlayerJoinEvent) -> BoxFuture<'_, ()> {
Box::pin(async move {
event.join_message =
TextComponent::text(format!("Welcome, {}!", event.player.gameprofile.name))
.color_named(NamedColor::Green);
})
}
}Açıklama:
struct MyJoinHandler;: Olay işleyicimiz için struct#[with_runtime(global)]: Pumpkin tokio async runtime'ını kullanır ve bu, eklenti sınırı boyunca garip davranabilir. Bu örnekte zorunlu olmasa da, async kodla etkileşime giren tüm asyncimpl'leri bu macro ile sarmak iyi bir pratiktir.fn handle_blocking(): Bu olayın bloklayıcı olmasını seçtiğimiz içinhandle()yerinehandle_blocking()yöntemini uygulamak gerekir.
İşleyiciyi kaydetme
Artık olay işleyicisini yazdığımıza göre, eklentiye bunu kullanmasını söylememiz gerekiyor. Bunu on_load yöntemine tek bir satır ekleyerek yapabiliriz:
use pumpkin::{
plugin::{player::player_join::PlayerJoinEvent, Context, EventHandler, EventPriority},
server::Server,
};
use pumpkin::{
plugin::{player::player_join::PlayerJoinEvent, Context, EventHandler},
server::Server,
};
#[plugin_method]
async fn on_load(&mut self, server: Arc<Context>) -> Result<(), String> {
server.init_log();
log::info!("Hello, Pumpkin!");
server.register_event(Arc::new(MyJoinHandler), EventPriority::Lowest, true).await;
Ok(())
}Artık eklentiyi derleyip sunucuya katıldığımızda, kullanıcı adımızla birlikte yeşil bir "Welcome" mesajı görmeliyiz!