Mungkinkah saya menjadi gila dengan Penangan Acara? Apakah saya salah arah dengan desain saya?

12

Saya kira saya sudah memutuskan bahwa saya sangat suka event handler. Saya mungkin menderita sedikit dari kelumpuhan analisis, tetapi saya khawatir tentang membuat desain saya berat atau mengalami konsekuensi tak terduga lainnya terhadap keputusan desain saya.

Mesin permainan saya saat ini melakukan rendering berbasis sprite dasar dengan kamera overhead panning. Desain saya terlihat sedikit seperti ini:

SceneHandler

Berisi daftar kelas yang mengimplementasikan antarmuka SceneListener (saat ini hanya Sprite). Memanggil render () sekali per centang, dan mengirimkan onCameraUpdate (); pesan ke SceneListeners.

InputHandler

Polling input sekali per centang, dan mengirim pesan "onKeyPressed" sederhana ke InputListeners. Saya memiliki Camera InputListener yang memegang instance SceneHandler dan memicu updateCamera (); peristiwa berdasarkan apa inputnya.

AgentHandler

Panggilan tindakan default pada Agen apa pun (AI) sekali per centang, dan akan memeriksa tumpukan untuk setiap peristiwa baru yang terdaftar, mengirimkannya ke Agen tertentu sesuai kebutuhan.

Jadi saya memiliki objek sprite dasar yang dapat bergerak di sekitar pemandangan dan menggunakan perilaku kemudi yang belum sempurna untuk bepergian. Saya sudah menemukan deteksi tabrakan, dan di sinilah saya tidak yakin arah desain saya berjalan dengan baik. Apakah praktik yang baik untuk memiliki banyak, penangan event kecil? Saya membayangkan pergi seperti saya bahwa saya harus menerapkan semacam CollisionHandler.

Apakah saya akan lebih baik dengan EntityHandler yang lebih terkonsolidasi yang menangani AI, pembaruan tabrakan, dan interaksi entitas lainnya dalam satu kelas? Atau apakah saya akan baik-baik saja hanya menerapkan banyak subsistem penanganan acara yang berbeda yang menyampaikan pesan satu sama lain berdasarkan jenis acara apa? Haruskah saya menulis EntityHandler yang hanya bertanggung jawab untuk mengoordinasikan semua penangan sub event ini?

Saya menyadari dalam beberapa kasus, seperti InputHandler dan SceneHandler saya, itu adalah jenis peristiwa yang sangat spesifik. Sebagian besar kode permainan saya tidak akan peduli tentang input, dan sebagian besar tidak akan peduli tentang pembaruan yang terjadi murni dalam rendering adegan. Jadi saya merasa isolasi saya terhadap sistem-sistem itu dibenarkan. Namun, saya mengajukan pertanyaan ini secara khusus mendekati peristiwa jenis logika game.

sensae
sumber

Jawaban:

21

Perancangan berbasis acara sebagian besar melibatkan penerapan pola desain Reaktor .

Sebelum mulai mendesain komponen, Anda harus melihat keterbatasan pola tersebut (Anda mungkin menemukan banyak informasi tentang ini).

Masalah pertama dan terpenting adalah bahwa penangan harus kembali dengan cepat , karena setiap orang yang melakukan pekerjaan serius pada kerangka kerja berbasis GUI dan aplikasi berbasis javascript tahu betul.

Ketika Anda mengembangkan setiap aplikasi dengan kompleksitas yang layak, Anda akan, cepat atau lambat, menghadapi beberapa penangan yang melakukan pekerjaan kompleks yang membutuhkan waktu .

Dalam kasus ini, Anda dapat membedakan dua situasi (tidak harus saling terpisah):

Kompleks -acara yang berhubungan dengan tanggung jawab dan kompleks acara-terkait tanggung jawab.

Tanggung jawab terkait peristiwa yang kompleks:

Dalam kasus pertama Anda menggabungkan terlalu banyak tanggung jawab menjadi satu penangan komponen tunggal : terlalu banyak tindakan yang diambil sebagai tanggapan terhadap suatu peristiwa atau ada yang menjalankan sinkronisasi misalnya.

Dalam hal ini solusinya adalah dengan membagi handler menjadi handler yang berbeda (dalam objek yang berbeda jika perlu) dan membiarkan pegangan untuk menembakkan kejadian alih-alih memanggil langsung kode penanganan. Ini memungkinkan Anda untuk mengijinkan acara dengan prioritas lebih tinggi untuk dikelola sebelumnya karena penangan utama Anda telah kembali setelah menambahkan acara ke antrian acara.

Solusi lain adalah membiarkan entitas eksternal untuk memecat acara dan membiarkan yang lain untuk berlangganan jika tertarik (peristiwa waktu adalah contoh paling sepele yang dapat Anda generalisasi).

Tanggung jawab yang tidak berkaitan dengan peristiwa yang kompleks:

Kasus kedua terjadi ketika ada kompleksitas intrinsik dalam tindakan untuk mengambil setelah suatu peristiwa: Anda harus menghitung angka fibonacci setelah suatu kejadian misalnya.

Di sini pola Reactor pada dasarnya gagal , tidak banyak artinya untuk memecah algoritma pembangkitan fibonacci menjadi potongan-potongan kecil yang memicu peristiwa saat penghentian untuk memicu langkah berikutnya.

Di sini solusinya adalah mencampur desain berulir ke reaktor , kabar baiknya adalah jika kerumitannya bersifat intrinsik (jadi Anda membaca bagian yang tepat), sangat mungkin untuk memulai dan memisahkan utas yang melakukan pekerjaan dan yang perlu tahu sedikit atau tidak sama sekali tentang sisa komponen yang berhubungan dengan Reaktor.

Untuk menangani situasi semacam ini, saya merasa berguna untuk mengadopsi antrian pekerjaan di atas kumpulan utas yang fleksibel .

Ketika seorang pawang perlu memulai aksi panjang, itu merangkum aksi itu ke dalam unit kerja untuk dimasukkan ke dalam antrian pekerjaan. Tindakan enkapsulasi ini perlu memiliki sarana untuk memicu peristiwa ke dalam reaktor. Manajer antrian pekerjaan mungkin berjalan ke utasnya sendiri atau di utas reaktor dan bereaksi terhadap peristiwa "newJob".

Manajer antrian pekerjaan melakukan hal berikut:

  • itu mengalokasikan unit kerja ke utas dari kumpulan utas fleksibel menggunakan algoritme shedule-nya jika kumpulan ini dapat menyediakan satu utas (ada utas gratis atau pembuatan utas baru diizinkan)

  • dengarkan kumpulan itu sendiri untuk melihat apakah unit pekerjaan selesai sehingga utas dapat dipulihkan untuk mengeksekusi satu unit lagi yang tertunda, jika ada.

Menggunakan mekanisme pelepasan kejadian, unit kerja dapat memicu acara untuk memberi tahu penyelesaian, status pembaruan, peringatan, kesalahan, atau kapan saja diperlukan. Kumpulan thread fleksibel memastikan penggunaan sumber daya yang baik sambil menghindari thread mati untuk menggantung seluruh sistem; antrian pekerjaan memungkinkan Anda untuk memilih jenis prioritas yang ditetapkan untuk jenis tindakan yang berbeda karena Anda tahu bahwa mereka akan memerlukan jumlah sumber daya komputasi yang konsisten.

FxIII
sumber
3
+1 karena sangat teliti. Beberapa tautan untuk pembaca yang ingin tahu akan luar biasa.
sam hocevar
1

Dalam sebagian besar situasi, menggunakan peristiwa di atas opsi lain sering kali dapat meningkatkan kecepatan dan desentralisasi. Saya pikir jika Anda dapat menggunakan banyak acara, Anda harus melakukannya.

secara anonim
sumber