Skip to content

Commit 1acb6c1

Browse files
committed
GenericMapSyncHandler
1 parent 27cb91e commit 1acb6c1

File tree

2 files changed

+195
-3
lines changed

2 files changed

+195
-3
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
package com.cleanroommc.modularui.value.sync;
2+
3+
import com.cleanroommc.modularui.utils.ICopy;
4+
import com.cleanroommc.modularui.utils.serialization.IByteBufAdapter;
5+
import com.cleanroommc.modularui.utils.serialization.IByteBufDeserializer;
6+
import com.cleanroommc.modularui.utils.serialization.IByteBufSerializer;
7+
import com.cleanroommc.modularui.utils.serialization.IEquals;
8+
9+
import net.minecraft.network.PacketBuffer;
10+
11+
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
12+
13+
import java.io.IOException;
14+
import java.util.Collections;
15+
import java.util.Map;
16+
import java.util.Objects;
17+
import java.util.function.Consumer;
18+
import java.util.function.Supplier;
19+
20+
public class GenericMapSyncHandler<K, V> extends ValueSyncHandler<Map<K, V>> {
21+
22+
private final Supplier<Map<K, V>> getter;
23+
private final Consumer<Map<K, V>> setter;
24+
private final IByteBufDeserializer<K> keyDeserializer;
25+
private final IByteBufDeserializer<V> valueDeserializer;
26+
private final IByteBufSerializer<K> keySerializer;
27+
private final IByteBufSerializer<V> valueSerializer;
28+
private final IEquals<V> equals;
29+
private final ICopy<K> keyCopy;
30+
private final ICopy<V> valueCopy;
31+
private final Map<K, V> cache = new Object2ObjectOpenHashMap<>();
32+
33+
public GenericMapSyncHandler(Supplier<Map<K, V>> getter,
34+
Consumer<Map<K, V>> setter,
35+
IByteBufDeserializer<K> keyDeserializer,
36+
IByteBufDeserializer<V> valueDeserializer,
37+
IByteBufSerializer<K> keySerializer,
38+
IByteBufSerializer<V> valueSerializer,
39+
IEquals<V> equals,
40+
ICopy<K> keyCopy,
41+
ICopy<V> valueCopy) {
42+
this.getter = getter;
43+
this.setter = setter;
44+
this.keyDeserializer = keyDeserializer;
45+
this.valueDeserializer = valueDeserializer;
46+
this.keySerializer = keySerializer;
47+
this.valueSerializer = valueSerializer;
48+
this.equals = equals != null ? IEquals.wrapNullSafe(equals) : Objects::equals;;
49+
this.keyCopy = keyCopy != null ? keyCopy : ICopy.ofSerializer(keySerializer, keyDeserializer);;
50+
this.valueCopy = valueCopy != null ? valueCopy : ICopy.ofSerializer(valueSerializer, valueDeserializer);;
51+
}
52+
53+
@Override
54+
public void setValue(Map<K, V> value, boolean setSource, boolean sync) {
55+
this.cache.clear();
56+
for (Map.Entry<K, V> entry : value.entrySet()) {
57+
this.cache.put(this.keyCopy.createDeepCopy(entry.getKey()), this.valueCopy.createDeepCopy(entry.getValue()));
58+
}
59+
if (setSource && this.setter != null) {
60+
this.setter.accept(value);
61+
}
62+
if (sync) {
63+
sync(0, this::write);
64+
}
65+
}
66+
67+
@Override
68+
public boolean updateCacheFromSource(boolean isFirstSync) {
69+
Map<K, V> map = this.getter.get();
70+
if (isFirstSync || didValuesChange(map)) {
71+
setValue(map, false, false);
72+
return true;
73+
}
74+
return false;
75+
}
76+
77+
protected boolean didValuesChange(Map<K, V> value) {
78+
if (this.cache.size() != value.size()) return true;
79+
for (Map.Entry<K, V> entry : this.cache.entrySet()) {
80+
if (!value.containsKey(entry.getKey())) return true;
81+
V v = value.get(entry.getKey());
82+
if (!this.equals.areEqual(entry.getValue(), v)) return true;
83+
}
84+
return false;
85+
}
86+
87+
@Override
88+
public void write(PacketBuffer buffer) throws IOException {
89+
buffer.writeVarInt(this.cache.size());
90+
for (Map.Entry<K, V> entry : this.cache.entrySet()) {
91+
this.keySerializer.serialize(buffer, entry.getKey());
92+
this.valueSerializer.serialize(buffer, entry.getValue());
93+
}
94+
}
95+
96+
@Override
97+
public void read(PacketBuffer buffer) throws IOException {
98+
this.cache.clear();
99+
for (int i = 0; i < buffer.readVarInt(); i++) {
100+
this.cache.put(this.keyDeserializer.deserialize(buffer), this.valueDeserializer.deserialize(buffer));
101+
}
102+
this.setter.accept(getValue());
103+
}
104+
105+
@Override
106+
public Map<K, V> getValue() {
107+
return Collections.unmodifiableMap(this.cache);
108+
}
109+
110+
public static class Builder<K, V> {
111+
private Supplier<Map<K, V>> getter;
112+
private Consumer<Map<K, V>> setter;
113+
private IByteBufDeserializer<K> keyDeserializer;
114+
private IByteBufDeserializer<V> valueDeserializer;
115+
private IByteBufSerializer<K> keySerializer;
116+
private IByteBufSerializer<V> valueSerializer;
117+
private IEquals<V> equals;
118+
private ICopy<K> keyCopy;
119+
private ICopy<V> valueCopy;
120+
121+
public Builder<K, V> getter(Supplier<Map<K, V>> getter) {
122+
this.getter = getter;
123+
return this;
124+
}
125+
126+
public Builder<K, V> setter(Consumer<Map<K, V>> setter) {
127+
this.setter = setter;
128+
return this;
129+
}
130+
131+
public Builder<K, V> keyDeserializer(IByteBufDeserializer<K> keyDeserializer) {
132+
this.keyDeserializer = keyDeserializer;
133+
return this;
134+
}
135+
136+
public Builder<K, V> valueDeserializer(IByteBufDeserializer<V> valueDeserializer) {
137+
this.valueDeserializer = valueDeserializer;
138+
return this;
139+
}
140+
141+
public Builder<K, V> keySerializer(IByteBufSerializer<K> keySerializer) {
142+
this.keySerializer = keySerializer;
143+
return this;
144+
}
145+
146+
public Builder<K, V> valueSerializer(IByteBufSerializer<V> valueSerializer) {
147+
this.valueSerializer = valueSerializer;
148+
return this;
149+
}
150+
151+
public Builder<K, V> keyAdapter(IByteBufAdapter<K> adapter) {
152+
return keyDeserializer(adapter).keySerializer(adapter);
153+
}
154+
155+
public Builder<K, V> valueAdapter(IByteBufAdapter<V> adapter) {
156+
return valueDeserializer(adapter).valueSerializer(adapter).equals(adapter);
157+
}
158+
159+
public Builder<K, V> equals(IEquals<V> equals) {
160+
this.equals = equals;
161+
return this;
162+
}
163+
164+
public Builder<K, V> keyCopy(ICopy<K> keyCopy) {
165+
this.keyCopy = keyCopy;
166+
return this;
167+
}
168+
169+
public Builder<K, V> immutableKey() {
170+
return keyCopy(ICopy.immutable());
171+
}
172+
173+
public Builder<K, V> valueCopy(ICopy<V> valueCopy) {
174+
this.valueCopy = valueCopy;
175+
return this;
176+
}
177+
178+
public Builder<K, V> immutableValue() {
179+
return valueCopy(ICopy.immutable());
180+
}
181+
182+
public GenericMapSyncHandler<K, V> build() {
183+
if (this.getter == null) throw new NullPointerException("Getter in GenericMapSyncHandler must not be null");
184+
if (this.keyDeserializer == null) throw new NullPointerException("Key deserializer in GenericMapSyncHandler must not be null");
185+
if (this.valueDeserializer == null) throw new NullPointerException("Value deserializer in GenericMapSyncHandler must not be null");
186+
if (this.keySerializer == null) throw new NullPointerException("Key serializer in GenericMapSyncHandler must not be null");
187+
if (this.valueSerializer == null) throw new NullPointerException("Value serializer in GenericMapSyncHandler must not be null");
188+
return new GenericMapSyncHandler<>(this.getter, this.setter, this.keyDeserializer, this.valueDeserializer, this.keySerializer,
189+
this.valueSerializer, this.equals, this.keyCopy, this.valueCopy);
190+
}
191+
}
192+
}

src/main/java/com/cleanroommc/modularui/value/sync/GenericSetSyncHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ public static <T> Builder<T> builder() {
6464
public static class Builder<T> extends GenericCollectionSyncHandler.Builder<T, Set<T>, Builder<T>> {
6565

6666
public GenericSetSyncHandler<T> build() {
67-
if (this.getter == null) throw new NullPointerException("Getter in GenericListSyncHandler must not be null");
68-
if (this.deserializer == null) throw new NullPointerException("Deserializer in GenericListSyncHandler must not be null");
69-
if (this.serializer == null) throw new NullPointerException("Serializer in GenericListSyncHandler must not be null");
67+
if (this.getter == null) throw new NullPointerException("Getter in GenericSetSyncHandler must not be null");
68+
if (this.deserializer == null) throw new NullPointerException("Deserializer in GenericSetSyncHandler must not be null");
69+
if (this.serializer == null) throw new NullPointerException("Serializer in GenericSetSyncHandler must not be null");
7070
return new GenericSetSyncHandler<>(this.getter, this.setter, this.deserializer, this.serializer, this.copy);
7171
}
7272
}

0 commit comments

Comments
 (0)