From 82db5b7ac7b29db51e9e0bb4d7ec9cabae3a7622 Mon Sep 17 00:00:00 2001 From: TheFruxz Date: Sun, 14 Aug 2022 14:52:37 +0200 Subject: [PATCH] feature: upgrade unfold to new context based structure --- MoltenKT-Core/build.gradle.kts | 1 + .../kotlin/de/moltenKt/paper/app/MoltenApp.kt | 27 ++++ .../app/interchange/MoltenKtInterchange.kt | 16 +-- .../moltenKt/paper/extension/paper/Block.kt | 13 +- .../de/moltenKt/unfold/MoltenContext.kt | 12 -- .../main/kotlin/de/moltenKt/unfold/Unfold.kt | 128 ++++++------------ .../de/moltenKt/unfold/extension/Adventure.kt | 7 + build.gradle.kts | 1 + 8 files changed, 99 insertions(+), 106 deletions(-) delete mode 100644 MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/MoltenContext.kt diff --git a/MoltenKT-Core/build.gradle.kts b/MoltenKT-Core/build.gradle.kts index 0e2e9e5185..e26a3f8a97 100644 --- a/MoltenKT-Core/build.gradle.kts +++ b/MoltenKT-Core/build.gradle.kts @@ -91,6 +91,7 @@ tasks { kotlinOptions.freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi" kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.io.path.ExperimentalPathApi" kotlinOptions.freeCompilerArgs += "-opt-in=kotlinx.serialization.ExperimentalSerializationApi" + kotlinOptions.freeCompilerArgs += "-Xcontext-receivers" } } diff --git a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/MoltenApp.kt b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/MoltenApp.kt index 20b24183aa..5875e78e6e 100644 --- a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/MoltenApp.kt +++ b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/MoltenApp.kt @@ -27,8 +27,10 @@ import de.moltenKt.paper.app.interchange.DebugModeInterchange import de.moltenKt.paper.app.interchange.MoltenKtInterchange import de.moltenKt.paper.app.interchange.PlaygroundInterchange import de.moltenKt.paper.extension.debugLog +import de.moltenKt.paper.extension.display.message import de.moltenKt.paper.extension.display.notification import de.moltenKt.paper.extension.mainLog +import de.moltenKt.paper.extension.objectBound.buildAndRegisterSandBox import de.moltenKt.paper.mojang.MojangProfile import de.moltenKt.paper.mojang.MojangProfileCape import de.moltenKt.paper.mojang.MojangProfileRaw @@ -70,12 +72,17 @@ import de.moltenKt.paper.tool.position.relative.LinearShape import de.moltenKt.paper.tool.position.relative.PyramidalShape import de.moltenKt.paper.tool.position.relative.Shape import de.moltenKt.paper.tool.position.relative.SphereShape +import de.moltenKt.unfold.buildComponent +import de.moltenKt.unfold.extension.asComponent +import de.moltenKt.unfold.extension.asStyledComponent import de.moltenKt.unfold.text +import de.moltenKt.unfold.unaryPlus import kotlinx.coroutines.cancel import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.runBlocking import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass +import net.kyori.adventure.text.event.ClickEvent import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.Location import org.bukkit.NamespacedKey @@ -229,6 +236,26 @@ class MoltenApp : App() { add(AppComponent()) + buildAndRegisterSandBox(this, "demo") { + + buildComponent { + + + "Hello!" + + + text(" This is") { + + " my Test" + } + + + text(" Word!") { + color(NamedTextColor.RED) + hoverEvent("Hey Hover!".asStyledComponent) + + ClickEvent.suggestCommand("DID IT!") + } + + }.message().broadcastPlayers() + + } + } override fun bye() { diff --git a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/interchange/MoltenKtInterchange.kt b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/interchange/MoltenKtInterchange.kt index ff90a3e503..aa97e592e4 100644 --- a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/interchange/MoltenKtInterchange.kt +++ b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/app/interchange/MoltenKtInterchange.kt @@ -8,8 +8,9 @@ import de.moltenKt.paper.structure.command.structured.StructuredInterchange import de.moltenKt.paper.structure.command.completion.buildInterchangeStructure import de.moltenKt.paper.tool.display.message.Transmission.Level.GENERAL import de.moltenKt.paper.tool.display.message.Transmission.Level.INFO -import de.moltenKt.unfold.newline import de.moltenKt.unfold.text +import de.moltenKt.unfold.unaryPlus +import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.format.Style.style import net.kyori.adventure.text.format.TextDecoration.BOLD @@ -19,24 +20,23 @@ internal class MoltenKtInterchange : StructuredInterchange("moltenkt", protected concludedExecution { text { - - text("MoltenKT") { + + text("MoltenKT") { style(style(NamedTextColor.GOLD, BOLD)) } - text(" was developed by ") { + + text(" was developed by ") { color(NamedTextColor.GRAY) } - text("TheFruxz") { + + text("TheFruxz") { color(NamedTextColor.YELLOW) } - text(", and other contributors of the repository: ") { + + text(", and other contributors of the repository: ") { color(NamedTextColor.GRAY) } - text(vendor.description.website ?: "FEHLER") { + + text(vendor.description.website ?: "FEHLER") { style(style(NamedTextColor.GOLD, BOLD)) } - newline() + + Component.newline() }.notification(INFO, executor).display() diff --git a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/extension/paper/Block.kt b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/extension/paper/Block.kt index 5a60055dc2..235361d9bf 100644 --- a/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/extension/paper/Block.kt +++ b/MoltenKT-Paper/src/main/kotlin/de/moltenKt/paper/extension/paper/Block.kt @@ -1,20 +1,21 @@ package de.moltenKt.paper.extension.paper -import de.moltenKt.paper.extension.tasky.doSync import de.moltenKt.paper.tool.annotation.RequiresSync import org.bukkit.Material import org.bukkit.Material.AIR -import org.bukkit.Material.TNT import org.bukkit.block.Block import org.bukkit.block.BlockState +import org.bukkit.block.Chest import org.bukkit.block.Container import org.bukkit.block.Sign import org.bukkit.entity.EntityType import org.bukkit.entity.FallingBlock import org.bukkit.entity.TNTPrimed -import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason import org.bukkit.inventory.Inventory +val Block.sign: Sign + get() = this.state as Sign + /** * This function casts a [BlockState] to the correct, * editable block state. @@ -24,6 +25,12 @@ import org.bukkit.inventory.Inventory val BlockState.sign: Sign get() = this as Sign +val Block.chest: Chest + get() = this.state as Chest + +val BlockState.chest: Chest + get() = this as Chest + /** * This function takes the sign's state and applies the * [builder] process to it. diff --git a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/MoltenContext.kt b/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/MoltenContext.kt deleted file mode 100644 index 2a0b31f2ef..0000000000 --- a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/MoltenContext.kt +++ /dev/null @@ -1,12 +0,0 @@ -package de.moltenKt.unfold - -public interface MoltenContext { - - public companion object { - - @JvmStatic - public fun contextOf(): MoltenContext = object : MoltenContext { } - - } - -} \ No newline at end of file diff --git a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/Unfold.kt b/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/Unfold.kt index 3c4825ae57..d1a880fc64 100644 --- a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/Unfold.kt +++ b/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/Unfold.kt @@ -1,83 +1,45 @@ -@file:Suppress("unused") // TODO use kotlin context API to avoid 'useless' seeming object extensions - -package de.moltenKt.unfold - -import de.moltenKt.unfold.extension.asStyledComponent -import io.ktor.http.* -import net.kyori.adventure.text.Component -import net.kyori.adventure.text.ComponentLike -import net.kyori.adventure.text.TextComponent -import net.kyori.adventure.text.event.ClickEvent -import net.kyori.adventure.text.event.HoverEventSource -import java.io.File -import java.net.URL -import java.nio.file.Path - -fun text(build: TextComponent.Builder.() -> Unit) = - Component.text().apply(build).build() - -fun text(componentContent: String) = - componentContent.asStyledComponent - -fun spaceText() = Component.space() - -fun emptyText() = Component.empty() - -fun newline() = Component.newline() - -fun MoltenContext>.text(componentContent: String) = - text { text(componentContent) } - -fun MoltenContext>.space() = - text { text(" ") } - -fun MoltenContext>.empty() = - text { text("") } - -fun MoltenContext>.newline() = - text { text("\n") } - -operator fun TextComponent.Builder.plus(component: ComponentLike) = - append(component.asComponent()) - -fun TextComponent.Builder.text(componentContent: String) = - this + componentContent.asStyledComponent - -fun TextComponent.Builder.text(component: TextComponent) = - this + component - -fun TextComponent.Builder.text(componentContent: String, modify: TextComponent.Builder.() -> Unit) = - this.append(componentContent.asStyledComponent.toBuilder().apply(modify).build()) - -fun TextComponent.Builder.text(component: TextComponent, modify: TextComponent.Builder.() -> Unit) = - this.append(component.toBuilder().apply(modify).build()) - -fun TextComponent.Builder.hover(eventSource: MoltenContext>.() -> HoverEventSource<*>) = - hoverEvent(eventSource(MoltenContext.contextOf())) - -fun TextComponent.Builder.click(click: MoltenContext.() -> ClickEvent) = - clickEvent(click(MoltenContext.contextOf())) - -fun MoltenContext.url(url: String) = ClickEvent.openUrl(url) - -fun MoltenContext.url(url: URL) = ClickEvent.openUrl(url) - -fun MoltenContext.url(url: Url) = ClickEvent.openUrl(url.toString()) - -fun MoltenContext.file(file: String) = ClickEvent.openFile(file) - -fun MoltenContext.file(path: Path) = file("$path") - -fun MoltenContext.file(file: File) = file(file.toPath()) - -fun MoltenContext.run(command: String) = ClickEvent.runCommand(command) - -fun MoltenContext.suggest(command: String) = ClickEvent.suggestCommand(command) - -fun MoltenContext.toPage(page: Int) = ClickEvent.changePage(page) - -fun MoltenContext.toPage(page: String) = ClickEvent.changePage(page) - -fun MoltenContext.copy(text: String) = ClickEvent.copyToClipboard(text) - -fun MoltenContext.click(action: ClickEvent.Action, string: String) = ClickEvent.clickEvent(action, string) \ No newline at end of file +package de.moltenKt.unfold + +import de.moltenKt.core.extension.dump +import de.moltenKt.unfold.extension.asStyledComponent +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.ComponentLike +import net.kyori.adventure.text.TextComponent +import net.kyori.adventure.text.TextComponent.Builder +import net.kyori.adventure.text.event.ClickEvent +import net.kyori.adventure.text.event.HoverEventSource + +@Unfold fun buildComponent(base: TextComponent = Component.empty(), builder: Builder.() -> Unit): TextComponent = + base.toBuilder().apply(builder).build() + +context(Builder) +@Unfold operator fun String.unaryPlus(): Unit = + append(this.asStyledComponent).dump() + +context(Builder) +@Unfold operator fun ComponentLike.unaryPlus(): Builder = + append(this) + +context(Builder) +@Unfold operator fun > T.unaryPlus(): Builder = + append(this) + +context(Builder) +@Unfold operator fun ClickEvent.unaryPlus(): Builder = + clickEvent(this) + +@Unfold +fun text(content: String, builder: Builder.() -> Unit = { }) = content.asStyledComponent(builder) + +@Unfold +fun text(builder: Builder.() -> Unit) = text("", builder) + +@Unfold +fun TextComponent.hover(process: () -> HoverEventSource<*>) = this.hoverEvent(process()) + +@Unfold +fun Builder.hover(process: () -> HoverEventSource<*>) = this.hoverEvent(process()) + +@DslMarker +@PublishedApi +internal annotation class Unfold \ No newline at end of file diff --git a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/extension/Adventure.kt b/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/extension/Adventure.kt index 46093fec16..5dbbaec2e3 100644 --- a/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/extension/Adventure.kt +++ b/MoltenKT-Unfold/src/main/kotlin/de/moltenKt/unfold/extension/Adventure.kt @@ -3,6 +3,7 @@ package de.moltenKt.unfold.extension import net.kyori.adventure.text.Component import net.kyori.adventure.text.ComponentLike import net.kyori.adventure.text.TextComponent +import net.kyori.adventure.text.TextComponent.Builder import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.text.minimessage.MiniMessage import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer @@ -52,6 +53,9 @@ val ComponentLike.asString: String val String.asComponent: TextComponent get() = adventureSerializer.deserializeOr(this, Component.text("FAILED", NamedTextColor.RED))!! +fun String.asComponent(builder: Builder.() -> Unit) = + asComponent.toBuilder().apply(builder).build() + /** * This computational value converts this [String] into a [TextComponent] * list (every list entry is a line) by using the [LegacyComponentSerializer], @@ -98,6 +102,9 @@ val ComponentLike.asStyledString: String val String.asStyledComponent: TextComponent get() = Component.text().append(miniMessageSerializer.deserializeOr(this, Component.text("FAILED", NamedTextColor.RED))!!).build() +fun String.asStyledComponent(builder: TextComponent.Builder.() -> Unit) = + asStyledComponent.toBuilder().apply(builder).build() + /** * This computational value converts this [String] into a [TextComponent] * list (every entry represents a line) by using the [MiniMessage], provided by the diff --git a/build.gradle.kts b/build.gradle.kts index 871ae88153..d97d2bf81f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -19,6 +19,7 @@ allprojects { tasks.withType().configureEach { kotlinOptions.freeCompilerArgs += "-opt-in=kotlin.RequiresOptIn" + kotlinOptions.freeCompilerArgs += "-Xcontext-receivers" } }