Data Manipulator
Mengakses dan memodifikasi data
Manipulasi data mewakili komponen tertentu dan semua datanya. Ini menyimpan representasi data tersebut dan dapat ditawarkan atau dibuat dari pemegang data yang memiliki kompomen yang sesuai. Sekali lagi, mari kita gunakan sebuah contoh. Dan lagi coba sembuhkan seseorang (atau sesuatu).
Contoh Kode: Penyembuhan dengan manipulator data
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataTransactionResult;
import org.spongepowered.api.data.manipulator.mutable.entity.HealthData;
import org.spongepowered.api.data.value.mutable.MutableBoundedValue;
import java.util.Optional;
public static DataTransactionResult heal(DataHolder target) {
Optional<HealthData> healthOptional = target.get(HealthData.class);
if (healthOptional.isPresent()) {
HealthData healthData = healthOptional.get();
double maxHealth = healthData.maxHealth().get();
MutableBoundedValue<Double> currentHealth = healthData.health();
currentHealth.set(maxHealth);
healthData.set(currentHealth);
target.offer(healthData);
}
}
Pertama kami perlu mengecek apakah target kami memilioki data kesehatan. Kami melakukannya dengan terlebih dahulu meminta untukmenyediakan kami derengan data kesehatan dengan metode kelasnya``dapaty()``. Kitamendapatkan opsional
yang dapat kita gunakan untuk memeriksa kami. Ini opsional
akan absen jika target kami tidak mendukung:javadoc:Datakesehatan atau jika mendukung itu tetapi pada saat ini tidak memegang data kesehatan.
Jika data kesehatan ada, sekarang berisi salinan yang tidak tetap dari data yang ada pada pemegang data. Kita membuat perubahan dan akhirnya menawarkan penggantian data kembali ke sasaran kita, yang diterima (lagi, offer()
yang akan mengembalikan DataTransactionResult yang akan kita abaikan dalam contoh ini dan kembali ke at a later point).
Seperti yang dapat anda lihat, hasil untuk health()
dan maxHealth()``lagi-lagi merupakan nilai kunci yang kita peroleh dari :javadoc:`DataHolder`. Sebagai :javadoc:`MutableBoundedValue` kita menerima panggilan ``health()
lagi yang berisi salinan data, yang perlu kita terapkan perubahan kembali ke DataManipulator sebelum kita dapat menawarkan healthData
kembali ke sasaran kita.
Tip
Peraturan #1 dari Data API: Semua yang anda terima merupakan salinan. Jadi kapanpun anda mengubah sesuatu, pastikan bahwa yang anda ubah diterapkan kembali ke nilai aslinya berasal.
Modifikasi lain yang memungkinkan adalah sepenuhnya menghapus DataManipulator
. Ini dapat dilakukan melalui metode remove()
yang menerima referensi kelas dari jenis DataManipulator
untuk dihapus. Beberapa data tidak dapat dihapus dan upaya untuk melakukannya akan selalu mengembalikan tanda kegagalan DataTransactionResult
. Kode berikut berupaya untuk menghapus nama pilihan dari yang diberikan DataHolder
. Lagi-lagi, hasil transaksinya dibuang.
Contoh kode: menghapus nama tampilan kustom
import org.spongepowered.api.data.manipulator.mutable.DisplayNameData;
public void removeName(DataHolder target) {
target.remove(DisplayNameData.class);
}
Datamanipulator Vs, tombol
Jika Anda membandingkan kedua contoh penyembuhan kami, mungkin Anda bertanya-tanya 'Mengapa repot-repot dengan manipulator data, kunci menjadi lebih mudah' dan benar - untuk mendapatkan dan menetapkan nilai tunggal. Tapi manfaat sebenarnya dari manipulator data adalah data berisi semua data yang berkaitan dengan komponen tertentu. Mari kita lihat contoh lain.
Contoh Kode: Menukar dua data pemegang kesehatan
public void swapHealth(DataHolder targetA, DataHolder targetB) {
if (targetA.supports(HealthData.class) && targetB.supports(HealthData.class)) {
HealthData healthA = targetA.getOrCreate(HealthData.class).get();
HealthData healthB = targetB.getOrCreate(HealthData.class).get();
targetA.offer(healthB);
targetB.offer(healthA);
}
}
Pertama kita periksa jika kedua sasaran mendukung HealthData. Jika iya, kita simpan kedua kesehatan di dalam satu variabel masing-masing. Kita tidak perlu repot dengan Optional
kali ini karena kita telah memverifikasi bahwa HealthData
didukung dan metode ``getOrCreate()``memastikan bahkan jika tidak ada data, nilai bawaan akan dihasilkan.
Kemudian kami hanya menawarkan data kesehatan yang tersimpan ke target lainnya, sehingga mengubah status kesehatan mereka satu sama lain.
Contoh ini diselesaikan dengan Keys
yang akan memakan waktu lebih lama dan lebih rumit karena kita akan mengurus kunci individu masing-masing oleh kita sendiri. Dan daripada kesehatan kita menukar data manipulator lain yang berisi bahkan lebih data (mungkin berisi daftar InvisibilityData), yang akan memiliki banyak pekerjaan untuk dilakukan. Tetapi sejak pemegang data itu sendiri mengurus semua data yang berkaitan dengan itu, kita bahkan dapat mengubah fungsi di atas untuk menukar data sewenang-wenang di antara dua pemegang.
Contoh Kode: Penyembuhan dengan manipulator data
import org.spongepowered.api.data.manipulator.DataManipulator;
public <T extends DataManipulator<?,?>> void swapData(DataHolder targetA, DataHolder targetB, Class<T> dataClass) {
if (targetA.supports(dataClass) && targetB.supports(dataClass)) {
T dataA = targetA.getOrCreate(dataClass).get();
T dataB = targetB.getOrCreate(dataClass).get();
targetA.offer(dataB);
targetB.offer(dataA);
}
}
Kemampuan untuk menulis fungsi yang dapat menukar data pada dudukan data dengan data yang sama pada dudukan data lain menunjukkan tujuan perancangan inti API data: kompatibilitas maksimum di API.
Data Manipulator Tidak Tetap vs Tetap
Untuk setiap manipulasi data, ada yang cocok :javadoc: ImmutableDataManipulator. Misalnya, HealthData
dan :javadoc: ImmutableHealthData berisi data yang sama, hanya yang terakhir mengembalikan kasus baru saat meminta data yang dimodifikasi.
Konversi antara data manipulator yang tetap dan tidak tetap diselesaikan melalui metode asImmutable()
dan asMutable()
, yang masing-masing akan mengembalikan salinan data. Satu-satunya cara untuk memperoleh data manipulator yang tetap dari pemegang data adalah memperoleh satu yang tetap lalu menggunakan asImmutable()
.
Kemungkinan penggunaan kasus ini akan menjadi acara kustom yang dipecat saat seseorang disembuhkan. Ini harus menyediakan salinan data kesehatan sebelum dan sesudahnya, namun pendengar acara seharusnya tidak dapat mengubahnya. Oleh karena itu, kami dapat menulis acara kami untuk hanya menyediakan contoh ImmutableHealthData
. Dengan begitu, walaupun kode pihak ketiga bisa berinteraksi dengan data kami, kami yakin bahwa itu tidak akan berubah.
Data absen
Seperti yang telah disebutkan di atas, metode get()
mungkin mengembalikan Optional
kosong jika salah satu dari ini benar:
DataHolder
tidak mendukung pemberianDataManipulator
DataHolder
mendukungDataManipulator
, tetapi saat ini tidak memegang data jenis tersebut
Ada perbedaan semantik besar antara data tidak hadir dan data yang terdiri dari nilai default. Sedangkan yang kedua selalu mungkin, ada kasus-kasus yang mana ianya mustahil untuk DataHolder
untuk mendukung jenis data dan kemudian tidak tahan. Contoh yang meliputi:
HealthData
selalu ada pada setiap (vanilla)DataHolder
yang mendukungDisplayNameData selalu ada pada Player, tetapi mungkin tidak ada pada entitas lainnya.