Archiviert
13
0

Added a shallow clone method.

Removed the identity cloner, as it's no longer needed.
Dieser Commit ist enthalten in:
Kristian S. Stangeland 2012-12-27 11:13:42 +01:00
Ursprung dea725e1e3
Commit 695a4f3b0e
4 geänderte Dateien mit 51 neuen und 24 gelöschten Zeilen

Datei anzeigen

@ -30,6 +30,8 @@ import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import javax.annotation.Nullable;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.WorldType; import org.bukkit.WorldType;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
@ -38,13 +40,19 @@ import org.bukkit.inventory.ItemStack;
import com.comphenix.protocol.injector.StructureCache; import com.comphenix.protocol.injector.StructureCache;
import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.EquivalentConverter;
import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.FuzzyReflection;
import com.comphenix.protocol.reflect.ObjectWriter;
import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.reflect.cloning.AggregateCloner; import com.comphenix.protocol.reflect.cloning.AggregateCloner;
import com.comphenix.protocol.reflect.cloning.Cloner;
import com.comphenix.protocol.reflect.cloning.FieldCloner;
import com.comphenix.protocol.reflect.cloning.AggregateCloner.BuilderParameters;
import com.comphenix.protocol.reflect.instances.DefaultInstances;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.ChunkPosition; import com.comphenix.protocol.wrappers.ChunkPosition;
import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject; import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import com.google.common.base.Function;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
/** /**
@ -69,6 +77,21 @@ public class PacketContainer implements Serializable {
private static ConcurrentMap<Class<?>, Method> writeMethods = Maps.newConcurrentMap(); private static ConcurrentMap<Class<?>, Method> writeMethods = Maps.newConcurrentMap();
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap(); private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
// Used to clone packets
private static final AggregateCloner DEEP_CLONER = AggregateCloner.DEFAULT;
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner.newBuilder().
instanceProvider(DefaultInstances.DEFAULT).
andThen(new Function<BuilderParameters, Cloner>() {
@Override
public Cloner apply(@Nullable BuilderParameters param) {
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
// Use a default writer with no concept of cloning
writer = new ObjectWriter();
}};
}
}).
build();
/** /**
* Creates a packet container for a new packet. * Creates a packet container for a new packet.
* @param id - ID of the packet to create. * @param id - ID of the packet to create.
@ -364,12 +387,29 @@ public class PacketContainer implements Serializable {
return id; return id;
} }
/**
* Create a shallow copy of the current packet.
* <p>
* This merely writes the content of each field to the new class directly,
* without performing any expensive copies.
*
* @return A shallow copy of the current packet.
*/
public PacketContainer shallowClone() {
Object clonedPacket = SHALLOW_CLONER.clone(getHandle());
return new PacketContainer(getID(), clonedPacket);
}
/** /**
* Create a deep copy of the current packet. * Create a deep copy of the current packet.
* <p>
* This will perform a full copy of the entire object tree, only skipping
* known immutable objects and primitive types.
*
* @return A deep copy of the current packet. * @return A deep copy of the current packet.
*/ */
public PacketContainer deepClone() { public PacketContainer deepClone() {
Object clonedPacket = AggregateCloner.DEFAULT.clone(getHandle()); Object clonedPacket = DEEP_CLONER.clone(getHandle());
return new PacketContainer(getID(), clonedPacket); return new PacketContainer(getID(), clonedPacket);
} }

Datei anzeigen

@ -47,6 +47,11 @@ public class AggregateCloner implements Cloner {
} }
} }
/**
* Represents a builder for aggregate (combined) cloners.
*
* @author Kristian
*/
public static class Builder { public static class Builder {
private List<Function<BuilderParameters, Cloner>> factories = Lists.newArrayList(); private List<Function<BuilderParameters, Cloner>> factories = Lists.newArrayList();
private BuilderParameters parameters; private BuilderParameters parameters;
@ -75,7 +80,7 @@ public class AggregateCloner implements Cloner {
*/ */
public Builder andThen(final Class<? extends Cloner> type) { public Builder andThen(final Class<? extends Cloner> type) {
// Use reflection to generate a factory on the fly // Use reflection to generate a factory on the fly
return orCloner(new Function<BuilderParameters, Cloner>() { return andThen(new Function<BuilderParameters, Cloner>() {
@Override @Override
public Cloner apply(@Nullable BuilderParameters param) { public Cloner apply(@Nullable BuilderParameters param) {
Object result = param.typeConstructor.create(type); Object result = param.typeConstructor.create(type);
@ -97,7 +102,7 @@ public class AggregateCloner implements Cloner {
* @param factory - factory constructing the next cloner. * @param factory - factory constructing the next cloner.
* @return This builder. * @return This builder.
*/ */
public Builder orCloner(Function<BuilderParameters, Cloner> factory) { public Builder andThen(Function<BuilderParameters, Cloner> factory) {
factories.add(factory); factories.add(factory);
return this; return this;
} }

Datei anzeigen

@ -10,11 +10,11 @@ import com.comphenix.protocol.reflect.instances.InstanceProvider;
* @author Kristian * @author Kristian
*/ */
public class FieldCloner implements Cloner { public class FieldCloner implements Cloner {
private final Cloner defaultCloner; protected Cloner defaultCloner;
private final InstanceProvider instanceProvider; protected InstanceProvider instanceProvider;
// Used to clone objects // Used to clone objects
private final ObjectWriter writer; protected ObjectWriter writer;
/** /**
* Constructs a field cloner that copies objects by reading and writing the internal fields directly. * Constructs a field cloner that copies objects by reading and writing the internal fields directly.

Datei anzeigen

@ -1,18 +0,0 @@
package com.comphenix.protocol.reflect.cloning;
/**
* Represents a cloner that simply returns the given object.
*
* @author Kristian
*/
public class IdentityCloner implements Cloner {
@Override
public boolean canClone(Object source) {
return true;
}
@Override
public Object clone(Object source) {
return source;
}
}