Egyéni DataManipulators
A központi része az egyéni adatok DataManipulator. Hajtják végre, először el kell dönteni, ha azt akarom, hogy hozzon létre egy külön API, az egyéni adatok. Általában az a legjobb, ha külön az API-a végrehajtás (mint SpongeAPI nem), de ha nem látta más fejlesztők, akkor csak tedd mindketten ugyanabban az osztályban.
You’ll want to define an API method for each „unit” your data, such as a String
, int
, ItemStack or
a custom type like Home
. These units will be wrapped in a Value, which will allow it to be accessed
with Keys. There are various extensions of Value
depending on which object will be represented, such
as MapValue which provides the standard map operations, or BoundedComparableValue which can set
limits on the upper and lower bound of an Comparable objects like integers.
Most, válasszon, amely a AbstractData típusú, akkor meghosszabbítja. Amíg lehet végrehajtani a semmiből, ezek az absztrakt típusok eltávolítása sok a munka, amit meg kell tenni végrehajtási a szükséges módszereket. A teljes lista megtalálható org.spongepowered.api.adatok.manipulátor.változékony.közös. Lásd single-adatok-típusok, vagy :ref:`összetett-adatok-típusok alatt a megvalósítás részleteit, minden típus.
Létre kell hozni két különböző osztályok - ami változékony, illetve valósít meg DataManipulator az absztrakt típus, egy megváltoztathatatlan változata, amely végrehajtja ImmutableDataManipulator s a állandó absztrakt típus.
Megjegyzés
**** Kell az adatokat változékony, megváltoztathatatlan verziók kell végrehajtása.
Minden típusú, akkor meg kell adnunk azt az DataManipulator#asImmutable()/ asMutable() módszerek - ez olyan egyszerű, mint a másolás, a meglévő objektumok a kivitelező a másik változat is.
Values
Az érték vagány(s) kell egy értéket meg kíván kapni. Az alábbi példa mutatja, a ValueFactory. Ez ment meg bennünket, sok típus segítségével Szivacs már végre Érték tárgyakat. Attól függően, hogy milyen értéket hoz létre más módszerek hívni, mint createMapValue, createBoundedComparableValue, stb.
Kód, Például: Végrehajtási Érték Erőszakos
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.value.ValueFactory;
import org.spongepowered.api.data.value.mutable.Value;
import org.spongepowered.cookbook.myhomes.data.home.Home;
import org.spongepowered.cookbook.myhomes.data.Keys;
@Override
protected Value<Home> defaultHome() {
return Sponge.getRegistry().getValueFactory()
.createValue(Keys.DEFAULT_HOME, getValue(), null);
}
Megjegyzés: ez egy ImmutableDataManipulator inkább vissza egy ImmutableValue, hívja asImmutable() a visszatért Érték. Javasoljuk, hogy cache-e (például egy osztály mező) a megváltoztathatatlan verzió.
Minden Értéke is szüksége van egy :javadoc:`Kulcs`, hogy azonosítani, a példában látjuk is, mint a Kulcsok.DEFAULT_HOME. Hasonló értékek, használja a makeXKey() módszerek :javadoc:`KeyFactory, hogy hozzon létre egy `Kulcs` az értéke.
Meg kell adni egy TypeToken képviselő nyers írja be az értéket, majd egy TypeToken képviselő Érték. Neked is meg kell adnia DataQuery utat - ez a leggyakrabban használt serialize az Érték. Mint minden katalógus írja meg kell adnia egy egyedi AZONOSÍTÓ, név. Tedd ezt minden együtt van egy Kulcs a Értéks.
Kód, Például: Létrehozása Gomb
import org.spongepowered.api.data.DataQuery;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.key.KeyFactory;
import org.spongepowered.api.data.value.mutable.Value;
import org.spongepowered.api.data.value.mutable.Value;
import com.google.common.reflect.TypeToken;
import org.spongepowered.cookbook.myhomes.data.home.Home;
public static final Key<Value<Home>> DEFAULT_HOME = KeyFactory.makeSingleKey(
TypeToken.of(Home.class),
new TypeToken<Value<Home>>() {},
DataQuery.of("DefaultHome"), "myhomes:default_home", "Default Home");
Megjegyzés
TypeTokens are used by the server implementation to preserve the generic type of your values. They are created in one of two ways:
A nem-generikus típusok, használja a TypeToken.(MyType.class)`
A generikus típusok, hozzon létre egy névtelen osztályt TypeToken<MyGenericType<String>>() {}`
Sorozatkészítés
Ahhoz, hogy az adatok serializable hogy DataHolders vagy a config fájlok, akkor is kell végrehajtani ::javadoc::DataSerializable#toContainer(). Javasoljuk, hívja a szuper.toContainer() mivel ez tartalmazza a verzió DataSerializable#getContentVersion(). Növelni kell a változat minden alkalommal, amikor egy változás történt, hogy a formátum a megjelent adatok, használjuk :ref:`content-updaters, hogy lehetővé teszik, visszafelé kompatibilitás.
Megjegyzés
Ez nem szükséges akkor, egyszerű, egységes típusú, mint a már végre toContainer()`
Kód, Például: Végrehajtási toContainer
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.cookbook.myhomes.data.Keys;
@Override
public DataContainer toContainer() {
DataContainer container = super.toContainer();
// This is the simplest, but use whatever structure you want!
container.set(Keys.DEFAULT_HOME.getQuery(), this.defaultHome);
container.set(Keys.HOMES, this.homes);
return container;
}
Single Types
Egyes típusok igényel kis végrehajtás, mert sok a munka már megtörtént a AbstractSingleData type meghosszabbítja.
Az „egyszerű” absztrakt típusok a legegyszerűbb megvalósítani, de kizárólag csak a típusok az alábbi:
Boolean
Comparable
Integer
List
Map
CatalogType
Enum
Minden más típusú kell végrehajtani egyéni egyetlen típus, kiterjesztve AbstractSingleData. Ez lehetővé teszi, hogy meghatározza a saját egyetlen adat, amit típus akar, miközben még mindig a legtöbb munka.
Javaslat
The abstract implementations save the object for you in the constructor. You can access it in your implementation
by calling the getValue()
and getValueGetter()
methods.
Simple Single Types
Szinte minden a munka az ön számára egyszerű absztrakt típusok. Csak ennyit kell tennie:
Extend the relevant abstract type
át a Kulcs az adatok, maga az objektum, az alapértelmezett tárgy (ha az objektum null) a kivitelező
AbstractBoundedComparableData (and the immutable equivalent) additionally require minimum and maximum values that will be checked, as well as a Comparator.
Megjegyzés
List
and Mapped
single types must instead implement ListData
/ MappedData
(or the immutable
equivalent). This adds additional methods to allow Map-like/List-like behavior directly on the DataManipulator
.
A következő 3 módszerekkel meg kell határozni a változékony manipluators:
fill(DataHolder, MergeFunction)
should replace the data on your object with that of the given DataHolder
,
using the result of MergeFunction#merge()
.
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.merge.MergeFunction;
import org.spongepowered.cookbook.myhomes.data.friends.FriendsData;
import java.util.Optional;
@Override
public Optional<FriendsData> fill(DataHolder dataHolder, MergeFunction overlap) {
FriendsData merged = overlap.merge(this, dataHolder.get(FriendsData.class).orElse(null));
setValue(merged.friends().get());
return Optional.of(this);
}
from(DataContainer)
should overwrite its value with the one in the container and return itself, otherwise return
Optional.empty()
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataQuery;
import org.spongepowered.cookbook.myhomes.data.Keys;
import org.spongepowered.cookbook.myhomes.data.friends.FriendsData;
import org.spongepowered.cookbook.myhomes.data.friends.ImmutableFriendsData;
import com.google.common.collect.Maps;
import java.util.Optional;
import java.util.UUID;
@Override
public Optional<FriendsData> from(DataContainer container) {
if(container.contains(Keys.FRIENDS)) {
List<UUID> friends = container.getObjectList(Keys.FRIENDS.getQuery(), UUID.class).get();
return Optional.of(setValue(friends));
}
return Optional.empty();
}
copy()
should, as the name suggests, return a copy of itself with the same data.
import org.spongepowered.cookbook.myhomes.data.friends.FriendsData;
@Override
public FriendsData copy() {
return new FriendsDataImpl(getValue());
}
Custom Single Types
Amellett, hogy a , meg kell, hogy felülbírálja a következő módszereket:
getValueGetter()
should pass the Value
representing your data (see above).
toContainer()
should return a DataContainer
representing your data (see above).
Compound Types
Whereas single types only support one value, „compound” types support however many values you want. This is useful when multiple objects are grouped, such as FurnaceData. The downside, however, is that they are more complex to implement.
To start with, create all the Value
getters that your data will have. For each value, create a method to get and
set the raw object, which you’ll use later. For immutable data, only the getters are necessary.
Registering Values
Next, you’ll want to register these so that the Keys-based system can reference them. To do this, implement either DataManipulator#registerGettersAndSetters() or ImmutableDataManipulator#registerGetters() depending on whether the data is mutable or not.
For each value you must call:
registerKeyValue(Key, Supplier)
referencing theValue
getter for the given keyregisterFieldGetter(Key, Supplier)
referencing the getter method for the raw object defined aboveregisterFieldSetter(Key, Consumer)
referencing the setter method above if you are implementing the mutable version
We recommend using Java 8’s ::
syntax for easy Supplier
and Consumer
functions.
Code Example: Implementing Getters and Setters
import org.spongepowered.cookbook.myhomes.data.Keys
// registerGetters() for immutable implementation
@Override
protected void registerGettersAndSetters() {
registerKeyValue(Keys.DEFAULT_HOME, this::defaultHome);
registerKeyValue(Keys.HOMES, this::homes);
registerFieldGetter(Keys.DEFAULT_HOME, this::getDefaultHome);
registerFieldGetter(Keys.HOMES, this::getHomes);
// Only on mutable implementation
registerFieldSetter(Keys.DEFAULT_HOME, this::setDefaultHome);
registerFieldSetter(Keys.HOMES, this::setHomes);
}
fill(DataHolder, MergeFunction)
and from(DataContainer)
are similar to the implementations for single data,
but loading all your values.