1+ package net .modificationstation .stationapi .api .registry .sync .trackers ;
2+
3+ import com .google .common .base .Joiner ;
4+ import it .unimi .dsi .fastutil .ints .Int2IntMap ;
5+ import it .unimi .dsi .fastutil .ints .Int2ObjectMap ;
6+ import it .unimi .dsi .fastutil .ints .Int2ObjectOpenHashMap ;
7+ import it .unimi .dsi .fastutil .objects .Reference2ObjectMap ;
8+ import it .unimi .dsi .fastutil .objects .Reference2ObjectOpenHashMap ;
9+ import net .mine_diver .unsafeevents .listener .EventListener ;
10+ import net .mine_diver .unsafeevents .listener .Listener ;
11+ import net .modificationstation .stationapi .api .event .registry .RegistryEntryAddedEvent ;
12+ import net .modificationstation .stationapi .api .event .registry .RegistryIdRemapEvent ;
13+ import net .modificationstation .stationapi .api .registry .ListenableRegistry ;
14+ import net .modificationstation .stationapi .api .registry .Registry ;
15+ import net .modificationstation .stationapi .api .util .Identifier ;
16+
17+ import java .util .ArrayList ;
18+ import java .util .List ;
19+
20+ import static net .modificationstation .stationapi .api .StationAPI .LOGGER ;
21+
22+ public class Int2ObjectMapTracker <V , OV > {
23+ private final String name ;
24+ private final Int2ObjectMap <OV > mappers ;
25+ private final Reference2ObjectMap <Identifier , OV > removedMapperCache = new Reference2ObjectOpenHashMap <>();
26+
27+ private Int2ObjectMapTracker (String name , Int2ObjectMap <OV > mappers ) {
28+ this .name = name ;
29+ this .mappers = mappers ;
30+ }
31+
32+ public static <V , OV , R extends Registry <V > & ListenableRegistry > void register (R registry , String name , Int2ObjectMap <OV > mappers ) {
33+ Int2ObjectMapTracker <V , OV > tracker = new Int2ObjectMapTracker <>(name , mappers );
34+ registry .getEventBus ().register (Listener .object ()
35+ .listener (tracker )
36+ .build ());
37+ }
38+
39+ @ EventListener
40+ private void onEntryAdded (RegistryEntryAddedEvent <V > event ) {
41+ if (removedMapperCache .containsKey (event .id ))
42+ mappers .put (event .rawId , removedMapperCache .get (event .id ));
43+ }
44+
45+ @ EventListener
46+ private void onRemap (RegistryIdRemapEvent <V > event ) {
47+ Int2ObjectMap <OV > oldMappers = new Int2ObjectOpenHashMap <>(mappers );
48+ Int2IntMap remapMap = event .state .getRawIdChangeMap ();
49+ List <String > errors = null ;
50+
51+ mappers .clear ();
52+
53+ for (int i : oldMappers .keySet ()) {
54+ int newI = remapMap .getOrDefault (i , Integer .MIN_VALUE );
55+
56+ if (newI >= 0 ) {
57+ if (mappers .containsKey (newI )) {
58+ if (errors == null ) errors = new ArrayList <>();
59+
60+ errors .add (" - Map contained two equal IDs " + newI + " (" + event .state .getIdFromOld (i ) + "/" + i + " -> " + event .state .getIdFromNew (newI ) + "/" + newI + ")!" );
61+ } else mappers .put (newI , oldMappers .get (i ));
62+ } else {
63+ LOGGER .warn ("Int2ObjectMap " + name + " is dropping mapping for integer ID " + i + " (" + event .state .getIdFromOld (i ) + ") - should not happen!" );
64+ removedMapperCache .put (event .state .getIdFromOld (i ), oldMappers .get (i ));
65+ }
66+ }
67+
68+ if (errors != null )
69+ throw new RuntimeException ("Errors while remapping Int2ObjectMap " + name + " found:\n " + Joiner .on ('\n' ).join (errors ));
70+ }
71+ }
0 commit comments