Skip to content

Commit

Permalink
Detach Mui from GuiScreenWrapper (CleanroomMC#64)
Browse files Browse the repository at this point in the history
* detach GuiScreenWrapper

* fix mouse input

* slightly scuffed gui overlays

* fix text widget for unusual scales

* lots of small stuff

* setup tests & own matrix and vector impl

* dont use deprecated field

* move overlay test to own class

* test button overlapping

* allow creating custom gui wrappers from UIFactory

* helpers & javadoc for ui factories

(cherry picked from commit 47cf883)
  • Loading branch information
brachy84 authored and miozune committed Sep 6, 2024
1 parent e45d8d0 commit 3def879
Show file tree
Hide file tree
Showing 73 changed files with 3,291 additions and 672 deletions.
46 changes: 46 additions & 0 deletions addon.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
test {
useJUnitPlatform()
testLogging {
events "passed", "skipped", "failed"
}
}

SourceSet functionalTestSet = null

sourceSets {
functionalTestSet = create("functionalTest") {
java {
srcDir("src/functionalTest/java")
compileClasspath += sourceSets.patchedMc.output + sourceSets.main.output
}
}
}

configurations { configs ->
// Keep all dependencies from the main mod in the functional test mod
named(functionalTestSet.compileClasspathConfigurationName).configure {it.extendsFrom(named("compileClasspath").get())}
named(functionalTestSet.runtimeClasspathConfigurationName).configure {it.extendsFrom(named("runtimeClasspath").get())}
named(functionalTestSet.annotationProcessorConfigurationName).configure {it.extendsFrom(named("annotationProcessor").get())}
}

tasks.register(functionalTestSet.jarTaskName, Jar) {
from(functionalTestSet.output)
archiveClassifier.set("functionalTests")
// we don't care about the version number here, keep it stable to avoid polluting the tmp directory
archiveVersion.set("1.0")
destinationDirectory.set(new File(buildDir, "tmp"))
}
tasks.named("assemble").configure {
dependsOn(functionalTestSet.jarTaskName)
}

// Run tests in the default runServer/runClient configurations
tasks.named("runServer", JavaExec).configure {
dependsOn(functionalTestSet.jarTaskName)
classpath(configurations.named(functionalTestSet.runtimeClasspathConfigurationName), tasks.named(functionalTestSet.jarTaskName))
}

tasks.named("runClient", JavaExec).configure {
dependsOn(functionalTestSet.jarTaskName)
classpath(configurations.named(functionalTestSet.runtimeClasspathConfigurationName), tasks.named(functionalTestSet.jarTaskName))
}
10 changes: 10 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,14 @@ dependencies {
//runtimeOnlyNonPublishable("com.github.GTNewHorizons:NotEnoughItems:2.6.34-GTNH:dev")
// For Thaumcraft runtime
//runtimeOnlyNonPublishable("com.github.GTNewHorizons:Baubles:1.0.4:dev")

testImplementation(platform('org.junit:junit-bom:5.9.2'))
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation("org.mockito:mockito-core:3.+")

functionalTestImplementation(platform('org.junit:junit-bom:5.9.2'))
functionalTestImplementation('org.junit.jupiter:junit-jupiter')
functionalTestImplementation('org.junit.platform:junit-platform-engine')
functionalTestImplementation('org.junit.platform:junit-platform-launcher')
functionalTestImplementation('org.junit.platform:junit-platform-reporting')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.cleanroommc.modularui.test;

import java.io.File;
import java.io.PrintWriter;
import java.nio.file.FileSystems;
import java.nio.file.Path;

import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ChatComponentText;

import org.apache.commons.io.output.CloseShieldOutputStream;
import org.junit.platform.engine.discovery.DiscoverySelectors;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.launcher.listeners.TestExecutionSummary;
import org.junit.platform.reporting.legacy.xml.LegacyXmlReportGeneratingListener;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLServerStartedEvent;

@Mod(modid = "mui-tests", name = "MUI Dev Tests", version = "1.0", dependencies = "required-after:modularui2")
public class MUITestMod {

@Mod.EventHandler
public void onServerStarted(FMLServerStartedEvent event) {
MinecraftServer.getServer()
.addChatMessage(new ChatComponentText("Running MUI unit tests..."));
runTests();
MinecraftServer.getServer()
.addChatMessage(new ChatComponentText("Running MUI unit tests finished"));
}

private void runTests() {
// https://junit.org/junit5/docs/current/user-guide/#launcher-api
System.setProperty("junit.platform.reporting.open.xml.enabled", "false");
final Path testsXmlOutDir = FileSystems.getDefault()
.getPath("./junit-out/")
.toAbsolutePath();
final File testsXmlOutDirFile = testsXmlOutDir.toFile();
testsXmlOutDirFile.mkdirs();
{
File[] fileList = testsXmlOutDirFile.listFiles();
if (fileList != null) {
for (File child : fileList) {
if (child.isFile() && child.getName()
.endsWith(".xml")) {
child.delete();
}
}
}
}
final LauncherDiscoveryRequest discovery = LauncherDiscoveryRequestBuilder.request()
.selectors(DiscoverySelectors.selectPackage("com.cleanroommc.modularui.test"))
.build();
final SummaryGeneratingListener summaryGenerator = new SummaryGeneratingListener();
final TestExecutionSummary summary;
try (PrintWriter stderrWriter = new PrintWriter(new CloseShieldOutputStream(System.err), true)) {
final LegacyXmlReportGeneratingListener xmlGenerator = new LegacyXmlReportGeneratingListener(
testsXmlOutDir,
stderrWriter);
try (LauncherSession session = LauncherFactory.openSession()) {
final Launcher launcher = session.getLauncher();
final TestPlan plan = launcher.discover(discovery);
launcher.registerTestExecutionListeners(summaryGenerator, xmlGenerator);
launcher.execute(plan);
}
summary = summaryGenerator.getSummary();

summary.printFailuresTo(stderrWriter, 32);
summary.printTo(stderrWriter);
stderrWriter.flush();
}
// Throw an exception if running via `runServer`
if (summary.getTotalFailureCount() > 0 && FMLCommonHandler.instance()
.getSide()
.isServer()) {
throw new RuntimeException("Some of the unit tests failed to execute, check the log for details");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.cleanroommc.modularui.test;

import com.cleanroommc.modularui.overlay.ScreenWrapper;
import com.cleanroommc.modularui.screen.ModularPanel;
import com.cleanroommc.modularui.screen.ModularScreen;
import com.cleanroommc.modularui.screen.NEISettingsImpl;
import com.cleanroommc.modularui.widget.sizer.Area;
import com.cleanroommc.modularui.widgets.ButtonWidget;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class SizerTest {

static final int W = 800, H = 450;

@Test
void test() {
ModularPanel panel = panel().child(new ButtonWidget<>().center());
testPanel(panel);
assertArea(panel.getArea(), W / 2 - 176 / 2, H / 2 - 166 / 2, 176, 166);
}

ModularPanel panel(int w, int h) {
return ModularPanel.defaultPanel("main", w, h);
}

ModularPanel panel() {
return ModularPanel.defaultPanel("main");
}

void assertArea(Area area, int x, int y, int w, int h) {
Area.SHARED.set(x, y, w, h);
assertEquals(Area.SHARED, area);
}

ModularScreen testPanel(ModularPanel panel) {
ModularScreen screen = new ModularScreen(panel);
screen.getContext().setNEISettings(new NEISettingsImpl());
ScreenWrapper wrapper = new ScreenWrapper(null, screen);
screen.construct(wrapper);
screen.onResize(W, H);
return screen;
}
}
15 changes: 15 additions & 0 deletions src/functionalTest/resources/mcmod.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[
{
"modid":"MUI-tests",
"name":"MUI Dev Tests",
"description":"MUI Tests to run in the development environment",
"version":"1.0",
"mcversion":"1.7.10",
"url":"https://github.com/GTNewHorizons/ModularUI2",
"updateUrl":"",
"authorList":[],
"credits":"",
"logoFile":"",
"screenshots":[]
}
]
29 changes: 29 additions & 0 deletions src/main/java/com/cleanroommc/modularui/ClientEventHandler.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.cleanroommc.modularui;

import com.cleanroommc.modularui.api.event.KeyboardInputEvent;
import com.cleanroommc.modularui.api.event.MouseInputEvent;
import com.cleanroommc.modularui.drawable.Stencil;

import com.cleanroommc.modularui.screen.GuiContainerWrapper;

import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

import net.minecraftforge.client.event.GuiScreenEvent;

import org.lwjgl.opengl.GL11;

@SideOnly(Side.CLIENT)
Expand All @@ -32,4 +39,26 @@ public void preDraw(TickEvent.RenderTickEvent event) {
}
Stencil.reset();
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
public static void onGuiInput(MouseInputEvent.Pre event) {
if (hasDraggable(event)) {
// cancel interactions with other mods
event.gui.handleMouseInput();
event.setCanceled(true);
}
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
public static void onGuiInput(KeyboardInputEvent.Pre event) {
if (hasDraggable(event)) {
// cancel interactions with other mods
event.gui.handleKeyboardInput();
event.setCanceled(true);
}
}

private static boolean hasDraggable(GuiScreenEvent event) {
return event.gui instanceof GuiContainerWrapper screenWrapper && screenWrapper.getScreen().getContext().hasDraggable();
}
}
21 changes: 6 additions & 15 deletions src/main/java/com/cleanroommc/modularui/ClientProxy.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.cleanroommc.modularui;

import codechicken.nei.guihook.GuiContainerManager;
import com.cleanroommc.modularui.drawable.DrawableSerialization;
import com.cleanroommc.modularui.factory.GuiManager;
import com.cleanroommc.modularui.holoui.HoloScreenEntity;
import com.cleanroommc.modularui.holoui.ScreenEntityRender;
import com.cleanroommc.modularui.integration.nei.ModularUIContainerObjectHandler;
import com.cleanroommc.modularui.mixins.early.forge.ForgeHooksClientMixin;
import com.cleanroommc.modularui.overlay.OverlayManager;
import com.cleanroommc.modularui.screen.ClientScreenHandler;
import com.cleanroommc.modularui.test.EventHandler;
import com.cleanroommc.modularui.test.OverlayTest;
import com.cleanroommc.modularui.theme.ThemeManager;
import com.cleanroommc.modularui.theme.ThemeReloadCommand;
import cpw.mods.fml.client.registry.RenderingRegistry;
Expand All @@ -24,9 +24,6 @@
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.MinecraftForge;

import static com.cleanroommc.modularui.ModularUI.MODID_NEI;
import static com.cleanroommc.modularui.ModularUI.isNEILoaded;

@SideOnly(Side.CLIENT)
@SuppressWarnings("unused")
public class ClientProxy extends CommonProxy {
Expand All @@ -37,14 +34,13 @@ public class ClientProxy extends CommonProxy {
void preInit(FMLPreInitializationEvent event) {
super.preInit(event);

if (isNEILoaded) {
registerNEIHandler();
}

FMLCommonHandler.instance().bus().register(new ClientEventHandler());
MinecraftForge.EVENT_BUS.register(new ClientScreenHandler());
MinecraftForge.EVENT_BUS.register(new OverlayManager());

if (ModularUIConfig.enableTestGuis) {
MinecraftForge.EVENT_BUS.register(new EventHandler());
OverlayTest.init();
}

DrawableSerialization.init();
Expand All @@ -67,9 +63,4 @@ void postInit(FMLPostInitializationEvent event) {
public Timer getTimer60Fps() {
return this.timer60Fps;
}

@Optional.Method(modid = MODID_NEI)
private void registerNEIHandler() {
GuiContainerManager.addObjectHandler(new ModularUIContainerObjectHandler());
}
}
9 changes: 2 additions & 7 deletions src/main/java/com/cleanroommc/modularui/CommonProxy.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package com.cleanroommc.modularui;

import com.cleanroommc.modularui.factory.GuiManager;
import com.cleanroommc.modularui.factory.ItemGuiFactory;
import com.cleanroommc.modularui.factory.SidedTileEntityGuiFactory;
import com.cleanroommc.modularui.factory.TileEntityGuiFactory;
import com.cleanroommc.modularui.factory.*;
import com.cleanroommc.modularui.holoui.HoloScreenEntity;
import com.cleanroommc.modularui.network.NetworkHandler;
import com.cleanroommc.modularui.test.ItemEditorGui;
Expand Down Expand Up @@ -39,9 +36,7 @@ void preInit(FMLPreInitializationEvent event) {

NetworkHandler.init();

GuiManager.registerFactory(TileEntityGuiFactory.INSTANCE);
GuiManager.registerFactory(SidedTileEntityGuiFactory.INSTANCE);
GuiManager.registerFactory(ItemGuiFactory.INSTANCE);
GuiFactories.init();
}

void postInit(FMLPostInitializationEvent event) {
Expand Down
4 changes: 0 additions & 4 deletions src/main/java/com/cleanroommc/modularui/ModularUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ public void postInit(FMLPostInitializationEvent event) {
proxy.postInit(event);
}

@Mod.EventHandler
public void onLoadComplete(FMLLoadCompleteEvent event) {
}

@Mod.EventHandler
public void onServerLoad(FMLServerStartingEvent event) {
proxy.onServerLoad(event);
Expand Down
Loading

0 comments on commit 3def879

Please sign in to comment.