Skip to content

Commit 2cb3d3c

Browse files
slightly better type wrappers
1 parent ae28439 commit 2cb3d3c

File tree

7 files changed

+330
-155
lines changed

7 files changed

+330
-155
lines changed

src/main/java/dev/latvian/mods/kubejs/block/MapColorHelper.java

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.latvian.mods.kubejs.block;
22

3+
import dev.latvian.mods.kubejs.error.KubeRuntimeException;
34
import dev.latvian.mods.rhino.Scriptable;
45
import dev.latvian.mods.rhino.Undefined;
56
import net.minecraft.world.item.DyeColor;
@@ -92,18 +93,31 @@ private static MapColorHelper add(String id, MapColor color) {
9293
add("glow_lichen", MapColor.GLOW_LICHEN);
9394
}
9495

95-
@SuppressWarnings("DuplicateBranchesInSwitch")
9696
public static MapColor wrap(Object o) {
9797
return switch (o) {
98-
case Undefined undefined -> MapColor.NONE;
99-
case Scriptable s when Undefined.isUndefined(s) -> MapColor.NONE;
98+
case Undefined undefined -> throw new KubeRuntimeException("MapColor cannot be undefined!");
99+
case Scriptable s when Undefined.isUndefined(s) -> throw new KubeRuntimeException("MapColor cannot be undefined!");
100100
case MapColor c -> c;
101-
case String s when s.isBlank() -> MapColor.NONE;
102-
case String s when s.charAt(0) == '#' -> findClosest(Integer.decode(s)).color;
103-
case String s -> NAME_MAP.getOrDefault(s.toLowerCase(Locale.ROOT), NONE).color;
101+
case String s when s.isBlank() -> throw new KubeRuntimeException("MapColor string cannot be blank!");
102+
case String s when s.charAt(0) == '#' -> {
103+
try {
104+
yield findClosest(Integer.decode(s)).color;
105+
} catch (Exception ex) {
106+
throw new KubeRuntimeException("Invalid MapColor hex value '%s'".formatted(s), ex);
107+
}
108+
}
109+
case String s -> {
110+
var color = NAME_MAP.get(s.toLowerCase(Locale.ROOT));
111+
if (color != null) {
112+
yield color.color;
113+
}
114+
115+
throw new KubeRuntimeException("Unknown MapColor '%s'".formatted(s));
116+
}
104117
case Number n -> findClosest(n.intValue()).color;
105118
case DyeColor c -> c.getMapColor();
106-
case null, default -> MapColor.NONE;
119+
case null -> throw new KubeRuntimeException("MapColor cannot be null!");
120+
default -> throw new KubeRuntimeException("Invalid MapColor input %s".formatted(o));
107121
};
108122
}
109123

src/main/java/dev/latvian/mods/kubejs/block/SoundTypeWrapper.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package dev.latvian.mods.kubejs.block;
22

3-
import com.google.gson.JsonElement;
3+
import com.google.gson.JsonPrimitive;
4+
import dev.latvian.mods.kubejs.error.KubeRuntimeException;
5+
import dev.latvian.mods.kubejs.script.SourceLine;
46
import dev.latvian.mods.rhino.Context;
7+
import dev.latvian.mods.rhino.Scriptable;
58
import dev.latvian.mods.rhino.Undefined;
69
import dev.latvian.mods.rhino.type.TypeInfo;
710
import dev.latvian.mods.rhino.util.wrap.TypeWrapperFactory;
11+
import net.minecraft.resources.ResourceLocation;
812
import net.minecraft.world.level.block.SoundType;
913

1014
import java.lang.reflect.Modifier;
@@ -42,12 +46,23 @@ public Map<String, SoundType> getMap() {
4246

4347
@Override
4448
public SoundType wrap(Context cx, Object o, TypeInfo target) {
45-
if (o instanceof SoundType t) {
46-
return t;
47-
} else if (o == null || Undefined.isUndefined(o)) {
48-
return SoundType.EMPTY;
49-
} else {
50-
return getMap().getOrDefault((o instanceof JsonElement j ? j.getAsString() : o.toString()).toLowerCase(Locale.ROOT), SoundType.EMPTY);
51-
}
49+
return switch (o) {
50+
case SoundType t -> t;
51+
case null -> throw new KubeRuntimeException("SoundType cannot be null!").source(SourceLine.of(cx));
52+
case Undefined u -> throw new KubeRuntimeException("Cannot wrap undefined as SoundType!").source(SourceLine.of(cx));
53+
case Scriptable s when Undefined.isUndefined(s) -> throw new KubeRuntimeException("Cannot wrap undefined as SoundType!").source(SourceLine.of(cx));
54+
case JsonPrimitive j -> wrap(cx, j.getAsString(), target);
55+
case ResourceLocation id -> wrap(cx, id.toString(), target);
56+
// TODO: maybe a record-style type wrapper? that's kinda all SoundType is anyways
57+
case CharSequence cs -> {
58+
var soundType = getMap().get(cs.toString());
59+
if (soundType != null) {
60+
yield soundType;
61+
}
62+
63+
throw new KubeRuntimeException("Unknown SoundType '%s'".formatted(o)).source(SourceLine.of(cx));
64+
}
65+
default -> throw new KubeRuntimeException("Don't know how to wrap %s as sound type!".formatted(o)).source(SourceLine.of(cx));
66+
};
5267
}
5368
}

src/main/java/dev/latvian/mods/kubejs/core/PlayerSelector.java

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,51 @@
11
package dev.latvian.mods.kubejs.core;
22

3+
import dev.latvian.mods.kubejs.error.KubeRuntimeException;
34
import dev.latvian.mods.kubejs.plugin.builtin.wrapper.UUIDWrapper;
5+
import dev.latvian.mods.kubejs.script.SourceLine;
6+
import dev.latvian.mods.kubejs.util.Cast;
7+
import dev.latvian.mods.rhino.BaseFunction;
8+
import dev.latvian.mods.rhino.Context;
9+
import dev.latvian.mods.rhino.type.TypeInfo;
410
import net.minecraft.server.MinecraftServer;
511
import net.minecraft.server.level.ServerPlayer;
612
import org.jetbrains.annotations.Nullable;
713

814
import java.util.Locale;
9-
import java.util.Objects;
1015
import java.util.UUID;
1116

1217
@FunctionalInterface
1318
public interface PlayerSelector {
19+
TypeInfo TYPE_INFO = TypeInfo.of(PlayerSelector.class);
20+
21+
static PlayerSelector wrap(Context cx, Object o) {
22+
return switch (o) {
23+
case null -> throw new KubeRuntimeException("PlayerSelector cannot be null!").source(SourceLine.of(cx));
24+
case ServerPlayer sp -> identity(sp);
25+
case UUID uuid -> uuid(uuid);
26+
case BaseFunction fn -> Cast.to(cx.createInterfaceAdapter(TYPE_INFO, fn));
27+
default -> fromString(cx, String.valueOf(o).trim().toLowerCase(Locale.ROOT));
28+
};
29+
}
1430

15-
static PlayerSelector wrap(Object o) {
16-
if (o instanceof ServerPlayer sp) {
17-
return identity(sp);
18-
} else if (o instanceof UUID uuid) {
19-
return uuid(uuid);
20-
}
21-
22-
var name = Objects.toString(o, "").trim().toLowerCase(Locale.ROOT);
23-
31+
private static PlayerSelector fromString(Context cx, String name) {
2432
if (name.isEmpty()) {
25-
return identity(null);
33+
throw new KubeRuntimeException("PlayerSelector cannot be blank!").source(SourceLine.of(cx));
2634
}
2735

2836
var uuid = UUIDWrapper.fromString(name);
2937
if (uuid != null) {
3038
return uuid(uuid);
3139
}
3240

33-
return name(name).or(fuzzyName(name));
41+
return server -> {
42+
var player = name(name).or(fuzzyName(name)).getPlayer(server);
43+
if (player != null) {
44+
return player;
45+
}
46+
47+
throw new KubeRuntimeException("No player matched selector '%s'".formatted(name)).source(SourceLine.of(cx));
48+
};
3449
}
3550

3651
@Nullable

src/main/java/dev/latvian/mods/kubejs/plugin/builtin/wrapper/BlockWrapper.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import dev.latvian.mods.kubejs.block.predicate.BlockEntityPredicate;
44
import dev.latvian.mods.kubejs.block.predicate.BlockIDPredicate;
55
import dev.latvian.mods.kubejs.block.predicate.BlockPredicate;
6+
import dev.latvian.mods.kubejs.error.KubeRuntimeException;
67
import dev.latvian.mods.kubejs.registry.RegistryKubeEvent;
78
import dev.latvian.mods.kubejs.typings.Info;
89
import dev.latvian.mods.kubejs.util.Cast;
@@ -19,7 +20,6 @@
1920
import net.minecraft.core.registries.Registries;
2021
import net.minecraft.resources.ResourceLocation;
2122
import net.minecraft.world.level.block.Block;
22-
import net.minecraft.world.level.block.Blocks;
2323
import net.minecraft.world.level.block.state.BlockState;
2424
import net.minecraft.world.level.block.state.properties.BlockSetType;
2525
import net.minecraft.world.level.block.state.properties.Property;
@@ -126,15 +126,12 @@ public static Collection<BlockState> getAllBlockStates() {
126126
return ALL_STATE_CACHE;
127127
}
128128

129+
// TODO (26.1): RegistryAccessContainer => Context
129130
public static BlockState parseBlockState(RegistryAccessContainer registries, String string) {
130-
if (string.isEmpty()) {
131-
return Blocks.AIR.defaultBlockState();
132-
}
133-
134131
try {
135132
return BlockStateParser.parseForBlock(registries.access().lookupOrThrow(Registries.BLOCK), string, false).blockState();
136133
} catch (Exception ex) {
137-
return Blocks.AIR.defaultBlockState();
134+
throw new IllegalArgumentException("Invalid block state '%s'".formatted(string), ex);
138135
}
139136
}
140137

@@ -160,10 +157,16 @@ public static BlockSetType wrapSetType(Context cx, Object from, TypeInfo target)
160157
@Info("Parses a block state from the input string. May throw for invalid inputs!")
161158
public static BlockState wrapBlockState(RegistryAccessContainer registries, Object o) {
162159
return switch (o) {
163-
case null -> Blocks.AIR.defaultBlockState();
160+
case null -> throw new KubeRuntimeException("BlockState cannot be null!");
164161
case BlockState bs -> bs;
165162
case Block block -> block.defaultBlockState();
166-
default -> parseBlockState(registries, o.toString());
163+
default -> {
164+
try {
165+
yield parseBlockState(registries, o.toString());
166+
} catch (IllegalArgumentException ex) {
167+
throw new KubeRuntimeException("Failed to read block state from %s: %s".formatted(o, ex.getMessage()));
168+
}
169+
}
167170
};
168171
}
169172

@@ -192,4 +195,4 @@ public static void registerBuildingMaterial(Context cx, RegistryKubeEvent<Block>
192195
public static void registerBuildingMaterial(Context cx, RegistryKubeEvent<Block> event, KubeResourceLocation id) {
193196
registerBuildingMaterial(cx, event, id, (BuildingMaterialProperties) cx.jsToJava(Map.of(), BuildingMaterialProperties.TYPE_INFO));
194197
}
195-
}
198+
}

src/main/java/dev/latvian/mods/kubejs/plugin/builtin/wrapper/EntitySelectorWrapper.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package dev.latvian.mods.kubejs.plugin.builtin.wrapper;
22

33
import com.mojang.brigadier.StringReader;
4-
import dev.latvian.mods.kubejs.script.ConsoleJS;
4+
import dev.latvian.mods.kubejs.error.KubeRuntimeException;
5+
import dev.latvian.mods.kubejs.script.SourceLine;
56
import dev.latvian.mods.rhino.Context;
67
import dev.latvian.mods.rhino.util.HideFromJS;
78
import net.minecraft.advancements.critereon.MinMaxBounds;
@@ -25,15 +26,15 @@ public static EntitySelector of(EntitySelector selector) {
2526
@HideFromJS
2627
public static EntitySelector wrap(Context cx, @Nullable Object o) {
2728
if (o == null) {
28-
return ALL_ENTITIES_SELECTOR;
29+
throw new KubeRuntimeException("EntitySelector cannot be null!").source(SourceLine.of(cx));
2930
} else if (o instanceof EntitySelector s) {
3031
return s;
3132
}
3233

3334
String s = o.toString();
3435

3536
if (s.isBlank()) {
36-
return ALL_ENTITIES_SELECTOR;
37+
throw new KubeRuntimeException("EntitySelector cannot be blank!").source(SourceLine.of(cx));
3738
}
3839

3940
EntitySelector sel;
@@ -45,8 +46,7 @@ public static EntitySelector wrap(Context cx, @Nullable Object o) {
4546
sel = new EntitySelectorParser(new StringReader(s), true).parse();
4647
ENTITY_SELECTOR_CACHE.put(s, sel);
4748
} catch (Exception ex) {
48-
ConsoleJS.getCurrent(cx).error("Error parsing entity selector, falling back to all", ex);
49-
return ALL_ENTITIES_SELECTOR;
49+
throw new KubeRuntimeException("Failed to parse entity selector '%s'".formatted(s), ex).source(SourceLine.of(cx));
5050
}
5151
}
5252

0 commit comments

Comments
 (0)