diff --git a/README.md b/README.md index 64b9fff..add4823 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,28 @@ This is a very simple Java tool for games and other apps to manage resources. # Installation -The current version is `1.0`. This version is compatible with Java 17 and above. +The current version is `1.1`. This version is compatible with Java 17 and above. The artifact can be installed from my [Maven repository](https://maven.shadew.net/). ## Gradle +```kotlin +// Kotlin DSL: + +repositories { + // Add my repository + maven { url = uri("https://maven.shadew.net/") } +} + +dependencies { + // Add the artifact + implementation("dev.runefox:rms:1.1") +} +``` + ```groovy +// Groovy DSL: + repositories { // Add my repository maven { url "https://maven.shadew.net/" } @@ -15,7 +31,7 @@ repositories { dependencies { // Add the artifact - implementation "dev.runefox:rms:1.0" + implementation "dev.runefox:rms:1.1" } ``` @@ -34,7 +50,7 @@ dependencies { dev.runefox rms - 1.0 + 1.1 ``` @@ -166,7 +182,7 @@ ContentResource myContent = mgr.get(ContentResourceType.INSTANCE, "my_content"); ``` -## 5. Extra: Using handles +## Extra: Using handles In some occasion, you may want to reload all the resources in your application. This means all the `Resource` instances change. You will have to re-obtain all the resources yourself, which can be quite annoying to do. That is, unless you use `Handle`s. A `Handle` is a reference to a resource. It will store the resource for quick access but it's controlled by the resource manager and reset upon `dispose()`. Instead of calling `ResourceManager.get`, you can call `ResourceManager.handle` in exactly the same way to get a handle instead. You can then store this handle anywhere in your app without ever having to think about reloading it again. Another advantage of using handles is that they're lazily loaded: it will load the resource only when you request it using `Handle.get`. A handle is simply just a glorified `Supplier`. ```java @@ -177,6 +193,14 @@ ContentResource instance = myContent.get(); Now you can call `dispose` at any time to simply unload all resources. RMS will invalidate all handles and the next time you call `get` on any of them, it will reload the resource. In fact, you can call `dispose` and give a new root path, and the resource will load as usual from the new path. +# Libraries for certain formats + +Below is a list of libraries that load files in certain formats, with an artifact that belongs to it. All artifacts have the same version as the main project and all artifacts depend on the main project with the same version (in the list referred to with `[rms-version]`). + +- [JSON](https://github.com/FoxSamu/json/): use `dev.runefox:rms-json:[rms-version]`. + +In the future I may add more supported formats through my libraries or third-party libraries. + # License Licensed under the LGPLv3 license. For the full LGPL+GPLv3 license, see `LICENSE`. diff --git a/build.gradle.kts b/build.gradle.kts index 593b9df..d49a6c0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,12 +16,12 @@ */ plugins { - id("java") + id("java-library") id("maven-publish") } group = "dev.runefox" -version = "1.0" +version = "1.1" repositories { mavenCentral() diff --git a/rms-json/build.gradle.kts b/rms-json/build.gradle.kts new file mode 100644 index 0000000..09b9542 --- /dev/null +++ b/rms-json/build.gradle.kts @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +plugins { + id("java") + id("maven-publish") +} + +group = rootProject.group +version = rootProject.version + +repositories { + mavenCentral() + maven { + url = uri("https://maven.shadew.net/") + } +} + +dependencies { + implementation("dev.runefox:json:0.7.2") + implementation(rootProject) + + testImplementation(platform("org.junit:junit-bom:5.9.1")) + testImplementation("org.junit.jupiter:junit-jupiter") +} + +tasks.test { + useJUnitPlatform() +} + +java { + withSourcesJar() + withJavadocJar() +} + +publishing { + publications { + create("maven") { + groupId = "${project.group}" + artifactId = project.name + version = "${project.version}" + + from(components["java"]) + } + } + repositories { + maven { + // You should have received these credentials when given permission + // to the Runefox Maven repository + val rfxMavenHost: String by properties + val rfxMavenUser: String by properties + val rfxMavenPass: String by properties + + name = "RfxMaven" + url = uri(rfxMavenHost) + credentials { + username = rfxMavenUser + password = rfxMavenPass + } + } + } +} + diff --git a/rms-json/src/main/java/dev/runefox/rms/json/Json5CodecResourceType.java b/rms-json/src/main/java/dev/runefox/rms/json/Json5CodecResourceType.java new file mode 100644 index 0000000..384b2f8 --- /dev/null +++ b/rms-json/src/main/java/dev/runefox/rms/json/Json5CodecResourceType.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package dev.runefox.rms.json; + +import dev.runefox.json.Json; +import dev.runefox.json.codec.JsonCodec; +import dev.runefox.rms.Resource; +import dev.runefox.rms.ResourceManager; + +import java.util.function.Supplier; + +/** + * A {@link Json5ResourceType} that decodes the JSON tree using a {@link JsonCodec}. You don't need to implement this + * interface if you just want the default features, you can use {@link #create} to get an instance with basic + * functionality. + * + * @author Samū + * @since 1.1 + */ +public interface Json5CodecResourceType extends JsonCodecResourceType, Json5ResourceType { + // I don't know which of the interfaces takes priority if we don't + // override these methods, so I'll override them just to be sure + // (plus it's probably clearer what's happening). + + @Override + default Json json() { + return Json.json5(); + } + + @Override + default String extension() { + return "json5"; + } + + /** + * Creates a basic {@link Json5CodecResourceType} with a fixed codec and a supplied fallback instance. This is a + * convenience method to quickly have a resource type to load JSON resources. + * + * @param codec The codec. + * @param fallback The fallback supplier. + * @return A new {@link JsonCodecResourceType}. + * + * @since 1.1 + */ + static Json5CodecResourceType create(JsonCodec codec, Supplier fallback) { + return new Json5CodecResourceType<>() { + @Override + public JsonCodec codec(ResourceManager res, String ns, String name) { + return codec; + } + + @Override + public R createFallback(ResourceManager res, String ns, String name) { + return fallback.get(); + } + }; + } +} diff --git a/rms-json/src/main/java/dev/runefox/rms/json/Json5ResourceType.java b/rms-json/src/main/java/dev/runefox/rms/json/Json5ResourceType.java new file mode 100644 index 0000000..04d9a1d --- /dev/null +++ b/rms-json/src/main/java/dev/runefox/rms/json/Json5ResourceType.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package dev.runefox.rms.json; + +import dev.runefox.json.Json; +import dev.runefox.rms.Resource; + +/** + * A {@link JsonResourceType} that uses {@linkplain Json#json5() JSON 5} to parse a resource. + * + * @author Samū + * @see JsonResourceType + * @see Json5CodecResourceType + * @since 1.1 + */ +public interface Json5ResourceType extends JsonResourceType { + @Override + default Json json() { + return Json.json5(); + } + + @Override + default String extension() { + return "json5"; + } +} diff --git a/rms-json/src/main/java/dev/runefox/rms/json/JsonCodecResourceType.java b/rms-json/src/main/java/dev/runefox/rms/json/JsonCodecResourceType.java new file mode 100644 index 0000000..365bc02 --- /dev/null +++ b/rms-json/src/main/java/dev/runefox/rms/json/JsonCodecResourceType.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package dev.runefox.rms.json; + +import dev.runefox.json.JsonNode; +import dev.runefox.json.codec.JsonCodec; +import dev.runefox.rms.Resource; +import dev.runefox.rms.ResourceManager; + +import java.util.function.Supplier; + +/** + * A {@link JsonResourceType} that decodes the JSON tree using a {@link JsonCodec}. You don't need to implement this + * interface if you just want the default features, you can use {@link #create} to get an instance with basic + * functionality. + * + * @author Samū + * @since 1.1 + */ +public interface JsonCodecResourceType extends JsonResourceType { + @Override + default R load(ResourceManager res, String ns, String name, JsonNode in) { + return codec(res, ns, name).decode(in); + } + + /** + * Returns the {@link JsonCodec} to be used to decode resource instances. + * + * @param res The resource manager. + * @param ns The namespace. + * @param name The resource's name. + * @return The {@link JsonCodec} to decode with. + * + * @since 1.1 + */ + JsonCodec codec(ResourceManager res, String ns, String name); + + /** + * Creates a basic {@link JsonCodecResourceType} with a fixed codec and a supplied fallback instance. This is a + * convenience method to quickly have a resource type to load JSON resources. + * + * @param codec The codec. + * @param fallback The fallback supplier. + * @return A new {@link JsonCodecResourceType}. + * + * @since 1.1 + */ + static JsonCodecResourceType create(JsonCodec codec, Supplier fallback) { + return new JsonCodecResourceType<>() { + @Override + public JsonCodec codec(ResourceManager res, String ns, String name) { + return codec; + } + + @Override + public R createFallback(ResourceManager res, String ns, String name) { + return fallback.get(); + } + }; + } +} diff --git a/rms-json/src/main/java/dev/runefox/rms/json/JsonResourceType.java b/rms-json/src/main/java/dev/runefox/rms/json/JsonResourceType.java new file mode 100644 index 0000000..b95d89e --- /dev/null +++ b/rms-json/src/main/java/dev/runefox/rms/json/JsonResourceType.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package dev.runefox.rms.json; + +import dev.runefox.json.Json; +import dev.runefox.json.JsonNode; +import dev.runefox.rms.Resource; +import dev.runefox.rms.ResourceManager; +import dev.runefox.rms.TextResourceType; + +import java.io.BufferedReader; + +/** + * A {@link TextResourceType} that uses {@linkplain Json#json() JSON} to parse a resource. + * + * @author Samū + * @see Json5ResourceType + * @see JsonCodecResourceType + * @since 1.1 + */ +public interface JsonResourceType extends TextResourceType { + @Override + default R load(ResourceManager res, String ns, String name, BufferedReader in) throws Exception { + return load(res, ns, name, json().parse(in)); + } + + @Override + default String extension() { + return "json"; + } + + /** + * Returns a {@link Json} instance that is used to parse a resource. + * + * @return The {@link Json} instance. + * + * @since 1.1 + */ + default Json json() { + return Json.json(); + } + + /** + * Attempt loading a resource. When loading fails, it falls back to {@link #createFallback}. + * + * @param res The {@link ResourceManager}. + * @param ns The namespace. + * @param name The name of the resource. + * @param in The {@link JsonNode} that was loaded. + * @return The loaded resource. + * + * @throws Exception If loading fails. + * @since 1.1 + */ + R load(ResourceManager res, String ns, String name, JsonNode in) throws Exception; +} diff --git a/rms-json/src/main/java/module-info.java b/rms-json/src/main/java/module-info.java new file mode 100644 index 0000000..da31660 --- /dev/null +++ b/rms-json/src/main/java/module-info.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Samū + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import dev.runefox.rms.ResourceType; + +/** + * Basic JSON integration with RMS. This module provides a {@link ResourceType} that loads JSON formatted resources. + * + * @author Samū + * @since 1.1 + */ +module dev.runefox.rms.json { + exports dev.runefox.rms.json; + requires dev.runefox.rms; + requires dev.runefox.json; +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 362b395..f819a04 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,3 +17,4 @@ rootProject.name = "rms" +include(":rms-json") diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java new file mode 100644 index 0000000..d270aaa --- /dev/null +++ b/src/main/java/module-info.java @@ -0,0 +1,10 @@ +/** + * RMS stands for Resource Management System. This module provides basic Java tools to manage resources for apps and + * games written in Java (or Kotlin). + * + * @author Samū + * @since 1.1 + */ +module dev.runefox.rms { + exports dev.runefox.rms; +}