Skip to content

Instantly share code, notes, and snippets.

@ryantheleach
Last active October 26, 2016 07:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ryantheleach/ada719d50113baf40054c3bb21551761 to your computer and use it in GitHub Desktop.
Save ryantheleach/ada719d50113baf40054c3bb21551761 to your computer and use it in GitHub Desktop.
package au.id.rleach.testdata;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataQuery;
import org.spongepowered.api.data.DataSerializable;
import org.spongepowered.api.data.MemoryDataContainer;
import org.spongepowered.api.data.Queries;
import org.spongepowered.api.world.Location;
import org.spongepowered.api.world.World;
public class Home implements DataSerializable {
static final DataQuery LOCATION = DataQuery.of("location");
Location<World> location;
public Home(Location<World> out) {
this.location = out;
}
@Override public int getContentVersion() {
return 1;
}
@Override public DataContainer toContainer() {
final DataContainer container = new MemoryDataContainer();
container.set(Queries.CONTENT_VERSION, getContentVersion());
container.set(LOCATION, location.toContainer());
return container;
}
}
package au.id.rleach.testdata;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.api.data.persistence.DataBuilder;
import org.spongepowered.api.data.persistence.InvalidDataException;
import org.spongepowered.api.world.Location;
import java.util.Optional;
public class HomeBuilder extends AbstractDataBuilder<Home> {
protected HomeBuilder() {
super(Home.class, 1);
}
@Override protected Optional<Home> buildContent(DataView container) throws InvalidDataException {
//todo: Raw class warning.
//What does it mean if the location builder isn't present?
DataBuilder<Location> locBuilder = Sponge.getDataManager().getBuilder(Location.class).get();
Optional<Object> locationView = container.get(Home.LOCATION);
try{
return locationView
.map(view -> (DataView)view)
.flatMap(locBuilder::build)
.map(Home::new);
} catch (final Throwable e) {
throw new InvalidDataException(e);
}
}
}
package au.id.rleach.testdata;
import org.spongepowered.api.data.manipulator.DataManipulator;
import org.spongepowered.api.data.value.mutable.Value;
public interface HomeData extends DataManipulator<HomeData, ImmutableHomeData> {
Value<Home> defaultHome();
Home getValue();
}
package au.id.rleach.testdata;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.DataView;
import org.spongepowered.api.data.manipulator.DataManipulatorBuilder;
import org.spongepowered.api.data.persistence.AbstractDataBuilder;
import org.spongepowered.api.data.persistence.InvalidDataException;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.User;
import java.util.Optional;
public class HomeDataBuilder extends AbstractDataBuilder<HomeData> implements DataManipulatorBuilder<HomeData, ImmutableHomeData> {
protected HomeDataBuilder() {
super(HomeData.class, 1);
}
@Override public HomeData create() {
return new HomeDataImpl();
}
@Override public Optional<HomeData> createFrom(final DataHolder dataHolder) {
if(!(dataHolder instanceof User) || !(dataHolder instanceof Player)) return Optional.empty();
return this.create().fill(dataHolder);
}
@Override protected Optional<HomeData> buildContent(DataView container) throws InvalidDataException {
return this.create().from(container.copy());
}
}
package au.id.rleach.testdata;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.DataContainer;
import org.spongepowered.api.data.DataHolder;
import org.spongepowered.api.data.manipulator.mutable.common.AbstractSingleData;
import org.spongepowered.api.data.merge.MergeFunction;
import org.spongepowered.api.data.value.mutable.Value;
import java.util.Optional;
public class HomeDataImpl extends AbstractSingleData<Home, HomeData, ImmutableHomeData> implements HomeData {
public HomeDataImpl(Home value) {
super(value, MyKeys.DEFAULT_HOME);
}
// It's best to provide an empty constructor with "default" values
public HomeDataImpl() {
this(null);
}
// Override if you have a separate interface
@Override
public Value<Home> defaultHome() {
return getValueGetter();
}
@Override public Home getValue() {
return super.getValue();
}
@Override
public int getContentVersion() {
// Update whenever the serialization format changes
return 1;
}
@Override
protected Value<Home> getValueGetter() {
/* We recommend making this a field if implementing this immutable version,
as it will never change */
return Sponge.getRegistry().getValueFactory().createValue(MyKeys.DEFAULT_HOME, getValue(), null);
}
// asMutable() when implementing immutable data
@Override
public ImmutableHomeData asImmutable() {
return new ImmHomeDataImpl(getValue(), MyKeys.DEFAULT_HOME);
}
// Only required on mutable implementation
@Override
public Optional<HomeData> fill(DataHolder dataHolder, MergeFunction overlap) {
//suspicious orElse null followed immediately by calling a method.
HomeData merged = overlap.merge(this, dataHolder.get(HomeData.class).orElse(null));
setValue(merged.getValue());
return Optional.of(this);
}
// Only required on mutable implementation
@Override
public Optional<HomeData> from(DataContainer container) {
if(container.contains(MyKeys.DEFAULT_HOME)) {
// Loads the structure defined in toContainer
setValue(container.getSerializable(MyKeys.DEFAULT_HOME.getQuery(), Home.class).get());
return Optional.of(this);
}
return Optional.empty();
}
// Only required on mutable implementation
@Override
public HomeData copy() {
return new HomeDataImpl(getValue());
}
@Override
public DataContainer toContainer() {
DataContainer container = super.toContainer();
// This is the simplest, but use whatever structure you want!
container.set(MyKeys.DEFAULT_HOME.getQuery(), getValue());
return container;
}
}
package au.id.rleach.testdata;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.manipulator.immutable.common.AbstractImmutableSingleData;
import org.spongepowered.api.data.value.BaseValue;
import org.spongepowered.api.data.value.immutable.ImmutableValue;
public class ImmHomeDataImpl extends AbstractImmutableSingleData<Home, ImmutableHomeData, HomeData> implements ImmutableHomeData {
protected ImmHomeDataImpl(Home value, Key<? extends BaseValue<Home>> usedKey) {
super(value, usedKey);
}
@Override protected ImmutableValue<?> getValueGetter() {
return Sponge.getRegistry().getValueFactory().createValue(MyKeys.DEFAULT_HOME, this.getValue(), null).asImmutable();
}
@Override public HomeData asMutable() {
return new HomeDataImpl(this.getValue());
}
@Override public int getContentVersion() {
return 1;
}
}
package au.id.rleach.testdata;
import org.spongepowered.api.data.manipulator.ImmutableDataManipulator;
public interface ImmutableHomeData extends ImmutableDataManipulator<ImmutableHomeData, HomeData> {
}
package au.id.rleach.testdata;
import static org.spongepowered.api.data.DataQuery.of;
import com.google.common.reflect.TypeToken;
import org.spongepowered.api.data.key.Key;
import org.spongepowered.api.data.key.KeyFactory;
import org.spongepowered.api.data.value.mutable.Value;
public class MyKeys {
public static final TypeToken<Home> HOME_TOKEN = new TypeToken<Home>() {
};
public static final TypeToken<Value<Home>> HOME_VALUE_TOKEN = new TypeToken<Value<Home>>() {
};
public static Key<Value<Home>> DEFAULT_HOME = KeyFactory.makeSingleKey(
HOME_TOKEN,
HOME_VALUE_TOKEN,
of("DefaultHome"),
"testdata:default_home",
"Default Home"
);
}
package au.id.rleach.testdata;
import com.google.inject.Inject;
import org.slf4j.Logger;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.data.manipulator.mutable.entity.HealthData;
import org.spongepowered.api.data.manipulator.mutable.entity.JoinData;
import org.spongepowered.api.data.value.mutable.MutableBoundedValue;
import org.spongepowered.api.data.value.mutable.Value;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.filter.Getter;
import org.spongepowered.api.event.game.state.GameInitializationEvent;
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
import org.spongepowered.api.event.network.ClientConnectionEvent;
import org.spongepowered.api.plugin.Plugin;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColors;
import org.spongepowered.api.text.format.TextStyles;
import java.time.Instant;
import java.util.Optional;
@Plugin(
id = "testdata",
name = "Testdata",
version = "1.0-SNAPSHOT"
)
public class TestDataPlugin {
@Inject private Logger logger;
@Listener
public void onServerStart(GameInitializationEvent event) {
Sponge.getDataManager().register(HomeData.class, ImmutableHomeData.class, new HomeDataBuilder());
Sponge.getDataManager().registerBuilder(Home.class, new HomeBuilder());
}
@Listener
public void onPlayerJoin(ClientConnectionEvent.Join event, @Getter("getTargetEntity") Player player) {
// The text message could be configurable, check the docs on how to do so!
player.sendMessage(Text.of(TextColors.AQUA, TextStyles.BOLD, "Hi " + player.getName()));
Optional<HealthData> data_ = player.get(HealthData.class);
HealthData data = data_.get(); //don't shoot me it's an example
MutableBoundedValue<Double> currentHealth = data.health();
currentHealth.transform(a->a*2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment