mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-13 17:04:25 +00:00
feat: add Java material enumeration
This commit is contained in:
1 parent
9b78099d21
commit
2bb5e7ffc9
11 files changed
+267
-10
No files matched your search
+2
-1
@@ -529,7 +529,7 @@ their sibling and only need the annotation and javadoc.
|
||||
| --- | --- | --- |
|
||||
| `TileMultipart.partList(): scala.collection.Seq` | `jPartList(): java.util.List` | Sibling already exists |
|
||||
| `MultiPartRegistry.registerParts(IPartFactory2, scala.collection.Seq)` | `registerParts(IPartFactory2, String...)` | Sibling already exists |
|
||||
| `MicroMaterialRegistry.getIdMap(): scala.Tuple2[]` | `materialCount(): int` plus existing `materialName(int)` and `getMaterial(int)` | The array index **is** the material ID, so no pair or map type is needed |
|
||||
| `MicroMaterialRegistry.getIdMap(): scala.Tuple2[]` | `materialCount(): int` plus existing `materialName(int)` and `getMaterial(int)` | Implemented with static/companion deprecation; [guide and compiling example](docs/api/MATERIAL_ENUMERATION.md). Consumer release/adoption remains pending |
|
||||
| `TileMultipart.operate(scala.Function1<TMultiPart, BoxedUnit>)` | `forEachPart(java.util.function.Consumer<TMultiPart>)` | Preserve the existing skip-unbound-part behavior |
|
||||
| `TileMultipart.occlusionTest(scala.collection.Seq, TMultiPart)` | `occlusionTest(Collection<TMultiPart>, TMultiPart)` | |
|
||||
| `TileMultipart.loadParts(scala.collection.Iterable)` | `loadParts(Collection<TMultiPart>)` | Schematica and GuideNH reflect the Scala descriptor; see Phase 10 |
|
||||
@@ -544,6 +544,7 @@ same-name overload there invites a silent wrong-overload bind.
|
||||
|
||||
- [ ] Add the missing Java-shaped siblings over shared behavior, preserving legacy override dispatch and avoiding
|
||||
recursive forwarding as required by the API migration design.
|
||||
- [x] Add and document `materialCount()` with existing indexed lookups; retain and deprecate both `getIdMap()` entries.
|
||||
- [ ] Mark all nine rows `@Deprecated` with javadoc naming the replacement.
|
||||
- [ ] Confirm every original descriptor still exists in the ABI fixture after the change.
|
||||
- [ ] Document the supported API with compiling usage examples and an old-to-new migration guide. Validate Java
|
||||
|
||||
@@ -488,6 +488,26 @@ behavior:
|
||||
API, trait, generator, registry, or tile change. Add UtilitiesInExcess as a compile/runtime fixture now even though
|
||||
it is not yet in the pack.
|
||||
|
||||
## Java API adoption ledger
|
||||
|
||||
This ledger tracks migration of a specific legacy contract, not completion of an entire consumer's migration.
|
||||
The FMP material-enumeration addition is implemented on `algent/java`, with the
|
||||
[documented Java replacement](docs/api/MATERIAL_ENUMERATION.md) and a compiling example. It is not yet a released
|
||||
minimum dependency version. Unlisted contracts remain governed by the inventories above.
|
||||
|
||||
| Legacy contract | Consumer and inspected source | Supported replacement | Consumer migration/release | Target-pack adoption and removal gate |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `MicroMaterialRegistry.getIdMap(): scala.Tuple2[]` | UtilitiesInExcess `3e107a1fe9bc15fcb6a808242ffda1354dac7c3a`: `FMPRecipeLoader.run`, `UEMultipartItem.getSubItems` | `materialCount()` with `materialName(int)` and, when needed, `getMaterial(int)` | Source patch and first released version pending; checkout used as reference only | No migrated pack version verified; retain the bridge |
|
||||
| `MicroMaterialRegistry.getIdMap(): scala.Tuple2[]` | Extra Utilities 1.2.12 decompiled reference: both NEI microblock handlers and `multipart.microblock.ItemMicroBlock` | Same ID-based Java enumeration | No editable upstream consumer in scope; retirement/replacement remains pending | Verify Extra Utilities is absent and its replacement uses the new API before retiring this dependency |
|
||||
|
||||
Evidence for the FMP addition is under ignored `run/migration-material-enumeration-reference/`. The original
|
||||
reference-compiled Scala consumer still exercises the companion and tuple-array descriptor. The new compiling Java
|
||||
example has no Scala imports or bytecode references. Runtime checks cover initialized ID lookup and handshake order;
|
||||
they do not establish that an updated UtilitiesInExcess release has shipped or entered the pack.
|
||||
|
||||
FMP's own `ItemMicroPart` and `MicroRecipe$` still use the legacy array internally. Their migration, any additional
|
||||
retained companion users, and the other Scala-facing contracts remain separate removal gates.
|
||||
|
||||
## Practical priority for the current branch
|
||||
|
||||
1. Keep the existing `+678` ABI fixture as the exact binary floor and correct failures before source cleanup.
|
||||
|
||||
@@ -16,7 +16,7 @@ migration checkout; `codex/tile-compatibility-fixes` was deleted after its fixes
|
||||
|
||||
## Current state and next target
|
||||
|
||||
**530 plain-JVM tests and 237 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **224 Java
|
||||
**535 plain-JVM tests and 238 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **224 Java
|
||||
files and 9 Scala files / 747 nonblank Scala lines**. The packaged inventory has 443 classes.
|
||||
|
||||
Review follow-up: restored packet-scheduler callback mutation behavior with the original Scala hash-map traversal,
|
||||
@@ -31,17 +31,25 @@ use, but no override triggering these three regressions was found. All 443 class
|
||||
payloads and 116 generated dumps are retained. The agreed next milestone is the documented consumer-facing Java API,
|
||||
followed by consumer release/adoption and final Scala removal; see the plan's API migration design and Phases 8–10.
|
||||
|
||||
Latest bounded target: `ScalaSignature.MethodSymbol.info` delegates info-ID evaluation to
|
||||
`ScalaSignatureParser.methodSymbolInfo`. Seven characterization tests were committed first as `9859aa8`. They pin
|
||||
infoId/eval order, repeated uncached reads, exact and null results, the result cast, failures, unused symbol/type members
|
||||
and the frozen Scala caller descriptor. All 519 frozen JVM consumers pass; checks preserve 442 retained class/member
|
||||
APIs, all 17 ScalaSignature payloads, 3,744 unrelated method bodies and all 116 generated dumps. No class is added or
|
||||
removed; the total stays 443 classes. Evidence: `run/migration-method-symbol-info-reference/`.
|
||||
Latest API addition: `MicroMaterialRegistry.materialCount()` completes ID-based enumeration with the existing
|
||||
`materialName(int)` and `getMaterial(int)` methods. Both `getIdMap()` entries are deprecated with unchanged descriptors
|
||||
and live-array behavior. Two baseline cases were committed first as `9b78099`; three further JVM cases and one Forge
|
||||
case cover the new API and a compiling Java example. All 532 pre-change compiled tests pass with their recorded
|
||||
version. The 443 class APIs retain all existing members, with one public static method added; 17 ScalaSignature
|
||||
payloads, 3,746 existing method bodies and 116 generated dumps are unchanged apart from expected deprecation metadata
|
||||
and build-version literals. Evidence: `run/migration-material-enumeration-reference/`.
|
||||
|
||||
The [material enumeration guide](docs/api/MATERIAL_ENUMERATION.md) documents lifecycle, server ID ordering and failure
|
||||
boundaries. The consumer audit's adoption ledger records the inspected UtilitiesInExcess revision and Extra Utilities
|
||||
1.2.12; their source migrations, releases and pack adoption remain pending. The supplied checkouts remain reference-only.
|
||||
|
||||
**Next priority: close the Java API gaps in Phases 2 and 9 and map consumer migrations in Phase 10.** Reuse the existing
|
||||
Java surface; supply missing capabilities, precise contracts, migration guidance and compiling examples. Cover
|
||||
subclass/override behavior and generated extensions as well as ordinary calls. ProjectRed's illuminated microblocks
|
||||
are the representative external extension case. Consumer mods may remain Scala internally while adopting this API.
|
||||
The next bounded API candidate is `TileMultipart` collection/traversal access, preserving legacy getter and callback
|
||||
overrides, captured-sequence mutation behavior and detached-part filtering. Do not repeat material enumeration as an
|
||||
unimplemented gap or treat its FMP-side completion as consumer adoption.
|
||||
|
||||
Pause mechanical extraction of retained Scala shells unless it enables that API, fixes a demonstrated issue or has
|
||||
a measured benefit. `ScalaSignature.ClassSymbolRef.info` remains an optional bounded extraction, not the default next
|
||||
|
||||
@@ -14,3 +14,7 @@ If you only want to use the API and not modify it:
|
||||
* Place both mods in your /libs/ folder and link them as libraries in your IDE.
|
||||
|
||||
Implementation of all parts of the API should be clean and easy in Java. The minecraft multipart mod is implemented in java as a test case.
|
||||
|
||||
Java API migration guides:
|
||||
|
||||
* [Enumerating microblock materials](docs/api/MATERIAL_ENUMERATION.md), including a compiling example and legacy API replacements.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Enumerating microblock materials from Java
|
||||
|
||||
The `algent/java` branch adds `MicroMaterialRegistry.materialCount()`. Use it with the existing
|
||||
`materialName(int)` and `getMaterial(int)` methods to enumerate materials without importing Scala types.
|
||||
This API is not yet tied to a published release; consumers must require an FMP version containing the addition.
|
||||
|
||||
## Example
|
||||
|
||||
The following method copies the active material names in numeric ID order:
|
||||
|
||||
```java
|
||||
public static List<String> materialNames() {
|
||||
int count = MicroMaterialRegistry.materialCount();
|
||||
List<String> names = new ArrayList<>(count);
|
||||
for (int id = 0; id < count; id++) {
|
||||
names.add(MicroMaterialRegistry.materialName(id));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
```
|
||||
|
||||
Imports and the enclosing class are in the [compiling example](../../src/test/java/codechicken/microblock/examples/MaterialEnumerationExample.java).
|
||||
It is compiled and exercised by the normal `test` task. It also compiles with only the FMP dev jar and Java 8 APIs on
|
||||
the compile classpath; this does not remove FMP's runtime dependencies. Use `MicroMaterialRegistry.getMaterial(id)` in the loop when
|
||||
you also need the `IMicroMaterial`, for example to obtain its item. That returns the registered instance, not a copy.
|
||||
The example's list is an independent copy; editing it does not change the registry.
|
||||
|
||||
## Timing, order and identity
|
||||
|
||||
- Enumerate after ForgeMicroblock has built its ID map during post-initialization. A consumer's own post-init handler
|
||||
needs suitable mod ordering if it enumerates there; later lifecycle/game callbacks can use the initialized map.
|
||||
Consumers must not call `setupIDMap()` themselves to force readiness.
|
||||
- On a multiplayer client, enumeration of the connected server's IDs requires a completed, successful FMP handshake.
|
||||
FMP also rebuilds the local map before server startup. Reacquire IDs after map replacement.
|
||||
- Use the game/lifecycle thread. The calls are live lookups, not an atomic snapshot: do not rebuild the map or perform
|
||||
registration/handshake work from inside an enumeration loop.
|
||||
- Local setup orders IDs by material name. A multiplayer client adopts server order; do not sort or filter IDs when
|
||||
preserving a mapping. Store material names in saved data and resolve their numeric IDs for the active map.
|
||||
- `materialCount()` counts ID slots, including the missing-material placeholder when present. It throws
|
||||
`IllegalStateException` before initialization and returns zero for an initialized empty map.
|
||||
- A failed handshake can leave unresolved slots. The count includes them; `materialName(id)` and `getMaterial(id)`
|
||||
retain their existing `NullPointerException` for such slots. FMP disconnects the client for missing mappings.
|
||||
The count is not a handshake-success indicator, and callers should not silently skip unresolved IDs.
|
||||
- The existing indexed lookups throw `ArrayIndexOutOfBoundsException` outside the active ID range and
|
||||
`NullPointerException` before map initialization.
|
||||
|
||||
## Migrating existing consumers
|
||||
|
||||
| Legacy expression | Java API |
|
||||
| --- | --- |
|
||||
| `getIdMap().length` | `materialCount()` |
|
||||
| `getIdMap()[id]._1()` | `materialName(id)` |
|
||||
| `getIdMap()[id]._2()` | `getMaterial(id)` |
|
||||
| Loop over the tuple array | Loop over IDs from zero to `materialCount()`, exclusive |
|
||||
|
||||
For UtilitiesInExcess, apply this to `FMPRecipeLoader.run()` and `UEMultipartItem.getSubItems()`: replace each tuple
|
||||
loop with an ID loop and use `materialName(id)` wherever the tuple name was used. Preserve its recipe/item ordering,
|
||||
filters and material-name NBT. A material object, when needed, is available from `getMaterial(id)`.
|
||||
Extra Utilities' NEI handlers use both tuple fields; both indexed replacements are available.
|
||||
|
||||
The static and companion `getIdMap()` methods are deprecated, with their original descriptors and live-array
|
||||
behavior retained. This change does not authorize removal of either method. The
|
||||
[consumer adoption ledger](../../JAVA_MIGRATION_CONSUMER_AUDIT.md#java-api-adoption-ledger) records the migrations and
|
||||
released pack versions still needed.
|
||||
|
||||
## Validation
|
||||
|
||||
The JVM tests cover the legacy array contract, initialization, server ordering, empty maps, unresolved slots, the
|
||||
compiled Java example and the frozen Scala consumer. The Forge test checks that the Java enumeration matches the
|
||||
initialized registry and the material-ID handshake payload. The public addition does not change packet or NBT formats.
|
||||
@@ -1724,3 +1724,20 @@ differences belong in the [divergence ledger](../../JAVA_MIGRATION_DIVERGENCES.m
|
||||
- ProjectRed, Chisel and ExtraUtilities extend `BlockMicroMaterial`; no supplied consumer overrides the affected
|
||||
accessors. These are verified extension-contract regressions, without a demonstrated current-pack gameplay
|
||||
failure. Evidence is under ignored `run/conversion-review/`; migration-plan changes remain deferred.
|
||||
|
||||
### 2026-09-04 — Java material enumeration API
|
||||
|
||||
- Committed two baseline cases first as `9b78099`, pinning the shared legacy array, uninitialized access, server ID
|
||||
ordering, missing slots and empty maps. Saved the pre-API jar and all 532 compiled tests before implementation.
|
||||
- Added `MicroMaterialRegistry.materialCount()` beside the existing indexed name/material lookups. It reports the
|
||||
active ID-map length and explicitly rejects an uninitialized map. The static and companion `getIdMap()` methods
|
||||
keep their original descriptors and live-array behavior, with deprecation documentation pointing at the Java API.
|
||||
- Added three JVM cases, a compiling Java enumeration example and one Forge handshake/registry case. Normal/clean build/style
|
||||
checks, 535 JVM tests, 238 Java 8 Forge tests and all 532 frozen pre-change tests pass. The example compiles against
|
||||
only the dev jar and Java 8 APIs and has no Scala bytecode references; FMP's runtime dependencies remain in place.
|
||||
- Binary comparison retains all 443 class APIs with exactly one new public static method and two deprecations.
|
||||
All 17 ScalaSignature payloads, 3,746 existing method bodies and 116 generated dumps are unchanged, allowing only
|
||||
the expected deprecation metadata and build-version literals. No production class or dependency is added.
|
||||
- Added the material-enumeration guide and the first consumer adoption ledger rows. UtilitiesInExcess's two source
|
||||
call sites and Extra Utilities' tuple-array readers have supported replacements; consumer changes, releases and
|
||||
pack adoption remain pending. Evidence is under ignored `run/migration-material-enumeration-reference/`.
|
||||
+20
@@ -3,6 +3,8 @@ package codechicken.multipart.test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
@@ -22,6 +24,24 @@ import scala.Tuple2;
|
||||
|
||||
class MicroblockPacketHandlerFunctionalTest {
|
||||
|
||||
@Test
|
||||
void javaEnumerationUsesTheSameIdsAsTheInitializedRegistryAndHandshake() {
|
||||
PacketCustom outgoing = new PacketCustom("test", 1);
|
||||
MicroMaterialRegistry.writeIDMap(outgoing);
|
||||
PacketCustom incoming = new PacketCustom(outgoing.getByteBuf().copy());
|
||||
int count = MicroMaterialRegistry.materialCount();
|
||||
assertTrue(count > 0);
|
||||
assertEquals(count, incoming.readInt());
|
||||
for (int id = 0; id < count; id++) {
|
||||
String name = MicroMaterialRegistry.materialName(id);
|
||||
assertEquals(name, incoming.readString());
|
||||
assertEquals(id, MicroMaterialRegistry.materialID(name));
|
||||
assertNotNull(MicroMaterialRegistry.getMaterial(id));
|
||||
assertSame(MicroMaterialRegistry.getMaterial(name), MicroMaterialRegistry.getMaterial(id));
|
||||
}
|
||||
assertEquals(0, incoming.getByteBuf().readableBytes());
|
||||
}
|
||||
|
||||
@Test
|
||||
void sendsTheCompleteMaterialIdMapDuringTheServerHandshake() {
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
|
||||
@@ -89,6 +89,13 @@ public final class MicroMaterialRegistry$ {
|
||||
return MicroMaterialRegistry.getMaterial(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the same legacy backing array as {@link MicroMaterialRegistry#getIdMap()}.
|
||||
*
|
||||
* @deprecated For enumeration, use {@link MicroMaterialRegistry#materialCount()},
|
||||
* {@link MicroMaterialRegistry#materialName(int)} and {@link MicroMaterialRegistry#getMaterial(int)}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Tuple2<String, IMicroMaterial>[] getIdMap() {
|
||||
return MicroMaterialRegistry.getIdMap();
|
||||
}
|
||||
|
||||
@@ -241,6 +241,15 @@ public final class MicroMaterialRegistry {
|
||||
return idWriter.read(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the persistent name at a numeric ID in the active material map. IDs may change when the map is rebuilt or
|
||||
* synchronized with a server; store material names rather than numeric IDs in persistent data.
|
||||
*
|
||||
* @param id an ID from zero (inclusive) to {@link #materialCount()} (exclusive)
|
||||
* @throws ArrayIndexOutOfBoundsException if the ID is outside the active map
|
||||
* @throws NullPointerException if the map is uninitialized or the ID is unresolved after a failed
|
||||
* handshake
|
||||
*/
|
||||
public static String materialName(int id) {
|
||||
return idMap[id]._1();
|
||||
}
|
||||
@@ -258,10 +267,47 @@ public final class MicroMaterialRegistry {
|
||||
return typeMap.get(remapped(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the registered material instance at an ID in the active material map; no copy is made.
|
||||
*
|
||||
* @param id an ID from zero (inclusive) to {@link #materialCount()} (exclusive)
|
||||
* @throws ArrayIndexOutOfBoundsException if the ID is outside the active map
|
||||
* @throws NullPointerException if the map is uninitialized or the ID is unresolved after a failed
|
||||
* handshake
|
||||
*/
|
||||
public static IMicroMaterial getMaterial(int id) {
|
||||
return idMap[id]._2();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of numeric ID slots in the active material map, including the missing-material placeholder
|
||||
* when present. Enumerate IDs from zero (inclusive) to this count (exclusive) with {@link #materialName(int)} and
|
||||
* {@link #getMaterial(int)}.
|
||||
*
|
||||
* FMP builds the map during post-initialization and before server startup. A multiplayer handshake replaces the
|
||||
* client map with server ID order. Enumerate on the game/lifecycle thread after initialization; multiplayer clients
|
||||
* must also finish the handshake successfully. The map must not be rebuilt during enumeration. Do not cache numeric
|
||||
* IDs across map replacements. A failed handshake can leave unresolved slots, which this count includes; it is not
|
||||
* a readiness check.
|
||||
*
|
||||
* @return the active map length, or zero for an initialized empty map
|
||||
* @throws IllegalStateException if FMP has not initialized the material ID map
|
||||
*/
|
||||
public static int materialCount() {
|
||||
if (idMap == null) {
|
||||
throw new IllegalStateException("The material ID map has not been initialized.");
|
||||
}
|
||||
return idMap.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the legacy live backing array, or null before ID-map initialization. A map replacement leaves earlier
|
||||
* array references pointing at the old map; unresolved IDs after a failed handshake contain null.
|
||||
*
|
||||
* @deprecated For enumeration, use {@link #materialCount()}, {@link #materialName(int)} and
|
||||
* {@link #getMaterial(int)}. The Scala array descriptor is retained for existing consumers.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Tuple2<String, IMicroMaterial>[] getIdMap() {
|
||||
return idMap;
|
||||
}
|
||||
|
||||
+45
-2
@@ -35,11 +35,12 @@ import codechicken.lib.vec.Cuboid6;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
import codechicken.microblock.MicroMaterialRegistry.IMicroHighlightRenderer;
|
||||
import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial;
|
||||
import codechicken.microblock.examples.MaterialEnumerationExample;
|
||||
|
||||
/**
|
||||
* The registry is global mutable state, so everything is registered once in {@link #registerAndFreezeIdMap()} and the
|
||||
* cases below only read it. Error paths are not covered: they call the microblock logger, which is null until
|
||||
* MicroblockProxy.preInit runs, so they cannot execute headless.
|
||||
* cases below restore any temporary state changes. Logger-backed error paths require MicroblockProxy.preInit and cannot
|
||||
* execute headless.
|
||||
*/
|
||||
class MicroMaterialRegistryCharacterizationTest {
|
||||
|
||||
@@ -129,6 +130,48 @@ class MicroMaterialRegistryCharacterizationTest {
|
||||
assertEquals(java.lang.reflect.Array.getLength(original), MicroMaterialRegistry.getIdMap().length);
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaExampleEnumeratesTheSameMaterialsWithoutExposingTheLegacyArray() throws Exception {
|
||||
String[] names = Arrays.stream(MicroMaterialRegistry.getIdMap()).map(entry -> entry._1())
|
||||
.toArray(String[]::new);
|
||||
assertEquals(names.length, MicroMaterialRegistry.materialCount());
|
||||
assertEquals(Arrays.asList(names), MaterialEnumerationExample.materialNames());
|
||||
assertTrue(MicroMaterialRegistry.class.getMethod("getIdMap").isAnnotationPresent(Deprecated.class));
|
||||
assertTrue(MicroMaterialRegistry$.class.getMethod("getIdMap").isAnnotationPresent(Deprecated.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void javaEnumerationTracksServerOrderMissingSlotsAndEmptyMaps() {
|
||||
try {
|
||||
MicroMaterialRegistry.readIDMap(incomingMap("test:stone", "test:glass"));
|
||||
assertEquals(2, MicroMaterialRegistry.materialCount());
|
||||
assertEquals(Arrays.asList("test:stone", "test:glass"), MaterialEnumerationExample.materialNames());
|
||||
|
||||
MicroMaterialRegistry.readIDMap(incomingMap("test:stone", "server:unavailable", "test:glass"));
|
||||
assertEquals(3, MicroMaterialRegistry.materialCount());
|
||||
assertThrows(NullPointerException.class, MaterialEnumerationExample::materialNames);
|
||||
|
||||
MicroMaterialRegistry.readIDMap(incomingMap());
|
||||
assertEquals(0, MicroMaterialRegistry.materialCount());
|
||||
assertEquals(Collections.emptyList(), MaterialEnumerationExample.materialNames());
|
||||
} finally {
|
||||
MicroMaterialRegistry$.MODULE$.setupIDMap();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void materialCountRejectsAnUninitializedMapInsteadOfReportingAnEmptyRegistry() throws Exception {
|
||||
Field idMap = MicroMaterialRegistry.class.getDeclaredField("idMap");
|
||||
idMap.setAccessible(true);
|
||||
Object original = idMap.get(null);
|
||||
try {
|
||||
idMap.set(null, null);
|
||||
assertThrows(IllegalStateException.class, MicroMaterialRegistry::materialCount);
|
||||
} finally {
|
||||
idMap.set(null, original);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMaterialByNameResolvesRemapsAndReturnsNullWhenUnknown() {
|
||||
assertSame(GLASS, MicroMaterialRegistry.getMaterial("test:glass"));
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package codechicken.microblock.examples;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import codechicken.microblock.MicroMaterialRegistry;
|
||||
|
||||
/** Compiling example for docs/api/MATERIAL_ENUMERATION.md; call after material IDs are ready. */
|
||||
public final class MaterialEnumerationExample {
|
||||
|
||||
private MaterialEnumerationExample() {}
|
||||
|
||||
public static List<String> materialNames() {
|
||||
int count = MicroMaterialRegistry.materialCount();
|
||||
List<String> names = new ArrayList<>(count);
|
||||
for (int id = 0; id < count; id++) {
|
||||
names.add(MicroMaterialRegistry.materialName(id));
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user