Skip to content

Commit

Permalink
Added item model generation
Browse files Browse the repository at this point in the history
  • Loading branch information
Pabilo8 committed Aug 13, 2023
1 parent e971904 commit 987c47d
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 21 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package pl.pabilo8.modworks.annotations.item;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used to annotate an enum with item
* @author Pabilo8
* @since 11.08.2023
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.TYPE})
public @interface GeneratedItemModels
{
/**
* @return item name
*/
String itemName();

/**
* @return item texture path
*/
String texturePath() default "";

/**
* @return base model type of all entries
*/
ItemModelType type() default ItemModelType.ITEM_SIMPLE;

/**
* @return whether models should only be generated by entries annotated with {@link GeneratedSubItemModel}
*/
boolean onlyInAnnotated() default false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package pl.pabilo8.modworks.annotations.item;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Used to annotate an enum with item
* @author Pabilo8
* @since 11.08.2023
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.FIELD})
public @interface GeneratedSubItemModel
{
String customTexturePath() default "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package pl.pabilo8.modworks.annotations.item;

/**
* @author Pabilo8
* @since 12.08.2023
*/
public enum ItemModelType
{
//For simple, batched items like crafting materials
ITEM_SIMPLE("item/generated"),
//For tool item models, like hammers, wrenches, pickaxes
ITEM_SIMPLE_TOOL("item/handheld"),
//For empty item models that will have contents generated dynamically
ITEM_SIMPLE_AUTOREPLACED("item/generated");

private final String parentModel;

ItemModelType(String parentModel)
{
this.parentModel = parentModel;
}

public String getParentModel()
{
return parentModel;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package pl.pabilo8.modworks.processors;

import com.google.auto.service.AutoService;
import com.google.gson.stream.JsonWriter;
import pl.pabilo8.modworks.annotations.item.GeneratedItemModels;
import pl.pabilo8.modworks.annotations.item.GeneratedSubItemModel;
import pl.pabilo8.modworks.annotations.item.ItemModelType;
import pl.pabilo8.modworks.utils.GeneralUtils;

import javax.annotation.processing.Processor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic.Kind;
import java.io.IOException;
import java.util.List;
import java.util.Set;

@SupportedAnnotationTypes({
"pl.pabilo8.modworks.annotations.item.GeneratedItemModels",
"pl.pabilo8.modworks.annotations.item.GeneratedSubItemModel"
})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor.class)
public class ItemModelProcessor extends AbstractModProcessor
{
@Override
protected boolean doProcessing(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
{
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(GeneratedItemModels.class);
for(Element element : elements)
{
GeneratedItemModels itemModel = element.getAnnotation(GeneratedItemModels.class);
List<Element> enumValues = GeneralUtils.getEnumValues(element);

//Model properties
String fileName = itemModel.itemName();
String texturePath = itemModel.texturePath().isEmpty()?fileName: itemModel.itemName();

if(!enumValues.isEmpty()) //is an enum with multiple models
for(Element value : enumValues)
{
GeneratedSubItemModel subModel = value.getAnnotation(GeneratedSubItemModel.class);
if(itemModel.onlyInAnnotated()&&subModel==null)
continue;

String subName = fileName+"/"+GeneralUtils.simpleNameOf(value);
String subTexture = subName;

if(subModel!=null&&!subModel.customTexturePath().isEmpty())
subTexture = subModel.customTexturePath();

tryWriteModel(subName, subTexture, itemModel.type());

}
else //is a class with a single model
tryWriteModel(fileName, texturePath, itemModel.type());
}


return !elements.isEmpty();
}

void tryWriteModel(String modelName, String texturePath, ItemModelType type)
{
try(JsonWriter writer = GeneralUtils.writeJSON(processingEnv, String.format("%s/assets/%s/models/item/%s.json", DIR_RESOURCES, MODID, modelName)))
{
writer.beginObject();
writer.name("parent").value(type.getParentModel());

//Add textures
writer.name("textures").beginObject();
switch(type)
{
case ITEM_SIMPLE:
case ITEM_SIMPLE_TOOL:
writer.name("layer0").value(String.format("%s:items/%s", MODID, texturePath));
break;
case ITEM_SIMPLE_AUTOREPLACED:
break;
}
writer.endObject();

writer.endObject();
} catch(IOException e)
{
processingEnv.getMessager().printMessage(Kind.NOTE,
"Could not build a sound file for, "+modelName);
processingEnv.getMessager().printMessage(Kind.NOTE, e.getLocalizedMessage());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
})
@SupportedSourceVersion(SourceVersion.RELEASE_8)
@AutoService(Processor.class)
//TODO: 13.08.2023 rewrite with json
public class SoundProcessor extends AbstractModProcessor
{
@Override
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/pl/pabilo8/modworks/utils/GeneralUtils.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package pl.pabilo8.modworks.utils;

import com.google.common.base.Functions;
import com.google.gson.stream.JsonWriter;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import javax.tools.StandardLocation;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Pabilo8
Expand Down Expand Up @@ -37,4 +43,16 @@ public static JsonWriter writeJSON(ProcessingEnvironment env, String path) throw
writer.setIndent("\t");
return writer;
}

public static List<Element> getEnumValues(Element elementEnum)
{
return elementEnum.getEnclosedElements().stream()
.filter(element -> element.getKind().equals(ElementKind.ENUM_CONSTANT))
.collect(Collectors.toList());
}

public static String simpleNameOf(Element element)
{
return element.getSimpleName().toString().toLowerCase();
}
}
42 changes: 42 additions & 0 deletions src/test/java/ItemModelProcessorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import com.google.testing.compile.JavaFileObjects;
import org.junit.jupiter.api.Test;
import pl.pabilo8.modworks.processors.ItemModelProcessor;

import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;

import java.nio.charset.StandardCharsets;

import static com.google.common.truth.Truth.assertAbout;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

/**
* @author Pabilo8
* @since 01.08.2023
*/
class ItemModelProcessorTest
{
public static final JavaFileObject SOURCE = JavaFileObjects.forResource("test/ItemTestDevice.java");
public static final JavaFileObject MCMOD = JavaFileObjects.forResource("jsons/mcmod.info");

@Test
void doProcessing()
{
final CharSequence[] text = new CharSequence[1];
assertDoesNotThrow(() -> text[0] = MCMOD.getCharContent(true));

assertAbout(javaSource())
.that(SOURCE)
.withCompilerOptions("-Amodworks.modid=testmod")
.withCompilerOptions("-Amodworks.mcmod=true")
.processedWith(new ItemModelProcessor())
.compilesWithoutError()
.and()
.generatesFileNamed(StandardLocation.SOURCE_OUTPUT, "resources/assets/testmod/models/item/test_device", "test1.json")
.and()
.generatesFileNamed(StandardLocation.SOURCE_OUTPUT, "resources/assets/testmod/models/item/test_device", "test2.json")
.and()
.generatesFileNamed(StandardLocation.SOURCE_OUTPUT, "resources/assets/testmod/models/item/test_device", "test3.json");
}
}
15 changes: 4 additions & 11 deletions src/test/java/McModInfoProcessorTest.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
import com.google.common.collect.ImmutableList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.testing.compile.*;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.CompilationSubject;
import com.google.testing.compile.JavaFileObjects;
import org.junit.After;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pl.pabilo8.modworks.processors.MCModInfoProcessor;

import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;

import java.io.IOException;
import java.lang.Compiler;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.google.common.truth.Truth.assertAbout;
import static com.google.common.truth.Truth.assertThat;
import static com.google.testing.compile.Compiler.javac;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;

/**
Expand Down Expand Up @@ -95,6 +88,6 @@ private String strip(String text)
{
return Arrays.stream(text.split("\n"))
.map(String::trim).collect(Collectors.joining())
.replaceAll(" ","");
.replaceAll(" ", "");
}
}
24 changes: 24 additions & 0 deletions src/test/resources/test/ItemTestDevice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package test;

import pl.pabilo8.modworks.annotations.item.GeneratedItemModels;
import pl.pabilo8.modworks.annotations.item.GeneratedSubItemModel;
import pl.pabilo8.modworks.annotations.item.ItemModelType;
import pl.pabilo8.modworks.annotations.sound.ModSound;
import pl.pabilo8.modworks.annotations.MCModInfo;

/**
* @author Pabilo8
* @since 01.08.2023
*/
public class ItemTestDevice
{

@GeneratedItemModels(itemName = "test_device")
public enum Devices
{
TEST1,
@GeneratedSubItemModel(customTexturePath = "nucleardevice")
TEST2,
TEST3;
}
}

0 comments on commit 987c47d

Please sign in to comment.