Serializing Data
Sementara ImmutableDataManipulator merupakan cara yang baik untuk menyimpan data saat server sedang berjalan, tidak akan bertahan selama mengulang kembali. Bagaimanapun, setiap DataManipulator mengimplementasikan interface DataSerializable sehingga dapat diserialkan ke DataContainer dan dibuat tidak serial lagi oleh DataBuilder.
Setelah konversi awal ini dari DataManipulator
khusus ke struktur yang lebih umum, DataContainer
dapat diproses lebih lanjut.
Wadah Data dan Tampilan Data
DataView adalah struktur umum untuk memegang semua jenis data. Mendukung beberapa nilai dan bahkan DataView
s bersarang sebagai suatu nilai, sehingga mengizinkan untuk struktur seperti-tree. Setiap nilai diidentifikasikan oleh DataQuery. DataContainer
merupakan akar DataView
.
Setiap DataSerializable
menyediakan metode toContainer()
yang akan membuat dan mengembalikan DataContainer
. Sebagai contoh, memanggil toContainer()
pada sebuah instance HealthData akan menghasilkan sebuah DataContainer
yang berisi dua nilai, satu untuk kesehatan saat ini dan satu untuk kesehatan maksimal, masing-masing diidentifikasi oleh DataQuery
yang berhubungan dengan Key
.
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.key.Keys;
DataContainer serializedHealth = healthData.toContainer();
double currentHealth = serializedHealth.getDouble(Keys.HEALTH.getQuery()).get();
currentHealth == healthData.health().get(); // true
Mengkonversi container ini kembali ke instance HealthData
dilakukan oleh DataBuilder
yang sesuai. itu didaftarkan dan dikelola oleh DataManager. Dapat diperoleh salah satunya dari sebuah instance Game yang valid atau menggunakan kelas utilitas Sponge. DataManager
menyediakan sebuah metode untuk mendapatkan DataBuilder
yang sesuai memisahkan serial kelas yang diberikan dan tambahan metode singkat untuk mendapatkan DataBuilder
dan membuatnya melakukan pemisahan serial dalam satu langkah. Kedua contoh berikut sama secara fungsional.
Kode Contoh: Deserialization, jalan panjang
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.manipulator.mutable.entity.HealthData;
import org.spongepowered.api.util.persistence.DataBuilder;
import java.util.Optional;
public Optional<HealthData> deserializeHealth(DataView container) {
final Optional<DataBuilder<HealthData>> builder = Sponge.getDataManager().getBuilder(HealthData.class);
if (builder.isPresent()) {
return builder.get().build(container);
}
return Optional.empty();
}
Kode Contoh: Deserialization, cara singkat
import org.spongepowered.api.data.manipulator.mutable.entity.HealthData;
public Optional<HealthData> deserializeHealth(DataView container) {
return Sponge.getDataManager().deserialize(HealthData.class, container);
}
DeserializeHealth
fungsi akan kembali Optional.kosong()
jika tidak ada DataBuilder
terdaftar HealthData...` atau disediakan ``DataContainer
adalah kosong. Jika data yang tidak valid hadir dalam DataContainer
, InvalidDataException akan dilemparkan.
DataTranslator
Dalam Spons, umumnya implementasi MemoryDataView dan MemoryDataContainer yang digunakan, yang berada di memori saja dan dengan demikian tidak akan bertahan lebih dari satu server restart. Dalam rangka untuk terus-menerus menyimpan DataContainer
, hal pertama yang harus diubah menjadi storable representasi.
Menggunakan DataTranslators#CONFIGURATION_NODE pelaksanaan DataTranslator, kita dapat mengkonversi DataView ke ConfigurationNode dan sebaliknya. ConfigurationNodes kemudian dapat dibaca dan ditulis gigih file menggunakan Configurate Perpustakaan.
** Kode Contoh: Serializing contoh HealthData untuk configurate **
import ninja.leaping.configurate.ConfigurationNode;
import org.spongepowered.api.data.persistence.DataTranslator;
import org.spongepowered.api.data.persistence.DataTranslators;
public ConfigurationNode translateToConfig(HealthData data) {
final DataTranslator<ConfigurationNode> translator = DataTranslators.CONFIGURATION_NODE;
final DataView container = data.toContainer();
return translator.translate(container);
}
** Contoh Kode: Deserializing contoh HealthData dari Configurate **
import java.util.Optional;
public Optional<HealthData> translateFromConfig(ConfigurationNode node) {
final DataTranslator<ConfigurationNode> translator = DataTranslators.CONFIGURATION_NODE;
final DataView container = translator.translate(node);
return deserializeHealth(container);
}
Format Data
Alternatif untuk menggunakan DataTranslator adalah dengan menggunakan DataFormat, yang memungkinkan anda untuk menyimpan DataContainer di HOCON, JSON atau NBT format. Anda juga dapat menciptakan Datakontainer menggunakan DataFormat. Spons yang disediakan DataFormat implementasi tersedia di DataFormat kelas.
Sebagai contoh, kita dapat menggunakan DataFormat#JSON DataFormat yang memungkinkan kita untuk membuat JSON representasi dari Datakontainer. Pengeluaran JSON kemudian bisa dengan mudah disimpan dalam database. Kita kemudian dapat menggunakan yang sama DataFormat untuk menciptakan asli Datakontainer dari JSON ini bila diperlukan.
Impor untuk contoh kode
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.persistence.DataFormats;
import org.spongepowered.api.item.inventory.ItemStackSnapshot;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
** Contoh Kode: Serializing sebuah ItemStackSnapshot ke format JSON **
String json = DataFormats.JSON.write(itemStack.toContainer());
** Contoh Kode: Deserializing sebuah ItemStackSnapshot dari format JSON **
DataContainer container = DataFormats.JSON.read(json);
** Contoh Kode: Menulis sebuah ItemStackSnapshot ke file menggunakan NBT **
public void writeItemStackSnapshotToFile(ItemStackSnapshot itemStackSnapshot, Path path) {
DataContainer dataContainer = itemStackSnapshot.toContainer();
try (OutputStream outputStream = Files.newOutputStream(path)) {
DataFormats.NBT.writeTo(outputStream, dataContainer);
} catch (IOException e) {
// For the purposes of this example, we just print the error to the console. However,
// as this exception indicates the file didn't save, you should handle this in a way
// more suitable for your plugin.
e.printStackTrace();
}
}
** Contoh Kode: Membaca ItemStackSnapshot dari sebuah file menggunakan NBT **
public Optional<ItemStackSnapshot> readItemStackSnapshotFromFile(Path path) {
try (InputStream inputStream = Files.newInputStream(path)) {
DataContainer dataContainer = DataFormats.NBT.readFrom(inputStream);
return Sponge.getDataManager().deserialize(ItemStackSnapshot.class, dataContainer);
} catch (IOException e) {
e.printStackTrace();
}
return Optional.empty();
}