This repository has been archived by the owner on Jul 8, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
注解载入器 Annotation Loader
Mouse edited this page Jul 13, 2017
·
2 revisions
在开发中,我们需要不断提高开发者的效率,以使开发进度加快。为此,我们在ChinaCraft2中实现了一个注解载入器。
为什么使用注解呢?俗话说得好:“反射,反射,程序员的欢乐。”使用注解确实便于阅读和修改,下面来看ChinaCraft2中的注册例子。
@RegBlock(value = {"copper", "ore"}, oreDict = {"oreCopper"})
Block COPPER_ORE = new BlockCCOre().setHarvestLevelReturnBlock("pickaxe", 1);
该代码是cn.mccraft.chinacraft.init
的CCBlocks
类中的代码,可以看到在COPPER_ORE
字段上我们使用了RegBlock
注解,该注解表示COPPER_ORE
是一个需要注册的方块,确实是十分方便阅读和修改。下面我们来看一看RegBlock
的实现。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface RegBlock {
/**
* 该参数将自动设置方块的registryName和unlocalizedName
* The params to build registryName and unlocalizedName.
* @see cn.mccraft.chinacraft.util.NameBuilder
*/
String[] value();
/**
* 添加矿物词典
* All {@link net.minecraftforge.oredict.OreDictionary} values to be registered.
*/
String[] oreDict() default {};
/**
* 设置方块的ItemBlock类
*/
Class<? extends Item> itemClass() default ItemBlock.class;
/**
* 是否自动注册ItemBlock
*/
boolean isRegisterItemBlock() default true;
/**
* 是否自动注册渲染器
*/
boolean isRegisterRender() default true;
而如何自动注册这些方块呢?我们在cn.mccraft.chinacraft.block.BlockLoader
中实现了自动注册的方法,代码如下:
/**
* Auto loader of all blocks annotated with {@link RegBlock} in {@link CCBlocks}.
* 自动加载{@link CCBlocks}中被{@link RegBlock}注释的方块。
*/
@SuppressWarnings("unused")
public class BlockLoader implements ILoader { //ILoader接口是我们自己实现的加载器接口,与方块注册无关系
@Load //该注解是我们自己实现的加载器注解,与方块注册无关系
public void registerBlocks() { //注册CCBlocks中的所有方块
for (Field field : CCBlocks.class.getFields()) {
field.setAccessible(true);
RegBlock anno = field.getAnnotation(RegBlock.class);
if (anno==null) continue;
try {
Block block = (Block) field.get(null);
GameRegistry.register(block.setRegistryName(NameBuilder.buildRegistryName(anno.value())).setUnlocalizedName(NameBuilder.buildUnlocalizedName(anno.value()))); //设置方块注册名和未本地化名并注册
//Register item block.
//注册方块物品
if(anno.isRegisterItemBlock()) {
Class<? extends Item> itemClass = anno.itemClass();
Constructor<? extends Item> con = itemClass.getConstructor(Block.class);
con.setAccessible(true);
GameRegistry.register(con.newInstance(block).setRegistryName(block.getRegistryName()).setUnlocalizedName(block.getUnlocalizedName()));
}
Arrays.asList(anno.oreDict()).forEach(s -> OreDictionary.registerOre(s, block)); //添加矿物词典
} catch (Exception e) {
ChinaCraft.getLogger().warn("Un-able to register block " + field.toGenericString(), e);
}
}
}
@Load(side = Side.CLIENT)
@SideOnly(Side.CLIENT)
public void registerRenders() { //渲染器和方块注册要分开,因为服务端并不需要注册渲染器
for (Field field : CCBlocks.class.getFields()) {
field.setAccessible(true);
RegBlock anno = field.getAnnotation(RegBlock.class);
if (anno==null) continue;
if(!anno.isRegisterRender()||!anno.isRegisterItemBlock()) continue;
try {
Block block = (Block) field.get(null);
registerRender(block,0);
} catch (Exception e) {
ChinaCraft.getLogger().warn("Un-able to register block " + field.toGenericString(), e);
}
}
}
@SideOnly(Side.CLIENT)
private void registerRender(Block block, int meta)
{
Item item = Item.getItemFromBlock(block);
ModelLoader.setCustomModelResourceLocation(item, meta, new ModelResourceLocation(block.getRegistryName(), "inventory"));
}
}
以上就是ChinaCraft2中方块的注解载入器的内容。同样的,我们也实现了物品载入器,有兴趣的读者可以阅读cn.mccraft.chinacraft.item.ItemLoader
和cn.mccraft.chinacraft.util.loader.annotation.RegItem
的源码。