Skip to content

Commit

Permalink
Merge pull request #64 from MineInAbyss/refactor
Browse files Browse the repository at this point in the history
Refactor & web console start
  • Loading branch information
0ffz authored Jan 28, 2022
2 parents 8e84554 + 0328ecb commit 73f5fe0
Show file tree
Hide file tree
Showing 124 changed files with 2,586 additions and 1,132 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/publish-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,23 @@ jobs:
run: gradle build publish -PmineinabyssMavenUsername=${{ secrets.MAVEN_PUBLISH_USERNAME }} -PmineinabyssMavenPassword=${{ secrets.MAVEN_PUBLISH_PASSWORD }}

- name: Generate Dokka
run: gradle dokkaHtmlMultiModule
# TODO figure out dokka for kotlin multiplatform
# run: gradle dokkaHtmlMultiModule
run: gradle geary-core:dokkaHtml

- name: Publish documentation to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build/dokka/htmlMultiModule
# publish_dir: ./build/dokka/htmlMultiModule
publish_dir: ./geary-core/build/dokka/html
force_orphan: true

- name: Get version from gradle
shell: bash
id: extract_version
run: |
version=`./gradlew :geary-platform-papermc:properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}'`
version=`./gradlew :geary-papermc-core:properties --no-daemon --console=plain -q | grep "^version:" | awk '{printf $2}'`
echo "::set-output name=version::$version"
- name: Create GitHub Release
Expand All @@ -51,4 +54,4 @@ jobs:
prerelease: false
automatic_release_tag: v${{ steps.extract_version.outputs.version }}
files: |
platforms/geary-platform-papermc/build/libs/*-all.jar
platforms/papermc/build/libs/*-all.jar
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ out
eclipse
*.ipr
*.iws
kotlin-js-store/
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# Geary
[![Java CI with Gradle](https://github.com/MineInAbyss/Geary/actions/workflows/gradle-ci.yml/badge.svg)](https://github.com/MineInAbyss/Geary/actions/workflows/gradle-ci.yml)
[![Package](https://img.shields.io/maven-metadata/v?metadataUrl=https://repo.mineinabyss.com/releases/com/mineinabyss/geary-platform-papermc/maven-metadata.xml)](https://repo.mineinabyss.com/#/releases/com/mineinabyss/geary-platform-papermc)
[![Package](https://img.shields.io/maven-metadata/v?metadataUrl=https://repo.mineinabyss.com/releases/com/mineinabyss/geary-papermc-core/maven-metadata.xml)](https://repo.mineinabyss.com/#/releases/com/mineinabyss/geary-papermc-core)
[![Wiki](https://img.shields.io/badge/-Project%20Wiki-blueviolet?logo=Wikipedia&labelColor=gray)](https://wiki.mineinabyss.com/geary)
[![Contribute](https://shields.io/badge/Contribute-e57be5?logo=github%20sponsors&style=flat&logoColor=white)](https://wiki.mineinabyss.com/contribute)
</div>
Expand Down Expand Up @@ -54,7 +54,7 @@ class Velocity(...) {
An entity to get us started:

```kotlin
Engine.entity {
entity {
setAll(Textures(...), Render(...), Velocity(...))
}
```
Expand Down Expand Up @@ -124,7 +124,7 @@ repositories {
dependencies {
compileOnly 'com.mineinabyss:geary:<version>'
// Use the line below if you want to use Geary for your PaperMC plugin
compileOnly 'com.mineinabyss:geary-platform-papermc:<version>'
compileOnly 'com.mineinabyss:geary-papermc-core:<version>'
}
```

Expand Down
17 changes: 3 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
import Com_mineinabyss_conventions_platform_gradle.Deps

plugins {
java
kotlin("jvm")
id("org.jetbrains.dokka")
id("com.mineinabyss.conventions.platform")
}

repositories {
mavenCentral()
}

dependencies {
compileOnly(Deps.kotlin.stdlib)
// kotlin("multiplatform")
// id("org.jetbrains.dokka")
}

tasks {
build {
dependsOn(project(":geary-platform-papermc").tasks.build)
dependsOn(project(":geary-papermc").tasks.build)
}
}
14 changes: 14 additions & 0 deletions geary-addon/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("geary.kotlin-conventions")
kotlin("plugin.serialization")
id("com.mineinabyss.conventions.publication")
id("com.mineinabyss.conventions.testing")
}

dependencies {
// implementation(libs.kotlinx.coroutines)
implementation(libs.reflections)
implementation(libs.kotlin.reflect)
compileOnly(project(":geary-core"))
compileOnly(project(":geary-prefabs"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.mineinabyss.geary.api.addon

import com.mineinabyss.geary.ecs.api.entities.GearyEntity
import com.mineinabyss.geary.ecs.serialization.Formats
import com.mineinabyss.geary.prefabs.events.PrefabLoaded
import com.mineinabyss.idofront.messaging.logInfo
import org.koin.core.component.KoinComponent

public abstract class AbstractAddonManager : KoinComponent {
internal val loadingPrefabs = mutableListOf<GearyEntity>()
private val actions = sortedMapOf<GearyLoadPhase, MutableList<() -> Unit>>()

public fun add(phase: GearyLoadPhase, action: () -> Unit) {
if (actions.isEmpty()) scheduleLoadTasks()

actions.getOrPut(phase) { mutableListOf() }.add(action)
}

protected abstract fun scheduleLoadTasks()

private fun MutableList<() -> Unit>.runAll() = forEach { it() }

/** Tasks to run before all other addon startup tasks execute. */
public fun load() {
logInfo("Registering Serializers")
actions[GearyLoadPhase.REGISTER_SERIALIZERS]?.runAll()
Formats.createFormats()
logInfo("Loading prefabs")
actions[GearyLoadPhase.LOAD_PREFABS]?.runAll()
loadingPrefabs.forEach {
it.callEvent(PrefabLoaded())
}
loadingPrefabs.clear()
}

/** Run addons startup tasks. */
public fun enableAddons() {
logInfo("Running final startup tasks")
actions[GearyLoadPhase.ENABLE]?.runAll()
actions.clear()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.mineinabyss.geary.api.addon

public interface AbstractAddonManagerScope {
public val addonManager: AbstractAddonManager
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.mineinabyss.geary.api.addon

import com.mineinabyss.geary.ecs.api.GearyComponent
import com.mineinabyss.geary.ecs.api.engine.EngineScope
import com.mineinabyss.geary.ecs.api.systems.GearySystem
import com.mineinabyss.geary.ecs.serialization.Formats
import com.mineinabyss.geary.prefabs.PrefabManagerScope
import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.PolymorphicModuleBuilder
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.SerializersModuleBuilder
import kotlinx.serialization.modules.polymorphic
import java.io.File
import kotlin.reflect.KClass

@DslMarker
@Retention(AnnotationRetention.SOURCE)
public annotation class GearyAddonDSL

/**
* The entry point for other plugins to hook into Geary. Allows registering serializable components, systems, actions,
* and more.
*/
@GearyAddonDSL
public abstract class AbstractGearyAddon : EngineScope, AbstractAddonManagerScope, PrefabManagerScope {
public abstract val namespace: String

/** Adds a [SerializersModule] for polymorphic serialization of [GearyComponent]s within the ECS. */
public inline fun components(crossinline init: PolymorphicModuleBuilder<GearyComponent>.() -> Unit) {
serializers { polymorphic(GearyComponent::class) { init() } }
}

/** Registers a [system]. */
public fun system(system: GearySystem) {
engine.addSystem(system)
}

/** Registers a list of [systems]. */
public fun systems(vararg systems: GearySystem) {
systems.forEach { system(it) }
}

/**
* Adds a serializable component and registers it with Geary to allow finding the appropriate class via
* component serial name.
*/
public inline fun <reified T : GearyComponent> PolymorphicModuleBuilder<T>.component(serializer: KSerializer<T>) {
component(T::class, serializer)
}

/**
* Adds a serializable component and registers it with Geary to allow finding the appropriate class via
* component serial name.
*/
public fun <T : GearyComponent> PolymorphicModuleBuilder<T>.component(
kClass: KClass<T>,
serializer: KSerializer<T>?
): Boolean {
val serialName = serializer?.descriptor?.serialName ?: return false
if (!Formats.isRegistered(serialName)) {
Formats.registerSerialName(serialName, kClass)
subclass(kClass, serializer)
return true
}
return false
}

/** Adds a [SerializersModule] to be used for polymorphic serialization within the ECS. */
public inline fun serializers(init: SerializersModuleBuilder.() -> Unit) {
Formats.addSerializerModule(namespace, SerializersModule { init() })
}

/** Loads prefab entities from all files inside a [directory][from], into a given [namespace] */
public fun loadPrefabs(
from: File,
namespace: String = this.namespace
) {
startup {
GearyLoadPhase.LOAD_PREFABS {
// Start with the innermost directories
val dirs = from.walkBottomUp().filter { it.isDirectory }
val files = dirs.flatMap { dir -> dir.walk().maxDepth(1).filter { it.isFile } }
files.forEach { file ->
val entity = prefabManager.loadFromFile(namespace, file) ?: return@forEach
addonManager.loadingPrefabs += entity
}
}
}
}

public inner class PhaseCreator {
public operator fun GearyLoadPhase.invoke(run: () -> Unit) {
addonManager.add(this, run)
}
}

/**
* Allows defining actions that should run at a specific phase during startup
*
* Within its context, invoke a [GearyLoadPhase] to run something during it, ex:
*
* ```
* GearyLoadPhase.ENABLE {
* // run code here
* }
* ```
*/
public inline fun startup(run: PhaseCreator.() -> Unit) {
PhaseCreator().apply(run)
}
}

/** The polymorphic builder scope that allows registering subclasses. */
public typealias SerializerRegistry<T> = PolymorphicModuleBuilder<T>.(kClass: KClass<T>, serializer: KSerializer<T>?) -> Boolean
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.mineinabyss.geary.minecraft.dsl
package com.mineinabyss.geary.api.addon

public enum class GearyLoadPhase {
REGISTER_SERIALIZERS,
Expand Down
11 changes: 11 additions & 0 deletions geary-autoscan/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
plugins {
id("geary.kotlin-conventions")
// kotlin("plugin.serialization")
// id("com.mineinabyss.conventions.publication")
// id("com.mineinabyss.conventions.testing")
}

dependencies {
api(libs.reflections)
compileOnly(project(":geary-core"))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.mineinabyss.geary.autoscan

import com.mineinabyss.idofront.messaging.logWarn
import org.reflections.Reflections
import org.reflections.scanners.SubTypesScanner
import org.reflections.util.ClasspathHelper
import org.reflections.util.ConfigurationBuilder
import org.reflections.util.FilterBuilder
import kotlin.reflect.KClass

/**
* DSL for configuring automatic scanning of classes to be registered into Geary's [SerializersModule].
*
* A [path] to limit search to may be specified. Specific packages can also be excluded with [excludePath].
* Annotate a class with [ExcludeAutoScan] to exclude it from automatically being registered.
*
* _Note that if the plugin is loaded using a custom classloading solution, autoscan may not work._
*
* @property path Optional path to restrict what packages are scanned.
* @property excluded Excluded paths under [path].
*/
public class AutoScanner(private val classLoader: ClassLoader) {
public var path: String? = null
private val excluded = mutableListOf<String>()

/** Add a path to be excluded from the scanner. */
public fun excludePath(path: String) {
excluded += path
}

/** Gets a reflections object under [path] */
public fun getReflections(): Reflections? {
// cache the object we get because it takes considerable amount of time to get
val cacheKey = CacheKey(classLoader, path, excluded)
reflectionsCache[cacheKey]?.let { return it }

val reflections = Reflections(
ConfigurationBuilder()
.addClassLoader(classLoader)
.addUrls(ClasspathHelper.forClassLoader(classLoader))
.addScanners(SubTypesScanner())
.filterInputsBy(FilterBuilder().apply {
if (path != null) includePackage(path)
excluded.forEach { excludePackage(it) }
})
)

reflectionsCache[cacheKey] = reflections

// Check if the store is empty. Since we only use a single SubTypesScanner, if this is empty
// then the path passed in returned 0 matches.
if (reflections.store.keySet().isEmpty()) {
logWarn("Autoscanner failed to find classes for ${classLoader}${if (path == null) "" else " in package ${path}}"}.")
return null
}
return reflections
}

public inline fun <reified T : Any> getSubclassesOf(): List<KClass<out T>> {
return getReflections()?.getSubTypesOf(T::class.java)?.map { it.kotlin } ?: listOf()
}


private companion object {
private data class CacheKey(val classLoader: ClassLoader, val path: String?, val excluded: Collection<String>)

private val reflectionsCache = mutableMapOf<CacheKey, Reflections>()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.mineinabyss.geary.autoscan

import com.mineinabyss.geary.ecs.api.systems.GearyListener
import com.mineinabyss.geary.ecs.api.systems.GearySystem
import com.mineinabyss.geary.ecs.api.systems.TickingSystem
import com.mineinabyss.geary.ecs.query.Query

/**
* Excludes this class from having its serializer automatically registered for component serialization
* with the AutoScanner.
*/
public annotation class ExcludeAutoScan

/**
* Indicates this [GearySystem], such as [TickingSystem], [GearyListener], or [Query] be registered automatically
* on startup by the AutoScanner.
*/
public annotation class AutoScan
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@ repositories {
mavenCentral()
}

object GearyDeps {
val bimap = "com.uchuhimo:kotlinx-bimap:1.2"
val bitvector = "net.onedaybeard.bitvector:bitvector-jvm:0.1.4"
val fastutil = "it.unimi.dsi:fastutil:8.2.2" //Version on minecraft server
val reflections = "org.reflections:reflections:0.9.12"
val plugman = "com.rylinaux:PlugMan:2.2.5"
}

dependencies {
// MineInAbyss platform
compileOnly(Deps.kotlin.stdlib)
Expand Down
Loading

0 comments on commit 73f5fe0

Please sign in to comment.