-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #64 from MineInAbyss/refactor
Refactor & web console start
- Loading branch information
Showing
124 changed files
with
2,586 additions
and
1,132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,4 @@ out | |
eclipse | ||
*.ipr | ||
*.iws | ||
kotlin-js-store/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")) | ||
} |
42 changes: 42 additions & 0 deletions
42
geary-addon/src/main/kotlin/com/mineinabyss/geary/api/addon/AbstractAddonManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} |
5 changes: 5 additions & 0 deletions
5
geary-addon/src/main/kotlin/com/mineinabyss/geary/api/addon/AbstractAddonManagerScope.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
114 changes: 114 additions & 0 deletions
114
geary-addon/src/main/kotlin/com/mineinabyss/geary/api/addon/AbstractGearyAddon.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
2 changes: 1 addition & 1 deletion
2
...yss/geary/minecraft/dsl/GearyLoadPhase.kt → ...inabyss/geary/api/addon/GearyLoadPhase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")) | ||
} |
69 changes: 69 additions & 0 deletions
69
geary-autoscan/src/main/kotlin/com/mineinabyss/geary/autoscan/AutoScanner.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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>() | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
geary-autoscan/src/main/kotlin/com/mineinabyss/geary/autoscan/AutoscanAnnotations.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.