Optimize BlockStateWrapper getter
This commit is contained in:
+38
-11
@@ -167,20 +167,46 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
return AIR;
|
return AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a wrapper specifically for the API event to use
|
// pooling wrappers significantly improves chunk->LOD processing speed
|
||||||
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
|
// and also reduces GC pressure
|
||||||
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
|
BlockStateWrapper existingWrapper = WRAPPER_BY_BLOCK_STATE.get(blockState);
|
||||||
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockStateWrapperCreatedEvent.class, eventParam);
|
if (existingWrapper != null)
|
||||||
|
|
||||||
if (!eventParam.getOverridesSet())
|
|
||||||
{
|
{
|
||||||
// no changes needed, use the existing object
|
return existingWrapper;
|
||||||
return apiWrapper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new wrapper using whatever overrides the API user set
|
|
||||||
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
|
|
||||||
return returnWrapper;
|
// synchronized so the API event only fires once per block
|
||||||
|
synchronized (WRAPPER_BY_BLOCK_STATE)
|
||||||
|
{
|
||||||
|
// if another thread already finished this block, use that wrapper
|
||||||
|
existingWrapper = WRAPPER_BY_BLOCK_STATE.get(blockState);
|
||||||
|
if (existingWrapper != null)
|
||||||
|
{
|
||||||
|
return existingWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// create a wrapper specifically for the API event to use
|
||||||
|
BlockStateWrapper apiWrapper = new BlockStateWrapper(blockState, levelWrapper, null);
|
||||||
|
DhApiBlockStateWrapperCreatedEvent.EventParam eventParam = new DhApiBlockStateWrapperCreatedEvent.EventParam(apiWrapper);
|
||||||
|
ApiEventInjector.INSTANCE.fireAllEvents(DhApiBlockStateWrapperCreatedEvent.class, eventParam);
|
||||||
|
|
||||||
|
if (!eventParam.getOverridesSet())
|
||||||
|
{
|
||||||
|
// no API changes needed, use the existing object
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(blockState, apiWrapper);
|
||||||
|
return apiWrapper;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create a new wrapper using whatever overrides the API user set
|
||||||
|
BlockStateWrapper returnWrapper = new BlockStateWrapper(blockState, levelWrapper, eventParam);
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(blockState, returnWrapper);
|
||||||
|
return returnWrapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private BlockStateWrapper(
|
private BlockStateWrapper(
|
||||||
@Nullable BlockState blockState, ILevelWrapper levelWrapper,
|
@Nullable BlockState blockState, ILevelWrapper levelWrapper,
|
||||||
@@ -1000,6 +1026,7 @@ public class BlockStateWrapper implements IBlockStateWrapper
|
|||||||
// put if absent in case two threads deserialize at the same time
|
// put if absent in case two threads deserialize at the same time
|
||||||
// unfortunately we can't put everything in a computeIfAbsent() since we also throw exceptions
|
// unfortunately we can't put everything in a computeIfAbsent() since we also throw exceptions
|
||||||
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
WRAPPER_BY_RESOURCE_LOCATION.putIfAbsent(finalResourceStateString, foundWrapper);
|
||||||
|
WRAPPER_BY_BLOCK_STATE.putIfAbsent(foundWrapper.blockState, foundWrapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user