Skip to content

Commit

Permalink
WIP In-world displays
Browse files Browse the repository at this point in the history
  • Loading branch information
XyperCode committed Jun 4, 2024
1 parent c33dbaf commit e9b3c3d
Show file tree
Hide file tree
Showing 34 changed files with 480 additions and 124 deletions.
36 changes: 36 additions & 0 deletions common/src/main/java/dev/ultreon/devices/Display.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package dev.ultreon.devices;

import dev.ultreon.devices.api.os.OperatingSystem;
import dev.ultreon.devices.block.entity.ComputerBlockEntity;
import dev.ultreon.devices.client.DisplayGui;
import dev.ultreon.devices.mineos.apps.system.DisplayResolution;

import java.util.function.Consumer;

public interface Display {
void setResolution(DisplayResolution resolution);

boolean isPresent();

boolean isConnected();

int getScreenWidth();

int getScreenHeight();

int getMouseX();

int getMouseY();

float getPartialTicks();

int getMaxWidth();

int getMaxHeight();

void renderBezels();

ComputerBlockEntity getComputer();

OperatingSystem getOS();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import dev.ultreon.devices.api.task.TaskManager;
import dev.ultreon.devices.api.util.Vulnerability;
import dev.ultreon.devices.api.utils.OnlineRequest;
import dev.ultreon.devices.client.ClientModEvents;
import dev.ultreon.devices.mineos.apps.email.task.TaskRegisterEmailAccount;
import dev.ultreon.devices.mineos.apps.email.task.*;
import dev.ultreon.devices.mineos.apps.system.task.TaskAdd;
Expand Down
10 changes: 10 additions & 0 deletions common/src/main/java/dev/ultreon/devices/api/app/Application.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
Expand Down Expand Up @@ -272,6 +273,15 @@ public void onClose() {
currentLayout = null;
}

@Override
public CompoundTag writeState() {
CompoundTag tag = super.writeState();
tag.put("layout", currentLayout.writeState());
tag.put("defaultLayout", defaultLayout.writeState());

return tag;
}

/**
* Called when you first load up your application. Allows you to read any
* stored data you have saved. Only called if you have saved data. This
Expand Down
99 changes: 90 additions & 9 deletions common/src/main/java/dev/ultreon/devices/api/app/Component.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package dev.ultreon.devices.api.app;

import dev.ultreon.devices.UltreonDevicesMod;
import dev.ultreon.devices.mineos.client.MineOS;
import dev.ultreon.devices.mineos.apps.system.object.ColorScheme;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public abstract class Component {
/**
Expand All @@ -31,20 +39,21 @@ public abstract class Component {
*/
public int top;
/**
* Is the component enabled
* Is the component enabled?
*/
protected boolean enabled = true;
/**
* Is the component visible
* Is the component visible?
*/
protected boolean visible = true;

/**
* The default constructor for a component.
* <p>
* Laying out components is simply relative positioning. So for left (x position),
* specific how many pixels from the left of the application window you want
* it to be positioned at. The top is the same, but instead from the top (y position).
* Laying out components is simply relative positioning.
* So for "left" (x position),
* specifically how many pixels from the left of the application window you want it to be positioned at.
* The top is the same, but instead of the top (y position).
*
* @param left how many pixels from the left
* @param top how many pixels from the top
Expand All @@ -55,21 +64,80 @@ public Component(int left, int top) {
this.top = top;
}

public Component(CompoundTag tag) {
this.xPosition = tag.getInt("x");
this.yPosition = tag.getInt("y");
this.left = tag.getInt("left");
this.top = tag.getInt("top");
this.visible = tag.getBoolean("visible");
this.enabled = tag.getBoolean("enabled");
}

protected static int color(int personalColor, int systemColor) {
return personalColor >= 0 ? personalColor : systemColor;
}

protected static ListTag writeComponents(List<Component> components) {
ListTag tag = new ListTag();
for (Component component : components) {
tag.add(component.writeState());
}
return tag;
}

protected static List<Component> readComponents(ListTag components) {
List<Component> list = new java.util.ArrayList<>();
for (Tag tag : components) {
if (!(tag instanceof CompoundTag compoundTag)) continue;
Component e = Component.readState(compoundTag);
if (e == null) continue; // Failed to load
list.add(e);
}

return list;
}

private static @Nullable Component readState(CompoundTag tag) {
String className = tag.getString("type");

// Load the class in an uninitialized state
Class<?> uninitClass;
try {
uninitClass = Class.forName(className, false, MineOS.getOpened().getClass().getClassLoader());
} catch (ClassNotFoundException e) {
UltreonDevicesMod.LOGGER.warn("Failed to load component: class {} doesn't exist.", className, e);
return null;
}

// Check if the class extends Component
Class<?> superClass = uninitClass.getSuperclass();
while (superClass != null) {
if (superClass == Component.class) break;
superClass = superClass.getSuperclass();
}
if (superClass == null) {
UltreonDevicesMod.LOGGER.warn("Class security check failed: class {} does not extend Component, ignoring class.", className);
return null;
}
try {
return (Component) uninitClass.getConstructor(CompoundTag.class).newInstance(tag);
} catch (Exception e) {
UltreonDevicesMod.LOGGER.warn("Failed to load component: class {} failed to initialize.", className, e);
return null;
}
}

/**
* Called when this component is added to a Layout. You can add
* sub-components through this method. Use {@link Layout#addComponent(Component)}
* subcomponents through this method. Use {@link Layout#addComponent(Component)}
*
* @param layout the layout this component is added to
*/
protected void init(Layout layout) {
}

/**
* Called when the Layout this component is bound to is set as the current layout in an
* Called when the Layout, this component is bound to is set as the current layout in an
* application.
*/
protected void handleLoad() {
Expand Down Expand Up @@ -211,8 +279,9 @@ protected void handleMouseScroll(int mouseX, int mouseY, boolean direction) {

/**
* This method should be ignored. Used for the core.
* Will probably be removed in the future.
* It will probably be removed in the future.
*/
@ApiStatus.Internal
protected void updateComponents(int x, int y) {
this.xPosition = x + left;
this.yPosition = y + top;
Expand Down Expand Up @@ -241,7 +310,7 @@ public void setVisible(boolean visible) {
/**
* Gets the laptop's Color scheme. A simple helper method to clean up code.
*
* @return
* @return the color scheme
*/
protected ColorScheme getColorScheme() {
return MineOS.getOpened().getSettings().getColorScheme();
Expand All @@ -254,4 +323,16 @@ public void drawVerticalLine(GuiGraphics graphics, int x, int y1, int y2, int rg
public void drawHorizontalLine(GuiGraphics graphics, int x1, int x2, int y, int rgb) {
graphics.fill(x1, y, x2, y + 1, rgb);
}

public CompoundTag writeState() {
CompoundTag tag = new CompoundTag();
tag.putString("type", getClass().getName());
tag.putInt("x", xPosition);
tag.putInt("y", yPosition);
tag.putInt("left", left);
tag.putInt("top", top);
tag.putBoolean("visible", visible);
tag.putBoolean("enabled", enabled);
return tag;
}
}
31 changes: 23 additions & 8 deletions common/src/main/java/dev/ultreon/devices/api/app/Layout.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;

import java.awt.*;
import java.util.ArrayList;
Expand Down Expand Up @@ -79,23 +80,23 @@ public Layout(int width, int height) {
* noted that the width must be in the range of 20 to 362 and
* the height 20 to 164.
*
* @param width
* @param height
* @param width the width of the layout
* @param height the height of the layout
*/
public Layout(int left, int top, int width, int height) {
super(left, top);

if (width < 13 && false)
throw new IllegalArgumentException("Width can not be less than 13 wide");

if (height < 1 && false)
throw new IllegalArgumentException("Height can not be less than 1 tall");

this.components = new CopyOnWriteArrayList<>();
this.width = width;
this.height = height;
}

public Layout(CompoundTag tag) {
super(tag);
title = tag.getString("title");
components = Component.readComponents(tag.getList("components", Tag.TAG_COMPOUND));
}

/**
* Called on the initialization of the layout. Caused by
* {@link Application#setCurrentLayout(Layout)}. Will
Expand Down Expand Up @@ -306,6 +307,16 @@ public void setVisible(boolean visible) {
}
}

@Override
public CompoundTag writeState() {
CompoundTag tag = super.writeState();
tag.putString("title", title == null ? "" : title);
tag.put("components", Component.writeComponents(components));
tag.put("background", background == null ? null : background.writeState());

return tag;
}

/**
* Sets the initialization listener for this layout.
* See {@link InitListener}.
Expand Down Expand Up @@ -370,6 +381,10 @@ public interface Background {
* @param height the height of the layout
*/
void render(GuiGraphics graphics, Minecraft mc, int x, int y, int width, int height, int mouseX, int mouseY, boolean windowActive);

default CompoundTag writeState() {
return new CompoundTag();
}
}

public static class Context extends Layout {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ public void setItemClickListener(ItemClickListener<E> itemClickListener) {
*
* @param e the item
*/
public void addItem(@NotNull E e) {
public void addItem(@Nullable E e) {
if (e == null)
return;
items.add(e);
sort();
if (initialized) {
Expand Down
3 changes: 1 addition & 2 deletions common/src/main/java/dev/ultreon/devices/api/bios/Bios.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import dev.ultreon.devices.api.io.Drive;
import dev.ultreon.devices.api.os.OperatingSystem;
import dev.ultreon.devices.core.BootLoader;
import net.minecraft.client.gui.screens.Screen;

import java.util.UUID;

Expand All @@ -12,7 +11,7 @@ public interface Bios {

boolean powerOff();

void addOperatingSystem(BootLoader<?> operatingSystem);
void addBootLoader(BootLoader<?> operatingSystem);

OperatingSystem getRunningOS();

Expand Down
10 changes: 4 additions & 6 deletions common/src/main/java/dev/ultreon/devices/api/os/OSScreen.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@
import dev.ultreon.devices.api.app.Application;
import dev.ultreon.devices.api.bios.Bios;
import dev.ultreon.devices.api.bios.InterruptData;
import dev.ultreon.devices.client.Display;
import dev.ultreon.devices.client.DisplayGui;
import dev.ultreon.devices.object.AppInfo;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;

import java.util.concurrent.CompletableFuture;

public abstract class OSScreen extends Screen implements OperatingSystem {
private Display display;
private DisplayGui display;

protected OSScreen() {
super(Component.literal("Virtual Display"));
Expand Down Expand Up @@ -70,7 +68,7 @@ public Screen getScreen() {
}

@Override
public void connectDisplay(Display display) {
public void connectDisplay(DisplayGui display) {
this.display = display;
this.width = display.getScreenWidth();
this.height = display.getScreenHeight();
Expand All @@ -81,7 +79,7 @@ public void disconnectDisplay() {
this.display = null;
}

public Display getDisplay() {
public DisplayGui getDisplay() {
return display;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.ultreon.devices.api.os;

import dev.ultreon.devices.client.Display;
import dev.ultreon.devices.client.DisplayGui;
import dev.ultreon.devices.object.AppInfo;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.nbt.CompoundTag;
Expand Down Expand Up @@ -38,7 +38,9 @@ public interface OperatingSystem {

Screen getScreen();

void connectDisplay(Display display);
void connectDisplay(DisplayGui display);

void disconnectDisplay();

CompoundTag writeState();
}
Loading

0 comments on commit e9b3c3d

Please sign in to comment.