Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package fermiummixins.mixin.vanilla;

import fermiummixins.wrapper.IBlockStateIdentity;
import fermiummixins.wrapper.BlockStateIdentityPatchWrapper;
import net.minecraft.block.state.BlockStateBase;
import net.minecraft.block.state.IBlockState;
import org.spongepowered.asm.mixin.Mixin;
Expand All @@ -10,9 +9,14 @@
@Mixin(BlockStateBase.class)
public abstract class BlockStateBase_IdentityMixin implements IBlockState, IBlockStateIdentity {

//Registry is reference based, so each init is a new id
//ID for unknown state is -1
@Unique
private int fermiummixins$blockStateID = BlockStateIdentityPatchWrapper.getNewID();
private int fermiummixins$blockStateID = -1;

@Override
public void fermiummixins$setIdentityKey(int id) {
this.fermiummixins$blockStateID = id;
}

@Override
public int fermiummixins$getIdentityKey() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,39 @@
package fermiummixins.wrapper;

import com.google.common.collect.Lists;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.ObjectIntIdentityMap;

import javax.annotation.Nullable;
import java.util.ArrayList;

public abstract class BlockStateIdentityPatchWrapper {

//https://en.wikipedia.org/wiki/Jesus_nut
private static int currentID = 0;

public static int getNewID() {
return currentID++;
}

public static class ClearableObjectIntIdentityMapPatched extends ObjectIntIdentityMap<IBlockState> {

private final ArrayList<Integer> identityArray;
private int size = 0;

public ClearableObjectIntIdentityMapPatched() {
//TODO May be worth it to set expected size through config based on post-load totals?
//Default vanilla size is 512 but RLCraft test was ~40k-50k
//TODO test how expected size practically affects performance/alloc, just guessed for now
this(65536);
this(512);
}

public ClearableObjectIntIdentityMapPatched(int expectedSize) {
super(expectedSize);
this.identityArray = Lists.newArrayListWithExpectedSize(expectedSize);
}

@Override
public void put(IBlockState key, int value) {
if(key == null) return;
int fixKey = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey();
while(this.identityArray.size() <= fixKey) {
this.identityArray.add(null);
}
if(this.identityArray.set(fixKey, value) == null) this.size++;
((IBlockStateIdentity) key).fermiummixins$setIdentityKey(value);
//objectList can have multiple values return the same state ref but total size is based on total state refs
while(this.objectList.size() <= value) {
this.objectList.add(null);
}
this.objectList.set(value, key);
if(this.objectList.set(value, key) == null) this.size++;
}

@Override
public int get(@Nullable IBlockState key) {
if(key == null) return -1;
Integer integer = this.get(((IBlockStateIdentity)key).fermiummixins$getIdentityKey());
if(integer == null) {
integer = this.get(key.getBlock().getStateFromMeta(key.getBlock().getMetaFromState(key)));
}
return integer;
}

private Integer get(int key) {
if(key >= this.identityArray.size()) return null;
return this.identityArray.get(key);
return ((IBlockStateIdentity) key).fermiummixins$getIdentityKey();
}

@Override
Expand All @@ -70,19 +43,15 @@ public int size() {

public void clear() {
this.objectList.clear();
this.identityArray.clear();
this.size = 0;
}

public void remove(IBlockState key) {
if(key == null) return;
int fixKey = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey();
int value = ((IBlockStateIdentity)key).fermiummixins$getIdentityKey();
//Do not use remove, will shift array
Integer prev = this.get(fixKey);
if(prev != null) {
this.identityArray.set(fixKey, null);
this.objectList.set(prev, null);
this.size--;
if(value >= 0 && value < this.objectList.size()) {
if(this.objectList.set(value, null) != null) this.size--;
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/fermiummixins/wrapper/IBlockStateIdentity.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

public interface IBlockStateIdentity {

void fermiummixins$setIdentityKey(int id);

default int fermiummixins$getIdentityKey() {
FermiumMixins.LOGGER.log(Level.ERROR, "FermiumMixins BlockState Identity Registry Patch has encountered unexpected behavior, disable this patch.");
return 0;
Expand Down