Skip to content

Commit

Permalink
Remove FabricClientTestHelper moving most of it into the context. Add…
Browse files Browse the repository at this point in the history
… the ability to simulate key and mouse inputs
  • Loading branch information
Earthcomputer committed Dec 11, 2024
1 parent 8607772 commit 7140a4f
Show file tree
Hide file tree
Showing 20 changed files with 1,034 additions and 305 deletions.
4 changes: 4 additions & 0 deletions fabric-client-gametest-api-v1/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
version = getSubprojectVersion(project)

loom {
accessWidenerPath = file('src/client/resources/fabric-client-gametest-api-v1.accesswidener')
}

moduleDependencies(project, [
'fabric-api-base',
'fabric-resource-loader-v0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,140 @@

package net.fabricmc.fabric.api.client.gametest.v1;

import java.util.function.Predicate;

import org.apache.commons.lang3.function.FailableConsumer;
import org.apache.commons.lang3.function.FailableFunction;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import net.minecraft.SharedConstants;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;

/**
* Context for a client gametest containing various helpful functions and functions to access the game.
* Context for a client gametest containing various helpful functions and functions to access the game. Functions in
* this class can only be called on the client gametest thread.
*/
@ApiStatus.NonExtendable
public interface ClientGameTestContext {
/**
* Used to specify that a wait task should have no timeout.
*/
int NO_TIMEOUT = -1;

/**
* The default timeout for wait tasks.
*/
int DEFAULT_TIMEOUT = 10 * SharedConstants.TICKS_PER_SECOND;

/**
* Runs a single tick and waits for it to complete.
*/
void waitTick();

/**
* Runs {@code ticks} ticks and waits for them to complete.
*
* @param ticks The amount of ticks to run
*/
void waitTicks(int ticks);

/**
* Waits for a predicate to be true. Fails if the predicate is not satisfied after {@link #DEFAULT_TIMEOUT} ticks.
*
* @param predicate The predicate to check
*/
void waitFor(Predicate<MinecraftClient> predicate);

/**
* Waits for a predicate to be true. Fails if the predicate is not satisfied after {@code timeout} ticks. If
* {@code timeout} is {@link #NO_TIMEOUT}, there is no timeout.
*
* @param predicate The predicate to check
* @param timeout The number of ticks before timing out
*/
void waitFor(Predicate<MinecraftClient> predicate, int timeout);

/**
* Waits for the given screen class to be shown. If {@code screenClass} is {@code null}, waits for the current
* screen to be {@code null}. Fails if the screen does not open after {@link #DEFAULT_TIMEOUT} ticks.
*
* @param screenClass The screen class to wait to open
*/
void waitForScreen(@Nullable Class<? extends Screen> screenClass);

/**
* Opens a {@link Screen} on the client.
*
* @param screen The screen to open
* @see MinecraftClient#setScreen(Screen)
*/
void setScreen(@Nullable Screen screen);

/**
* Presses the button in the current screen whose label is the given translation key. Fails if the button couldn't
* be found.
*
* @param translationKey The translation key of the label of the button to press
*/
void clickScreenButton(String translationKey);

/**
* Presses the button in the current screen whose label is the given translation key, if the button exists. Returns
* whether the button was found.
*
* @param translationKey The translation key of the label of the button to press
* @return Whether the button was found
*/
boolean tryClickScreenButton(String translationKey);

/**
* Takes a screenshot after waiting 1 tick (for a frame to render) and saves it in the screenshots directory.
*
* @param name The name of the screenshot
*/
void takeScreenshot(String name);

/**
* Takes a screnshot after waiting {@code delay} ticks and saves it in the screenshots directory.
*
* @param name The name of the screenshot
* @param delay The delay in ticks before taking the screenshot
*/
void takeScreenshot(String name, int delay);

/**
* Gets the input handler used to simulate inputs to the client.
*
* @return The client gametest input handler
*/
ClientGameTestInput getInput();

/**
* Restores all game options in {@link MinecraftClient#options} to their default values for client gametests. This
* is called automatically before each gametest is run, so you only need to call this explicitly if you want to do
* it in the middle of the test.
*/
void restoreDefaultGameOptions();

/**
* Runs the given action on the render thread (client thread), and waits for it to complete.
*
* @param action The action to run on the render thread
* @param <E> The type of checked exception that the action throws
* @throws E When the action throws an exception
*/
<E extends Throwable> void runOnClient(FailableConsumer<MinecraftClient, E> action) throws E;

/**
* Runs the given function on the render thread (client thread), and returns the result.
*
* @param function The function to run on the render thread
* @return The result of the function
* @param <T> The type of the value to return
* @param <E> The type of the checked exception that the function throws
* @throws E When the function throws an exception
*/
<T, E extends Throwable> T computeOnClient(FailableFunction<MinecraftClient, T, E> function) throws E;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 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.gametest.v1;

import java.util.function.Function;

import net.minecraft.client.option.GameOptions;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.util.InputUtil;

/**
* The client gametest input handler used to simulate inputs to the client.
*/
public interface ClientGameTestInput {
// TODO: document all these methods
void pressKey(KeyBinding keyBinding);

void pressKey(Function<GameOptions, KeyBinding> keyBindingGetter);

void pressKey(InputUtil.Key key);

void pressKey(int keyCode);

void pressMouse(int button);

void pressControl();

void pressShift();

void pressAlt();

void releaseKey(KeyBinding keyBinding);

void releaseKey(Function<GameOptions, KeyBinding> keyBindingGetter);

void releaseKey(InputUtil.Key key);

void releaseKey(int keyCode);

void releaseMouse(int button);

void releaseControl();

void releaseShift();

void releaseAlt();

void pressReleaseKey(KeyBinding keyBinding);

void pressReleaseKey(Function<GameOptions, KeyBinding> keyBindingGetter);

void pressReleaseKey(InputUtil.Key key);

void pressReleaseKey(int keyCode);

void pressReleaseMouse(int button);

void holdKey(KeyBinding keyBinding, int ticks);

void holdKey(Function<GameOptions, KeyBinding> keyBindingGetter, int ticks);

void holdKey(InputUtil.Key key, int ticks);

void holdKey(int keyCode, int ticks);

void holdMouse(int button, int ticks);

void typeChar(int codePoint);

void typeChars(String chars);

void scroll(double amount);

void scroll(double xAmount, double yAmount);

void setCursorPos(double x, double y);

void moveCursor(double deltaX, double deltaY);
}
Loading

0 comments on commit 7140a4f

Please sign in to comment.