Add primitive registry for ItemColorMappers (#11)

* An initial implementation for colour mapper registries

There's elements I'm still not entirely happy here, but it appears to
work as expected.

* Add a test mod for colour mappers

* Fix license violations

* Rename everything to correspond with future names

* Woops
This commit is contained in:
SquidDev 2018-12-15 14:28:49 +00:00 committed by Shadowfacts
parent 9171236581
commit 12b3189f7d
7 changed files with 287 additions and 1 deletions

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.render;
import net.fabricmc.fabric.impl.client.render.ColorProviderRegistryImpl;
import net.minecraft.block.Block;
import net.minecraft.client.render.block.BlockColorMapper;
import net.minecraft.client.render.item.ItemColorMapper;
import net.minecraft.item.ItemContainer;
public interface ColorProviderRegistry<T, Provider> {
ColorProviderRegistry<ItemContainer, ItemColorMapper> ITEM = ColorProviderRegistryImpl.ITEM;
ColorProviderRegistry<Block, BlockColorMapper> BLOCK = ColorProviderRegistryImpl.BLOCK;
/**
* Register a color provider for one or more objects
*
* @param provider The color provider to register.
* @param objects The objects which should be colored using this provider.
*/
void register(Provider provider, T... objects);
/**
* Get a color provider for the given object.
*
* Please note that the underlying registry may not be fully populated or stable until the game has started,
* as other mods may overwrite the registry.
*
* @param object The object to acquire the provide for.
* @return The registered mapper for this provider, or {@code null} if none is registered or available.
*/
Provider get(T object);
}

View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.client.render;
import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;
import net.minecraft.block.Block;
import net.minecraft.client.render.block.BlockColorMap;
import net.minecraft.client.render.block.BlockColorMapper;
import net.minecraft.client.render.item.ItemColorMap;
import net.minecraft.client.render.item.ItemColorMapper;
import net.minecraft.item.ItemContainer;
import java.util.IdentityHashMap;
import java.util.Map;
public abstract class ColorProviderRegistryImpl<T, Provider, Underlying> implements ColorProviderRegistry<T, Provider> {
public static final ColorProviderRegistryImpl<Block, BlockColorMapper, BlockColorMap> BLOCK = new ColorProviderRegistryImpl<Block, BlockColorMapper, BlockColorMap>() {
@Override
void registerUnderlying(BlockColorMap map, BlockColorMapper mapper, Block block) {
map.register(mapper, block);
}
};
public static final ColorProviderRegistryImpl<ItemContainer, ItemColorMapper, ItemColorMap> ITEM = new ColorProviderRegistryImpl<ItemContainer, ItemColorMapper, ItemColorMap>() {
@Override
void registerUnderlying(ItemColorMap map, ItemColorMapper mapper, ItemContainer block) {
map.method_1708(mapper, block);
}
};
private Underlying colorMap;
private Map<T, Provider> tempMappers = new IdentityHashMap<>();
abstract void registerUnderlying(Underlying colorMap, Provider provider, T objects);
public void initialize(Underlying colorMap) {
if (this.colorMap != null) {
if (this.colorMap != colorMap) throw new IllegalStateException("Cannot set colorMap twice");
return;
}
this.colorMap = colorMap;
for (Map.Entry<T, Provider> mappers : tempMappers.entrySet()) {
registerUnderlying(colorMap, mappers.getValue(), mappers.getKey());
}
tempMappers = null;
}
@Override
@SafeVarargs
public final void register(Provider provider, T... objects) {
if (colorMap != null) {
for (T object : objects) registerUnderlying(colorMap, provider, object);
} else {
for (T object : objects) tempMappers.put(object, provider);
}
}
@Override
@SuppressWarnings("unchecked")
public Provider get(T object) {
return colorMap == null ? null : ((ColorMapperHolder<T, Provider>) colorMap).get(object);
}
public interface ColorMapperHolder<T, Provider> {
Provider get(T item);
}
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.render;
import net.fabricmc.fabric.impl.client.render.ColorProviderRegistryImpl;
import net.minecraft.block.Block;
import net.minecraft.client.render.block.BlockColorMap;
import net.minecraft.client.render.block.BlockColorMapper;
import net.minecraft.util.IdList;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockColorMap.class)
public class MixinBlockColorMap implements ColorProviderRegistryImpl.ColorMapperHolder<Block, BlockColorMapper> {
@Shadow
@Final
private IdList<BlockColorMapper> mappers;
@Inject(method = "create", at = @At("RETURN"))
private static void create(CallbackInfoReturnable<BlockColorMap> info) {
ColorProviderRegistryImpl.BLOCK.initialize(info.getReturnValue());
}
@Override
public BlockColorMapper get(Block block) {
return mappers.getInt(Registry.BLOCK.getRawId(block));
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.client.render;
import net.fabricmc.fabric.impl.client.render.ColorProviderRegistryImpl;
import net.minecraft.client.render.block.BlockColorMap;
import net.minecraft.client.render.item.ItemColorMap;
import net.minecraft.client.render.item.ItemColorMapper;
import net.minecraft.item.ItemContainer;
import net.minecraft.util.IdList;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ItemColorMap.class)
public class MixinItemColorMap implements ColorProviderRegistryImpl.ColorMapperHolder<ItemContainer, ItemColorMapper> {
@Shadow
@Final
private IdList<ItemColorMapper> field_1996;
@Inject(method = "method_1706", at = @At("RETURN"))
private static void method_1706(BlockColorMap blockMap, CallbackInfoReturnable<ItemColorMap> info) {
ColorProviderRegistryImpl.ITEM.initialize(info.getReturnValue());
}
@Override
public ItemColorMapper get(ItemContainer item) {
return field_1996.getInt(Registry.ITEM.getRawId(item.getItem()));
}
}

View file

@ -5,8 +5,10 @@
"mixins": [
"block.entity.MixinClientPlayNetworkHandler",
"bugfix.MixinBiomeColors",
"client.render.MixinBlockColorMap",
"client.render.MixinBlockEntityRenderManager",
"client.render.MixinEntityRenderManager",
"client.render.MixinItemColorMap",
"client.texture.MixinSpriteAtlasTexture",
"events.playerinteraction.MixinClientPlayerInteractionManager",
"events.tick.MixinMinecraftClient",
@ -19,4 +21,4 @@
"injectors": {
"defaultRequire": 1
}
}
}

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.colormapper;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.render.ColorProviderRegistry;
import net.minecraft.block.Blocks;
import net.minecraft.client.render.block.BlockColorMapper;
import net.minecraft.item.Items;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ColorProviderMod implements ClientModInitializer {
private static final boolean ENABLED = true;
private static final Logger LOGGER = LogManager.getLogger();
@Override
public void onInitializeClient() {
if (!ENABLED) return;
LOGGER.info("Initialising ColorProviderMod");
// Redstone is now the same color as grass
ColorProviderRegistry.BLOCK.register((block, pos, world, layer) -> {
BlockColorMapper provider = ColorProviderRegistry.BLOCK.get(Blocks.GRASS);
return provider == null ? -1 : provider.getColor(block, pos, world, layer);
}, Blocks.REDSTONE_WIRE);
// Make white dye glow red.
ColorProviderRegistry.ITEM.register((item, layer) ->
(int) (64 * (Math.sin(System.currentTimeMillis() / 5e2) + 3)) << 16,
Items.WHITE_DYE);
}
}

View file

@ -0,0 +1,11 @@
{
"id": "fabric_test",
"name": "Fabric API Tests",
"version": "0.1.1",
"side": "universal",
"description": "A series of test mods to check Fabric works.",
"license": "Apache-2.0",
"initializers": [
"net.fabricmc.fabric.colormapper.ColorProviderMod"
]
}