DevNatan / inventory-framework

Minecraft Inventory API framework
MIT License
116 stars 21 forks source link

InventoryFrameworkException: Missing layout character on View that has a layout #671

Open 4Ply opened 1 week ago

4Ply commented 1 week ago

Is there an existing issue for this?

🐛 Describe the bug

Attempting to render a View with a layout throws the following error:

[23:40:32 ERROR]: [Citadel] [ACF] me.devnatan.inventoryframework.InventoryFrameworkException: Missing layout character: #
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.DefaultPublicSlotComponentRenderer.lambda$layoutSlot$3(DefaultPublicSlotComponentRenderer.java:190)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/java.util.Optional.orElseThrow(Optional.java:403)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.DefaultPublicSlotComponentRenderer.layoutSlot(DefaultPublicSlotComponentRenderer.java:190)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.DefaultPublicSlotComponentRenderer.layoutSlot(DefaultPublicSlotComponentRenderer.java:15)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.PlatformRenderContext.layoutSlot(PlatformRenderContext.java:49)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.inventory.DeckInventoryView.onFirstRender(DeckInventoryView.kt:24)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.inventory.DeckInventoryView.onFirstRender(DeckInventoryView.kt:13)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.ContextPlatformRenderHandlerCallInterceptor.intercept(ContextPlatformRenderHandlerCallInterceptor.java:13)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.ContextPlatformRenderHandlerCallInterceptor.intercept(ContextPlatformRenderHandlerCallInterceptor.java:8)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.loop(PipelineContext.java:43)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.proceed(PipelineContext.java:53)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.execute(PipelineContext.java:59)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.Pipeline.execute(Pipeline.java:128)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.PlatformRenderContext.simulateRender(PlatformRenderContext.java:207)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.PlatformView.renderContext(PlatformView.java:301)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.ContextOpenInterceptor.finishOpen(ContextOpenInterceptor.java:61)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.ContextOpenInterceptor.intercept(ContextOpenInterceptor.java:35)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.ContextOpenInterceptor.intercept(ContextOpenInterceptor.java:15)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.loop(PipelineContext.java:43)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.proceed(PipelineContext.java:53)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.PipelineContext.execute(PipelineContext.java:59)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.pipeline.Pipeline.execute(Pipeline.java:128)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.context.OpenContext.simulateOpen(OpenContext.java:187)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.PlatformView.open(PlatformView.java:82)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.IFViewFrame.internalOpen(IFViewFrame.java:156)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.ViewFrame.open(ViewFrame.java:111)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.ViewFrame.open(ViewFrame.java:73)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//me.devnatan.inventoryframework.ViewFrame.open(ViewFrame.java:61)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.commands.ManageDeckCommand.showDeckEditor(ManageDeckCommand.kt:20)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/java.lang.reflect.Method.invoke(Method.java:568)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.acf.RegisteredCommand.invoke(RegisteredCommand.java:152)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.acf.BaseCommand.executeCommand(BaseCommand.java:578)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.acf.BaseCommand.execute(BaseCommand.java:513)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.acf.RootCommand.execute(RootCommand.java:99)
[23:40:32 ERROR]: [Citadel] [ACF]   at citadel-1.0-SNAPSHOT-all.jar//org.trackedout.citadel.acf.BukkitRootCommand.execute(BukkitRootCommand.java:84)
[23:40:32 ERROR]: [Citadel] [ACF]   at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:155)
[23:40:32 ERROR]: [Citadel] [ACF]   at org.bukkit.craftbukkit.v1_20_R1.CraftServer.dispatchCommand(CraftServer.java:987)
[23:40:32 ERROR]: [Citadel] [ACF]   at org.bukkit.craftbukkit.v1_20_R1.command.BukkitCommandWrapper.run(BukkitCommandWrapper.java:64)
[23:40:32 ERROR]: [Citadel] [ACF]   at com.mojang.brigadier.CommandDispatcher.execute(CommandDispatcher.java:265)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.commands.CommandDispatcher.performCommand(CommandDispatcher.java:324)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.commands.CommandDispatcher.a(CommandDispatcher.java:308)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.network.PlayerConnection.a(PlayerConnection.java:2354)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.network.PlayerConnection.lambda$handleChatCommand$21(PlayerConnection.java:2314)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.util.thread.IAsyncTaskHandler.b(IAsyncTaskHandler.java:59)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.TickTask.run(TickTask.java:18)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.util.thread.IAsyncTaskHandler.d(IAsyncTaskHandler.java:153)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.util.thread.IAsyncTaskHandlerReentrant.d(IAsyncTaskHandlerReentrant.java:24)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.b(MinecraftServer.java:1338)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.d(MinecraftServer.java:197)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.util.thread.IAsyncTaskHandler.x(IAsyncTaskHandler.java:126)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.bg(MinecraftServer.java:1315)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.x(MinecraftServer.java:1308)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.util.thread.IAsyncTaskHandler.bp(IAsyncTaskHandler.java:114)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.a(MinecraftServer.java:1424)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:1170)
[23:40:32 ERROR]: [Citadel] [ACF]   at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:317)
[23:40:32 ERROR]: [Citadel] [ACF]   at java.base/java.lang.Thread.run(Thread.java:840)

✔️ Expected behavior

The inventory view should appear

👣 Steps to Reproduce

  1. inventory-framework-paper-3.1.0-rc-all.jar is in my paper server's plugins directory.
  2. build.gradle contains:
    compileOnly 'me.devnatan:inventory-framework-platform-bukkit:3.1.0-rc'
    runtimeOnly 'me.devnatan:inventory-framework-platform-bukkit:3.1.0-rc'

The View that fails (copied from https://github.com/DevNatan/inventory-framework/wiki/Code-Samples#Counter):

class DeckInventoryView: View() {
    private val counterState: MutableIntState = mutableState(0)

    override fun onInit(config: ViewConfigBuilder) {
        config.title("Counter")
            .cancelOnClick()
            .layout("  - # +  ") // note the layout is defined here, debugging shows that this is executed before onFirstRender is called (as expected)
    }

    override fun onFirstRender(render: RenderContext) {
        // Current count item
        render.layoutSlot('#') // <--- error thrown on this line
            .watch(counterState)
            .renderWith {
                ItemStack(
                    Material.GOLD_INGOT,
                    counterState[render]
                )
            }

        // Decrement button
        render.layoutSlot('-')
            .withItem(ItemStack(Material.ARROW))
            .onClick { stateValueHost: StateValueHost? -> counterState.decrement(stateValueHost!!) }

        // Increment button
        render.layoutSlot('+')
            .withItem(ItemStack(Material.ARROW))
            .onClick { stateValueHost: StateValueHost? -> counterState.increment(stateValueHost!!) }
    }
}

💻 Platform

⭐ Server Version

1.20.1

📚 Library Version

v3.1.0-rc

✍️ Additional context

It's not clear whether this MC version (1.20.1) is supported? Do I need to use an older version of IF?

https://github.com/DevNatan/inventory-framework/wiki#versions-compatibility

4Ply commented 1 week ago

Stepping through this with a debugger indicates that render.config.layout_field has the expected layout

image

Yet the underlying slots are empty when the lookup is attempted:

image