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 pemberian DataManipulator

  • DataHolder mendukung DataManipulator, 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 mendukung

  • DisplayNameData selalu ada pada Player, tetapi mungkin tidak ada pada entitas lainnya.