mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-13 00:47:52 +00:00
refactor: port common microblock logic to Java
Retain Scala trait declarations and helper bridges for inherited mixin registration and existing consumers.
This commit is contained in:
1 parent
d6eb56b56f
commit
d89aaeacf3
6 files changed
+148
-60
No files matched your search
+15
-11
@@ -24,11 +24,12 @@ No trustworthy tool will produce a maintainable Java port automatically. A decom
|
||||
## Current status
|
||||
|
||||
Work continues on `algent/java`. The low-coupling queue, core part/tile types, registries, handlers, factories,
|
||||
placement/render helpers, both generators and all built-in tile traits are Java. Six generated microblock trait
|
||||
files and the compiler/signature/analyser compatibility shells remain Scala. Composite generation, Java-trait
|
||||
rewriting and compiler startup now delegate to Java helpers. Abstract Java mixins and Java-path side-only filtering
|
||||
are complete; the next bounded target is `microblock/MicroblockTraits.scala`. Retain the ScalaSignature
|
||||
path-dependent model bridges.
|
||||
placement/render helpers, both generators and all built-in tile traits are Java. Five generated microblock trait
|
||||
implementations and the compiler/signature/analyser compatibility shells remain Scala. `MicroblockTraits.scala`
|
||||
retains three inheritance/bridge declarations over Java behavior. Composite generation, Java-trait rewriting and
|
||||
compiler startup also delegate to Java helpers. Abstract Java mixins and Java-path side-only filtering are complete;
|
||||
multiple Scala-trait inheritance still needs its metadata. The next bounded target is the implementation in
|
||||
`microblock/FaceMicroblockTraits.scala`. Retain the ScalaSignature path-dependent model bridges.
|
||||
|
||||
Start with [JAVA_MIGRATION_HANDOFF.md](JAVA_MIGRATION_HANDOFF.md) for the exact source/test baseline, workflow and
|
||||
Java-source limitations. Read both the [ABI inventory](JAVA_MIGRATION_ABI_INVENTORY.md) and
|
||||
@@ -364,9 +365,10 @@ cache remain reference-identical; pass-through-interface coverage remains green.
|
||||
|
||||
### Phase 6 — Convert multipart core and microblocks
|
||||
|
||||
Status: core code, factories and ordinary helpers are Java. The six remaining generated microblock trait files
|
||||
can now move through the Java mixin path because both Phase 7 prerequisites are complete. The following gates
|
||||
continue to apply to those remaining units; completed per-type evidence is in the history.
|
||||
Status: core code, factories, ordinary helpers and common microblock trait behavior are Java. Five generated trait
|
||||
implementations remain. Extract their behavior while retaining Scala declarations where multiple-trait inheritance
|
||||
still needs signature metadata; abstract Java mixins and side filtering alone do not replace that metadata. The
|
||||
following gates continue to apply to those remaining units; completed per-type evidence is in the history.
|
||||
|
||||
- [ ] Add characterization coverage for each subsystem immediately before its conversion.
|
||||
- [ ] Convert the central tile, part, registry, placement, rendering, networking, scheduler, and microblock code in dependency order.
|
||||
@@ -548,8 +550,10 @@ The rewrite has two Phase 7 prerequisites:
|
||||
`@SideOnly(Side.CLIENT)` when ProjectRed rewrites the trait to Java, even though its `addTraits` ignores the
|
||||
`client` argument.
|
||||
|
||||
Both compiler prerequisites are complete. The FMP microblock trait files can now move through the Java path; removing
|
||||
external Scala-signature support still waits for a released ProjectRed Java rewrite.
|
||||
Both compiler prerequisites for the single-parent ProjectRed rewrite are complete. FMP's own microblock traits also
|
||||
use multiple Scala-trait inheritance: their implementation can move to Java helpers, while removing their Scala
|
||||
declarations needs a separate inheritance strategy. Removing external Scala-signature support still waits for a
|
||||
released ProjectRed Java rewrite.
|
||||
|
||||
UtilitiesInExcess is the cheapest case in the table because it is not yet in the pack. Anything fixed before it ships
|
||||
never becomes a compatibility obligation at all.
|
||||
@@ -677,7 +681,7 @@ Still open, and only to be decided when they become necessary:
|
||||
Track remaining work by completed compatibility gates, not the retired pre-audit calendar estimates:
|
||||
|
||||
1. Extract the remaining compiler algorithms with unchanged characterization and generated output.
|
||||
2. Characterize and port the remaining generated microblock traits through the completed Java-mixin path.
|
||||
2. Characterize and port the remaining generated microblock behavior, retaining necessary trait inheritance metadata.
|
||||
3. Resolve or explicitly retain the Scala model bridges; finish the applicable API and pre-merge cleanup gates.
|
||||
4. Complete packaged-pack, client and performance validation with recorded results.
|
||||
|
||||
|
||||
@@ -507,9 +507,12 @@ name like ProjectRed's `LightMicroblock`, direct-Java-source `TPartialOcclusionT
|
||||
direct-Java-source `TRedstoneTile`'s exact eight-method interface and class caching, and server-only pass-through
|
||||
forwarding, overloading, single-implementor selection, copying/rebinding, and removal cleanup.
|
||||
`TRedstoneTileFunctionalTest` additionally pins the ProjectRed/Extra Utilities query surface, masks, conduction, and
|
||||
world-side routing. `JavaTraitRegistrationFunctionalTest` now pins current/opposite-side selection for visible and
|
||||
invisible Java annotations, including method dispatch, field state and constructor initialization. Full downstream
|
||||
mixed tiles and client-side selection remain Phase 7 integration cases.
|
||||
world-side routing. `JavaTraitRegistrationFunctionalTest` pins current/opposite-side selection for visible and
|
||||
invisible Java annotations, including method dispatch, field state and constructor initialization.
|
||||
`MicroblockTraitsCharacterizationTest` executes a frozen concrete Scala consumer through all three common microblock
|
||||
helper bridges, covering slots, partial-box list behavior, material/render routing and particles. Its Forge companion
|
||||
covers generated common microblocks; the runtime interfaces used by Extra Utilities, ForgeRelocationFMP and GuideNH
|
||||
remain intact. Full downstream mixed tiles and client-side selection remain Phase 7 integration cases.
|
||||
|
||||
With these gates, the source audit is actionable: the port can simplify internals freely where no listed observation
|
||||
changes, while each externally observed behavior has a named consumer and a focused way to prove compatibility.
|
||||
+24
-16
@@ -16,23 +16,23 @@ migration checkout; `codex/tile-compatibility-fixes` was deleted after its fixes
|
||||
|
||||
## Current state and next target
|
||||
|
||||
**333 plain-JVM tests and 211 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **214 Java
|
||||
files and 9 Scala files / 1,188 nonblank Scala lines**. The packaged inventory has 437 classes.
|
||||
**340 plain-JVM tests and 213 Java 8 Forge tests pass, with zero failures/errors/skips.** Sources total **215 Java
|
||||
files and 9 Scala files / 1,170 nonblank Scala lines**. The packaged inventory has 438 classes.
|
||||
|
||||
Latest bounded compiler change: Java mixins now filter opposite-side fields, methods and constructors before metadata
|
||||
or bytecode rewriting. The Forge test first characterized the previous retention of visible/invisible annotations,
|
||||
state and constructor initialization (`a481859`). Current-side members remain; when the no-argument constructor is absent,
|
||||
an empty `$init$` satisfies the generated initializer contract without executing the opposite-side body. A regression
|
||||
also passes input through Forge's real side transformer before registration. Clean verification after stopping Gradle
|
||||
matched 432 class APIs, all five compiler closures and 3,643 non-target method bodies. All 112 reference dump names
|
||||
remain; 109 hashes are exact and only the trait, helper and composite from the SideOnly fixture differ. Four outputs
|
||||
are new for the already-stripped-constructor fixture. Local evidence is in
|
||||
`run/migration-java-side-only-reference/`; `clean` preserves this ignored directory.
|
||||
Latest bounded target: `MicroblockTraits.scala` delegates its eight remaining implementation methods to
|
||||
`MicroblockTraitLogic.java`; its particle callbacks already delegated to Java. The three Scala trait declarations,
|
||||
inheritance metadata and `$class` bridges remain. Characterization was committed first as `d6eb56b`, including a
|
||||
frozen concrete Scala consumer compiled against the unchanged jar. It exercises initialization, slots, immutable
|
||||
partial-box views, virtual class/material/render dispatch and particle evaluation order. Forge covers generated common
|
||||
microblocks and the existing server-side failure when a client fallback reaches the stripped `Block.getIcon`.
|
||||
Clean verification after stopping Gradle matches all 437 original class/member APIs, all 17 ScalaSignature payloads,
|
||||
3,674 non-target method bodies and all 116 generated dump names/hashes. Only the package-private Java helper is added.
|
||||
Local evidence is in `run/migration-microblock-traits-reference/`; `clean` preserves this ignored directory.
|
||||
|
||||
**Next: port `microblock/MicroblockTraits.scala` as the first generated microblock trait group.** Both Java-mixin
|
||||
prerequisites are complete. Characterize its interface/helper ABI, initialization, generated common/client dispatch,
|
||||
render/effect routing, slots, partial-occlusion boxes and item class ID before conversion. Keep the external ProjectRed
|
||||
Scala-trait fixture green and retain the ScalaSignature path-dependent model bridges.
|
||||
**Next: port the implementation in `microblock/FaceMicroblockTraits.scala`.** Characterize bounds/shape indexing,
|
||||
material solidity, negative-pass rendering, transparent/opaque face masks and generated dispatch before conversion.
|
||||
Retain the Scala declarations where inheritance metadata is still required. Keep the external ProjectRed Scala-trait
|
||||
fixture green and retain the ScalaSignature path-dependent model bridges; compiler changes stay separate.
|
||||
|
||||
Remaining Scala units:
|
||||
|
||||
@@ -41,7 +41,8 @@ Remaining Scala units:
|
||||
| `multipart/asm/ASMMixinCompiler.scala` | Retained nested models, construction callbacks and Scala entry-point shell |
|
||||
| `multipart/asm/ScalaSignature.scala` | Named models, primitive/erased bridges and five generic inner-construction branches |
|
||||
| `multipart/asm/StackAnalyser.scala` | Class/companion/model shell over Java `StackAnalyserLogic` |
|
||||
| `microblock/MicroblockTraits.scala`, `FaceMicroblockTraits.scala`, `CornerMicroblockTraits.scala`, `EdgeMicroblockTraits.scala`, `HollowMicroblockTraits.scala`, `TMicroOcclusion.scala` | Generated traits; port in dependency order now that both Java-mixin prerequisites are complete |
|
||||
| `microblock/MicroblockTraits.scala` | Three retained inheritance/bridge shells over Java implementation |
|
||||
| `microblock/FaceMicroblockTraits.scala`, `CornerMicroblockTraits.scala`, `EdgeMicroblockTraits.scala`, `HollowMicroblockTraits.scala`, `TMicroOcclusion.scala` | Generated trait implementations; port in dependency order while preserving inheritance metadata |
|
||||
|
||||
Both generators, both registries, core tile/part classes, ordinary microblock helpers/factories, handlers, networking,
|
||||
placement/render helpers and built-in tile traits are Java. The low-risk queue and immediate consumer gate are
|
||||
@@ -102,6 +103,13 @@ Compilation against the migrated artifact would defeat the binary-compatibility
|
||||
|
||||
## Retained compiler constraints
|
||||
|
||||
- **Microblock trait inheritance still needs Scala metadata.** Abstract Java mixins and Java `@SideOnly` filtering
|
||||
are supported, but that does not supply Scala multiple-trait linearization. `getAndRegisterParentTraits` collects
|
||||
Scala-signature traits, while Java registration only incorporates an already registered superclass trait, not
|
||||
implemented Scala interfaces. `CommonMicroblockClient` combines three trait parents, including the still-Scala
|
||||
`TMicroOcclusionClient`. Keep its declarations and bridges while extracting behavior; replacing them outright needs
|
||||
a separately characterized compiler/inheritance strategy. Extra Utilities, ForgeRelocationFMP and GuideNH also use
|
||||
these runtime interface types.
|
||||
- **External Scala traits remain supported.** ProjectRed registers `LightMicroblock` through
|
||||
`MicroblockGenerator.registerTrait`; keep its ScalaSignature ingestion, `$class` helper and generated dispatch.
|
||||
The Java path now supports its `@SideOnly` requirement, but retiring this external Scala path still needs a released
|
||||
|
||||
@@ -1035,3 +1035,26 @@ differences belong in the [divergence ledger](../../JAVA_MIGRATION_DIVERGENCES.m
|
||||
zero failures/errors/skips. All five packaged `@Mod` versions, the forced
|
||||
Scala-compilation guard and dev config remain correct. Sources stay at 214 Java files and 9 Scala files / 1,188
|
||||
nonblank Scala lines. Next: `microblock/MicroblockTraits.scala`, characterized before conversion.
|
||||
|
||||
### 2026-09-03 — Common microblock trait implementation
|
||||
|
||||
- Committed seven JVM and two Forge characterization tests first as `d6eb56b`. A frozen Scala 2.11.5 concrete
|
||||
`CommonMicroblockClient`, compiled under Java 8 against the unchanged jar, exercises all three trait helper bridges.
|
||||
Tests pin initialization, signed shape/slot handling and virtual shift operands, fresh immutable partial-box lists
|
||||
with shared bounds, dynamic class/material lookup, render-pass gating, common cuboid face masks and particle callback
|
||||
evaluation order. Forge verifies generated common parts and the original `NoSuchMethodError` when the missing-material
|
||||
client icon fallback reaches server-stripped `Block.getIcon`; the test does not turn that existing limitation into a fix.
|
||||
- Moved eight implementation methods to package-private `MicroblockTraitLogic.java`. Particle callbacks were already
|
||||
Java delegates. Retained the three Scala trait declarations, exact inheritance/signature metadata and `$class`
|
||||
bridges: Scala parent collection does not recognize Java interfaces as Scala traits, and Java registration does not
|
||||
incorporate implemented Scala interfaces into linearization. Both prior Java-mixin prerequisites remain useful,
|
||||
but are insufficient to remove this multiple-inheritance shell without another compiler behavior target.
|
||||
- Saved the reference jar, source, reports and generated dumps under ignored `run/migration-microblock-traits-reference/`.
|
||||
The clean comparison preserves all 437 original class/member APIs, all 17 ScalaSignature payloads and 3,674 non-target
|
||||
method bodies; only the new helper raises the class inventory to 438. All 116 generated dump names/hashes are exact,
|
||||
including external Scala and pass-through fixtures. No new effective divergence is introduced.
|
||||
- Formatting, checkstyle, build and Forge pass both normally and after stopping Gradle for a clean rebuild:
|
||||
340 JVM / 213 Forge tests, zero failures/errors/skips. The forced Scala-compilation guard and all five packaged
|
||||
`@Mod` versions remain verified. Sources total 215 Java files and 9 Scala files / 1,170 nonblank Scala lines.
|
||||
Next: `microblock/FaceMicroblockTraits.scala` implementation, with characterization before conversion. GPU rendering
|
||||
and full client selection remain on the manual checklist.
|
||||
@@ -0,0 +1,68 @@
|
||||
package codechicken.microblock;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.util.IIcon;
|
||||
|
||||
import codechicken.lib.vec.Cuboid6;
|
||||
import codechicken.lib.vec.Vector3;
|
||||
import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial;
|
||||
import scala.Predef$;
|
||||
import scala.collection.JavaConversions;
|
||||
import scala.collection.Seq;
|
||||
import scala.collection.Seq$;
|
||||
|
||||
/** Implementation behind the Scala trait declarations needed by inherited and external mixins. */
|
||||
final class MicroblockTraitLogic {
|
||||
|
||||
private MicroblockTraitLogic() {}
|
||||
|
||||
static IIcon getBrokenIcon(MicroblockClient part, int side) {
|
||||
IMicroMaterial material = ((Microblock) part).getIMaterial();
|
||||
return material == null ? Blocks.stone.getIcon(0, 0) : material.getBreakingIcon(side);
|
||||
}
|
||||
|
||||
static boolean renderStatic(MicroblockClient part, Vector3 pos, int pass) {
|
||||
if (((Microblock) part).getIMaterial().canRenderInPass(pass)) {
|
||||
part.render(pos, pass);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Cuboid6 getRenderBounds(MicroblockClient part) {
|
||||
return part.getBounds();
|
||||
}
|
||||
|
||||
static void render(CommonMicroblockClient part, Vector3 pos, int pass) {
|
||||
if (pass < 0) {
|
||||
MicroblockRender.renderCuboid(pos, ((Microblock) part).getIMaterial(), pass, part.getBounds(), 0);
|
||||
} else {
|
||||
MicroblockRender.renderCuboid(
|
||||
pos,
|
||||
((Microblock) part).getIMaterial(),
|
||||
pass,
|
||||
part.renderBounds(),
|
||||
part.renderMask());
|
||||
}
|
||||
}
|
||||
|
||||
static int getSlot(CommonMicroblock part) {
|
||||
return ((Microblock) part).getShape();
|
||||
}
|
||||
|
||||
static int getSlotMask(CommonMicroblock part) {
|
||||
return 1 << part.getSlot();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static List<Cuboid6> getPartialOcclusionBoxes(CommonMicroblock part) {
|
||||
return JavaConversions.seqAsJavaList(
|
||||
(Seq<Cuboid6>) Seq$.MODULE$.apply(Predef$.MODULE$.wrapRefArray(new Cuboid6[] { part.getBounds() })));
|
||||
}
|
||||
|
||||
static int itemClassID(CommonMicroblock part) {
|
||||
return part.microClass().getClassId();
|
||||
}
|
||||
}
|
||||
@@ -8,18 +8,14 @@ import codechicken.multipart.{
|
||||
TSlottedPart
|
||||
}
|
||||
import net.minecraft.client.particle.EffectRenderer
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
// Keep Scala inheritance metadata and helper bridges while derived and external mixins use Scala registration.
|
||||
trait MicroblockClient
|
||||
extends Microblock
|
||||
with TIconHitEffects
|
||||
with IMicroMaterialRender {
|
||||
def getBrokenIcon(side: Int) = getIMaterial match {
|
||||
case null => Blocks.stone.getIcon(0, 0)
|
||||
case mat => mat.getBreakingIcon(side)
|
||||
}
|
||||
def getBrokenIcon(side: Int) = MicroblockTraitLogic.getBrokenIcon(this, side)
|
||||
|
||||
// TIconHitEffects is a Java interface, so these must be declared explicitly or TMultiPart's empty versions win.
|
||||
override def addHitEffects(
|
||||
@@ -30,35 +26,20 @@ trait MicroblockClient
|
||||
override def addDestroyEffects(effectRenderer: EffectRenderer) =
|
||||
IconHitEffects.addDestroyEffects(this, effectRenderer)
|
||||
|
||||
override def renderStatic(pos: Vector3, pass: Int) = {
|
||||
if (getIMaterial.canRenderInPass(pass)) {
|
||||
render(pos, pass)
|
||||
true
|
||||
} else
|
||||
false
|
||||
}
|
||||
override def renderStatic(pos: Vector3, pass: Int) =
|
||||
MicroblockTraitLogic.renderStatic(this, pos, pass)
|
||||
|
||||
def render(pos: Vector3, pass: Int)
|
||||
|
||||
override def getRenderBounds = getBounds
|
||||
override def getRenderBounds = MicroblockTraitLogic.getRenderBounds(this)
|
||||
}
|
||||
|
||||
trait CommonMicroblockClient
|
||||
extends CommonMicroblock
|
||||
with MicroblockClient
|
||||
with TMicroOcclusionClient {
|
||||
def render(pos: Vector3, pass: Int) {
|
||||
if (pass < 0)
|
||||
MicroblockRender.renderCuboid(pos, getIMaterial, pass, getBounds, 0)
|
||||
else
|
||||
MicroblockRender.renderCuboid(
|
||||
pos,
|
||||
getIMaterial,
|
||||
pass,
|
||||
renderBounds,
|
||||
renderMask
|
||||
)
|
||||
}
|
||||
def render(pos: Vector3, pass: Int) =
|
||||
MicroblockTraitLogic.render(this, pos, pass)
|
||||
}
|
||||
|
||||
trait CommonMicroblock
|
||||
@@ -68,9 +49,10 @@ trait CommonMicroblock
|
||||
with TSlottedPart {
|
||||
def microClass: CommonMicroClass
|
||||
|
||||
def getSlot = getShape
|
||||
def getSlotMask = 1 << getSlot
|
||||
def getPartialOcclusionBoxes = Seq(getBounds)
|
||||
def getSlot = MicroblockTraitLogic.getSlot(this)
|
||||
def getSlotMask = MicroblockTraitLogic.getSlotMask(this)
|
||||
def getPartialOcclusionBoxes =
|
||||
MicroblockTraitLogic.getPartialOcclusionBoxes(this)
|
||||
|
||||
override def itemClassID = microClass.getClassId
|
||||
override def itemClassID = MicroblockTraitLogic.itemClassID(this)
|
||||
}
|
||||
Reference in new issue
Block a user