mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 22:58:29 +08:00
Created gradle plugin with workaround for https://youtrack.jetbrains.com/issue/KT-42923.
This commit is contained in:
parent
44d5918a1e
commit
0983be905d
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ build
|
||||
# Misc.
|
||||
.DS_Store
|
||||
*.log
|
||||
karma.config.generated.js
|
||||
|
17
buildSrc/build.gradle.kts
Normal file
17
buildSrc/build.gradle.kts
Normal file
@ -0,0 +1,17 @@
|
||||
plugins {
|
||||
kotlin("jvm") version "1.4.20-RC"
|
||||
`java-gradle-plugin`
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
create("pwPlugins") {
|
||||
id = "world.phantasmal.gradle.js"
|
||||
implementationClass = "world.phantasmal.gradle.PwJsPlugin"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package world.phantasmal.gradle
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
/**
|
||||
* This task generates a Karma configuration in karma.config.d that ensures Karma serves files from
|
||||
* the resources directories.
|
||||
*/
|
||||
open class KarmaResourcesTask : DefaultTask() {
|
||||
private val outputFile = project.file("karma.config.d/karma.config.generated.js")
|
||||
|
||||
init {
|
||||
outputs.file(outputFile)
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun generateKarmaConfig() {
|
||||
outputFile.outputStream().use { stream ->
|
||||
val writer = stream.writer()
|
||||
val path = project.projectDir.absolutePath.replace("\\", "\\\\")
|
||||
writer.write("const PROJECT_PATH = '$path';\n\n")
|
||||
writer.flush()
|
||||
|
||||
KarmaResourcesTask::class.java.getResourceAsStream("/karmaConfig.js").copyTo(stream)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package world.phantasmal.gradle
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
|
||||
/**
|
||||
* This plugin adds a karmaResources task as dependency to the browserTest and jsBrowserTest tasks
|
||||
* as a workaround for https://youtrack.jetbrains.com/issue/KT-42923.
|
||||
*/
|
||||
class PwJsPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) {
|
||||
val karmaResources = target.tasks.create("karmaResources", KarmaResourcesTask::class.java)
|
||||
|
||||
target.tasks.configureEach { task ->
|
||||
if (task.name == "browserTest" || task.name == "jsBrowserTest") {
|
||||
task.dependsOn(karmaResources)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
buildSrc/src/main/resources/karmaConfig.js
Normal file
26
buildSrc/src/main/resources/karmaConfig.js
Normal file
@ -0,0 +1,26 @@
|
||||
config.middleware = config.middleware || [];
|
||||
config.middleware.push('resource-loader');
|
||||
|
||||
function ResourceLoaderMiddleware() {
|
||||
const fs = require('fs');
|
||||
|
||||
return function (request, response, next) {
|
||||
try {
|
||||
const content = fs.readFileSync(PROJECT_PATH + '/build/processedResources/js/test' + request.originalUrl);
|
||||
response.writeHead(200);
|
||||
response.end(content);
|
||||
} catch (ignored) {
|
||||
try {
|
||||
const content = fs.readFileSync(PROJECT_PATH + '/build/processedResources/js/main' + request.originalUrl);
|
||||
response.writeHead(200);
|
||||
response.end(content);
|
||||
} catch (ignored) {
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
config.plugins.push({
|
||||
'middleware:resource-loader': ['factory', ResourceLoaderMiddleware]
|
||||
});
|
@ -5,6 +5,7 @@ import java.io.PrintWriter
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("world.phantasmal.gradle.js")
|
||||
}
|
||||
|
||||
buildscript {
|
||||
|
@ -1,6 +1,7 @@
|
||||
plugins {
|
||||
kotlin("js")
|
||||
kotlin("plugin.serialization")
|
||||
id("world.phantasmal.gradle.js")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
@ -49,11 +49,6 @@ private fun init(): Disposable {
|
||||
}
|
||||
disposer.add(disposable { httpClient.cancel() })
|
||||
|
||||
val pathname = window.location.pathname
|
||||
val assetBasePath = window.location.origin +
|
||||
(if (pathname.lastOrNull() == '/') pathname.dropLast(1) else pathname) +
|
||||
"/assets"
|
||||
|
||||
val scope = CoroutineScope(SupervisorJob())
|
||||
disposer.add(disposable { scope.cancel() })
|
||||
|
||||
@ -61,7 +56,7 @@ private fun init(): Disposable {
|
||||
Application(
|
||||
scope,
|
||||
rootElement,
|
||||
AssetLoader(assetBasePath, httpClient),
|
||||
AssetLoader(httpClient),
|
||||
disposer.add(HistoryApplicationUrl()),
|
||||
createEngine = { Engine(it) }
|
||||
)
|
||||
|
@ -4,11 +4,16 @@ import io.ktor.client.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import kotlinx.browser.window
|
||||
import org.khronos.webgl.ArrayBuffer
|
||||
|
||||
class AssetLoader(val basePath: String, val httpClient: HttpClient) {
|
||||
class AssetLoader(
|
||||
val httpClient: HttpClient,
|
||||
val origin: String = window.location.origin,
|
||||
val basePath: String = window.location.pathname.removeSuffix("/") + "/assets",
|
||||
) {
|
||||
suspend inline fun <reified T> load(path: String): T =
|
||||
httpClient.get("$basePath$path")
|
||||
httpClient.get("$origin$basePath$path")
|
||||
|
||||
suspend fun loadArrayBuffer(path: String): ArrayBuffer {
|
||||
val response = load<HttpResponse>(path)
|
||||
|
@ -20,7 +20,7 @@ abstract class Renderer(
|
||||
init {
|
||||
with(scene) {
|
||||
useRightHandedSystem = true
|
||||
clearColor = Color4(0.09, 0.09, 0.09, 1.0)
|
||||
clearColor = Color4.FromInts(0x18, 0x18, 0x18, 0xFF)
|
||||
}
|
||||
|
||||
light = HemisphericLight("Light", Vector3(-1.0, 1.0, 1.0), scene)
|
||||
|
@ -169,11 +169,13 @@ open external class ThinEngine {
|
||||
fun dispose()
|
||||
}
|
||||
|
||||
external class Engine(
|
||||
open external class Engine(
|
||||
canvasOrContext: HTMLCanvasElement?,
|
||||
antialias: Boolean = definedExternally,
|
||||
) : ThinEngine
|
||||
|
||||
external class NullEngine : Engine
|
||||
|
||||
external class Ray(origin: Vector3, direction: Vector3, length: Double = definedExternally) {
|
||||
var origin: Vector3
|
||||
var direction: Vector3
|
||||
|
@ -1,6 +1,6 @@
|
||||
package world.phantasmal.web.questEditor
|
||||
|
||||
import world.phantasmal.web.externals.babylon.Engine
|
||||
import world.phantasmal.web.externals.babylon.NullEngine
|
||||
import world.phantasmal.web.test.WebTestSuite
|
||||
import kotlin.test.Test
|
||||
|
||||
@ -8,7 +8,7 @@ class QuestEditorTests : WebTestSuite() {
|
||||
@Test
|
||||
fun initialization_and_shutdown_should_succeed_without_throwing() = test {
|
||||
val questEditor = disposer.add(
|
||||
QuestEditor(components.assetLoader, components.uiStore, createEngine = { Engine(it) })
|
||||
QuestEditor(components.assetLoader, components.uiStore, createEngine = { NullEngine() })
|
||||
)
|
||||
disposer.add(questEditor.initialize(scope))
|
||||
}
|
||||
|
@ -12,6 +12,19 @@ import world.phantasmal.web.test.createQuestNpcModel
|
||||
import kotlin.test.*
|
||||
|
||||
class QuestEditorToolbarControllerTests : WebTestSuite() {
|
||||
@Test
|
||||
fun can_create_a_new_quest() = asyncTest {
|
||||
val ctrl = disposer.add(QuestEditorToolbarController(
|
||||
components.questLoader,
|
||||
components.areaStore,
|
||||
components.questEditorStore,
|
||||
))
|
||||
|
||||
ctrl.createNewQuest(Episode.I)
|
||||
|
||||
assertNotNull(components.questEditorStore.currentQuest.value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun a_failure_is_exposed_when_openFiles_fails() = asyncTest {
|
||||
val ctrl = disposer.add(QuestEditorToolbarController(
|
||||
@ -56,7 +69,7 @@ class QuestEditorToolbarControllerTests : WebTestSuite() {
|
||||
|
||||
// Load quest.
|
||||
val npc = createQuestNpcModel(NpcType.Scientist, Episode.I)
|
||||
components.questEditorStore.setCurrentQuest(createQuestModel(npcs= listOf(npc)))
|
||||
components.questEditorStore.setCurrentQuest(createQuestModel(npcs = listOf(npc)))
|
||||
|
||||
assertEquals(nothingToUndo, ctrl.undoTooltip.value)
|
||||
assertFalse(ctrl.undoEnabled.value)
|
||||
|
@ -10,7 +10,7 @@ import world.phantasmal.testUtils.TestContext
|
||||
import world.phantasmal.web.core.loading.AssetLoader
|
||||
import world.phantasmal.web.core.stores.ApplicationUrl
|
||||
import world.phantasmal.web.core.stores.UiStore
|
||||
import world.phantasmal.web.externals.babylon.Engine
|
||||
import world.phantasmal.web.externals.babylon.NullEngine
|
||||
import world.phantasmal.web.externals.babylon.Scene
|
||||
import world.phantasmal.web.questEditor.loading.AreaAssetLoader
|
||||
import world.phantasmal.web.questEditor.loading.QuestLoader
|
||||
@ -39,11 +39,11 @@ class TestComponents(private val ctx: TestContext) {
|
||||
|
||||
// Babylon.js
|
||||
|
||||
var scene: Scene by default { Scene(Engine(null)) }
|
||||
var scene: Scene by default { Scene(NullEngine()) }
|
||||
|
||||
// Asset Loaders
|
||||
|
||||
var assetLoader: AssetLoader by default { AssetLoader(basePath = "", httpClient) }
|
||||
var assetLoader: AssetLoader by default { AssetLoader(httpClient, basePath = "/assets") }
|
||||
|
||||
var areaAssetLoader: AreaAssetLoader by default {
|
||||
AreaAssetLoader(ctx.scope, assetLoader, scene)
|
||||
|
Loading…
Reference in New Issue
Block a user