Reload the previous value in VolatileField when calling refreshValue()

This commit is contained in:
Kristian S. Stangeland 2013-12-07 00:56:45 +01:00
parent d83655f2d3
commit e44f02e1fa

View File

@ -19,6 +19,8 @@ package com.comphenix.protocol.reflect;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import net.minecraft.util.com.google.common.base.Objects;
/** /**
* Represents a field that will revert to its original state when this class is garbaged collected. * Represents a field that will revert to its original state when this class is garbaged collected.
* *
@ -136,15 +138,23 @@ public class VolatileField {
} }
/** /**
* Ensure the previously set value is set. * Reapply the current changed value.
* <p>
* Also refresh the previously set value.
*/ */
public void refreshValue() { public void refreshValue() {
Object fieldValue = readFieldValue();
if (currentSet) { if (currentSet) {
try { // If they differ, we need to set them again
FieldUtils.writeField(field, container, current, forceAccess); if (!Objects.equal(current, fieldValue)) {
} catch (IllegalAccessException e) { previous = readFieldValue();
throw new RuntimeException("Unable to read field " + field.getName(), e); previousLoaded = true;
writeFieldValue(current);
} }
} else if (previousLoaded) {
// Update that too
previous = fieldValue;
} }
} }
@ -183,12 +193,32 @@ public class VolatileField {
private void ensureLoaded() { private void ensureLoaded() {
// Load the value if we haven't already // Load the value if we haven't already
if (!previousLoaded) { if (!previousLoaded) {
try { previous = readFieldValue();
previous = FieldUtils.readField(field, container, forceAccess); previousLoaded = true;
previousLoaded = true; }
} catch (IllegalAccessException e) { }
throw new RuntimeException("Unable to read field " + field.getName(), e);
} /**
* Read the content of the underlying field.
* @return The field value.
*/
private Object readFieldValue() {
try {
return FieldUtils.readField(field, container, forceAccess);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to read field " + field.getName(), e);
}
}
/**
* Write the given value to the underlying field.
* @param newValue - the new value.
*/
private void writeFieldValue(Object newValue) {
try {
FieldUtils.writeField(field, container, newValue, forceAccess);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unable to write field " + field.getName(), e);
} }
} }