mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-01 14:07:43 +01:00
Add experimental tag update methods
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
2720d9ada2
commit
cb01b08b04
@ -0,0 +1,38 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import org.openjdk.jcstress.annotations.Actor;
|
||||
import org.openjdk.jcstress.annotations.JCStressTest;
|
||||
import org.openjdk.jcstress.annotations.Outcome;
|
||||
import org.openjdk.jcstress.annotations.State;
|
||||
import org.openjdk.jcstress.infra.results.L_Result;
|
||||
|
||||
import static org.openjdk.jcstress.annotations.Expect.ACCEPTABLE;
|
||||
|
||||
@JCStressTest
|
||||
@Outcome(id = "null", expect = ACCEPTABLE)
|
||||
@Outcome(id = "3", expect = ACCEPTABLE)
|
||||
@Outcome(id = "4", expect = ACCEPTABLE)
|
||||
@Outcome(id = "10", expect = ACCEPTABLE)
|
||||
@Outcome(id = "11", expect = ACCEPTABLE)
|
||||
@State
|
||||
public class TagUpdateTest {
|
||||
private static final Tag<Integer> TAG = Tag.Integer("key");
|
||||
|
||||
private final TagHandler handler = TagHandler.newHandler();
|
||||
|
||||
@Actor
|
||||
public void actor1() {
|
||||
handler.updateAndGetTag(TAG, integer -> integer == null ? 3 : integer + 1);
|
||||
}
|
||||
|
||||
@Actor
|
||||
public void actor2() {
|
||||
handler.updateAndGetTag(TAG, integer -> integer == null ? 10 : integer + 1);
|
||||
}
|
||||
|
||||
@Actor
|
||||
public void arbiter(L_Result r) {
|
||||
r.r1 = handler.getTag(TAG);
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,12 @@ package net.minestom.server.tag;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.UnknownNullability;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompoundLike;
|
||||
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* Represents an element which can read and write {@link Tag tags}.
|
||||
*/
|
||||
@ -46,6 +49,18 @@ public interface TagHandler extends TagReadable, TagWritable {
|
||||
*/
|
||||
@NotNull NBTCompound asCompound();
|
||||
|
||||
@ApiStatus.Experimental
|
||||
<T> void updateTag(@NotNull Tag<T> tag,
|
||||
@NotNull UnaryOperator<@UnknownNullability T> value);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
<T> @UnknownNullability T updateAndGetTag(@NotNull Tag<T> tag,
|
||||
@NotNull UnaryOperator<@UnknownNullability T> value);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
<T> @UnknownNullability T getAndUpdateTag(@NotNull Tag<T> tag,
|
||||
@NotNull UnaryOperator<@UnknownNullability T> value);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
static @NotNull TagHandler newHandler() {
|
||||
return new TagHandlerImpl();
|
||||
|
@ -104,6 +104,25 @@ final class TagHandlerImpl implements TagHandler {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <T> void updateTag(@NotNull Tag<T> tag, @NotNull UnaryOperator<@UnknownNullability T> value) {
|
||||
setTag(tag, value.apply(getTag(tag)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <T> @UnknownNullability T updateAndGetTag(@NotNull Tag<T> tag, @NotNull UnaryOperator<@UnknownNullability T> value) {
|
||||
final T next = value.apply(getTag(tag));
|
||||
setTag(tag, next);
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized <T> @UnknownNullability T getAndUpdateTag(@NotNull Tag<T> tag, @NotNull UnaryOperator<@UnknownNullability T> value) {
|
||||
final T prev = getTag(tag);
|
||||
setTag(tag, value.apply(prev));
|
||||
return prev;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull TagReadable readableCopy() {
|
||||
return updatedCache();
|
||||
|
57
src/test/java/net/minestom/server/tag/TagAtomicTest.java
Normal file
57
src/test/java/net/minestom/server/tag/TagAtomicTest.java
Normal file
@ -0,0 +1,57 @@
|
||||
package net.minestom.server.tag;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class TagAtomicTest {
|
||||
|
||||
@Test
|
||||
public void update() {
|
||||
var tag = Tag.Integer("coin");
|
||||
var handler = TagHandler.newHandler();
|
||||
handler.updateTag(tag, integer -> {
|
||||
assertNull(integer);
|
||||
return 5;
|
||||
});
|
||||
assertEquals(5, handler.getTag(tag));
|
||||
handler.updateTag(tag, integer -> {
|
||||
assertEquals(5, integer);
|
||||
return 10;
|
||||
});
|
||||
assertEquals(10, handler.getTag(tag));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateAndGet() {
|
||||
var tag = Tag.Integer("coin");
|
||||
var handler = TagHandler.newHandler();
|
||||
var result = handler.updateAndGetTag(tag, integer -> {
|
||||
assertNull(integer);
|
||||
return 5;
|
||||
});
|
||||
assertEquals(5, result);
|
||||
result = handler.updateAndGetTag(tag, integer -> {
|
||||
assertEquals(5, integer);
|
||||
return 10;
|
||||
});
|
||||
assertEquals(10, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAndUpdate() {
|
||||
var tag = Tag.Integer("coin");
|
||||
var handler = TagHandler.newHandler();
|
||||
var result = handler.getAndUpdateTag(tag, integer -> {
|
||||
assertNull(integer);
|
||||
return 5;
|
||||
});
|
||||
assertNull(result);
|
||||
result = handler.getAndUpdateTag(tag, integer -> {
|
||||
assertEquals(5, integer);
|
||||
return 10;
|
||||
});
|
||||
assertEquals(5, result);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user