Nesneleri Serileştirme
Yapılandırma kitaplığı ayrıca nesnelerin otomatik serileştirilmesi ve serileştirilmesi için gerekli araçları da sağlar. Varsayılan olarak, veri türleri kümesi (de)serialized: hale getirebilir: diğer dizeler arasında, ints, doubles, UUIDs, Lists (seri hale getirilebilir değerlerin) ve Maps (her iki anahtar ve değer de seri hale getirilebilir). Ancak, özel veri yapılarınızı bir yapılandırma dosyasına yazmak istiyorsanız, bu yeterli olmayacaktır.
Bir oyuncunun kaç elmas kazandığını izleyen bir veri yapısı düşünün. Biraz benzeyebilir:
public class DiamondCounter {
private UUID playerUUID;
private int diamonds;
...
}
Ayrıca bu alanlara erişmek için bazı yöntemler varsayalım, bu vb her ikisi de güzel bir yapıcı ayarı.
Özel bir TypeSerializer oluşturma
Bu tür bir veri yapısı yazma ve yükleme çok basit, özel bir :javadoc:`TypeSerializer`sağlar. ``TypeSerializer`` arabirimi, verileri bir nesneden bir yapılandırma düğümüne yazmak için iki yöntem ve belirli bir yapılandırma düğümünden bir nesne oluşturmak için arabirim sağlar.
import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
public class DiamondCounterSerializer implements TypeSerializer<DiamondCounter> {
@Override
public DiamondCounter deserialize(TypeToken<?> type, ConfigurationNode value)
throws ObjectMappingException {
UUID player = value.getNode("player").getValue(TypeToken.of(UUID.class));
int diamonds = value.getNode("diamonds").getInt();
return new DiamondCounter(player, diamonds);
}
@Override
public void serialize(TypeToken<?> type, DiamondCounter obj, ConfigurationNode value)
throws ObjectMappingException {
value.getNode("player").setValue(obj.getPlayerUUID());
value.getNode("diamonds").setValue(obj.getDiamonds());
}
}
Daha sonra bu``TypeSerializer`` yapılandırılarak kaydedilir. Bu genellikle, varsayılan TypeSerializerCollection veya yerel olarak, yapılandırmanızı yüklerken ConfigurationOptions içinde belirtilerek yapılabilir.
** Kod örneği: Bir TypeSerializer’ın genel olarak kaydedilmesi **
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;
TypeSerializers.getDefaultSerializers().registerType(TypeToken.of(DiamondCounter.class), new DiamondCounterSerializer());
** Kod örneği: Bir TypeSerializer’ın yerel olarak kaydedilmesi **
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializerCollection;
import ninja.leaping.configurate.objectmapping.serialize.TypeSerializers;
TypeSerializerCollection serializers = TypeSerializers.getDefaultSerializers().newChild();
serializers.registerType(TypeToken.of(DiamondCounter.class), new DiamondCounterSerializer());
ConfigurationOptions options = ConfigurationOptions.defaults().setSerializers(serializers);
ConfigurationNode rootNode = someConfigurationLoader.load(options);
Uyarı
Eğer kendi eklentiniz tarafından kullanılmayan türler için özel bir TypeSerializer
sağladıysanız, TypeSerializer
’ın üzerine yazılmasından kaynaklanan diğer eklentiler veya Sponge ile uyumlu olmayanlar eklentiler için yerel olarak kaydetmelisiniz.
ObjectMappers kullanımı
Çoğu durumda serileştirme, harita alanlarını yapılandırma düğümlerine çevirir, böyle bir TypeSerializer
yazmak oldukça sıkıcı bir durum ve yapılandırmada kendi başına yapılmasını istediğimiz bir durumdur. Bunu :javadoc: ConfigSerializable ve :javadoc:` Setting` bölümlerinde açıklayalım.
import ninja.leaping.configurate.objectmapping.Setting;
import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@ConfigSerializable
public class DiamondCounter {
@Setting(value="player", comment="Player UUID")
private UUID playerUUID;
@Setting(comment="Number of diamonds mined")
private int diamonds;
...
}
Yukarıdaki örnek şimdi daha fazla kayıt olmadan yapılandırma düğümlerinden seri hale getirilebilir. @Setting
açıklamaları, bir biçim düğümünü açıklama yapılan alanla eşleştirir. İki isteğe bağlı parametre, value
ve comment
kabul eder. Eğer value
parametresi mevcutsa, alanın kaydedileceği düğümün adını tanımlar. Eğer mevcut değilse alanın adı kullanılır. Yukarıdaki örnekte, açıklama, playerUUID
alanının içeriğinin “playerUUID” ile yorumlandığı ‘’player’’ düğümüne kaydedilmesini sağlar. Bununla birlikte, diamonds
alanı, tam açıklamanın sadece bir yorum belirttiği için bu tam ad altında kaydedilecektir. Uygulama, yorumlanan yapılandırma düğümlerini destekliyorsa, bu yorum yapılandırmaya yazılır, yoksa atılır.
Tüyo
@Setting(value ="someNode")
yerine @Setting("someNode")
kısaltmasını da kullanabilirsiniz
@ConfigSerializable
annotation’ı class için Configurate’in ObjectMapper oluşturmasına olanak sağladığından dolayı başka kayıtlara muhtaç kalınmasını engeller. Tek sınırlama Configurate’in belirlenmiş yerleri doldurabilmek için boş bir constructor’a ihtiyaç duymasıdır.
Özel bir ObjectMapperFactory sağlanıyor
Kısıtlama, farklı bir ObjectMapperFactory kullandığımızda, örneğin GuiceObjectMapperFactory, ortadan kaldırılabilir. Bu durumda boş bir constuctor’a ihtiyaç duyulması yerine guice’un dependency injenction ile oluşturabileceği tüm class’larda çalışır. Bu ayrıca @Inject
ve @Setting
gibi belirlenmiş yerlerin karışımına da olanak sağlar.
Eklentiniz, dependency injection (bkz Bağımlılık Enjeksiyonu) kullanıp bunu ConfigurationOptions``a okutarak``GuiceObjectMapperFactory
kullanabilir.
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
import org.spongepowered.api.plugin.Plugin;
import com.google.inject.Inject;
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
import ninja.leaping.configurate.loader.ConfigurationLoader;
import ninja.leaping.configurate.objectmapping.GuiceObjectMapperFactory;
@Plugin(name="IStoleThisFromZml", id="shamelesslystolen", version="0.8.15")
public class StolenCodeExample {
@Inject private GuiceObjectMapperFactory factory;
@Inject private ConfigurationLoader<CommentedConfigurationNode> loader;
@Listener
public void enable(GamePreInitializationEvent event) {
CommentedConfigurationNode node =
loader.load(ConfigurationOptions.defaults().setObjectMapperFactory(factory));
DiamondCounter myDiamonds = node.getValue(TypeToken.of(DiamondCounter.class));
}
}
Not
Yukarıda ki kod bir örnektir ve özlük için uygun bir istisna işlemesinden yoksundur.