[FEATURE] Version comparing

This commit is contained in:
Gravita 2021-04-06 22:36:43 +07:00
parent f1331b6d5d
commit 6c37dd6ed2
7 changed files with 115 additions and 11 deletions

View file

@ -64,7 +64,7 @@ public static void prepare() throws Throwable {
launchServer = builder.build();
}
@Test
public static void reloadTest() throws Exception {
public void reloadTest() throws Exception {
AuthProvider provider = new AuthProvider() {
@Override
public AuthProviderResult auth(String login, AuthRequest.AuthPasswordInterface password, String ip) throws Exception {

View file

@ -1,14 +1,24 @@
package pro.gravit.launcher.modules;
import pro.gravit.launcher.LauncherTrustManager;
import pro.gravit.utils.Version;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public abstract class LauncherModule {
protected final LauncherModuleInfo moduleInfo;
@SuppressWarnings("rawtypes")
private final Map<Class<? extends Event>, EventHandler> eventMap = new HashMap<>();
private final static class EventEntity<T extends Event> {
final Class<T> clazz;
final EventHandler<T> handler;
private EventEntity(EventHandler<T> handler, Class<T> clazz) {
this.clazz = clazz;
this.handler = handler;
}
}
private final List<EventEntity<? extends Event>> eventList = new ArrayList<>(4);
protected LauncherModulesManager modulesManager;
protected ModulesConfigManager modulesConfigManager;
protected InitStatus initStatus = InitStatus.CREATED;
@ -23,7 +33,7 @@ protected LauncherModule(LauncherModuleInfo info) {
moduleInfo = info;
}
public LauncherModuleInfo getModuleInfo() {
public final LauncherModuleInfo getModuleInfo() {
return moduleInfo;
}
@ -60,6 +70,27 @@ public final LauncherTrustManager.CheckClassResult getCheckResult() {
return new LauncherTrustManager.CheckClassResult(this.checkResult);
}
protected final LauncherModule requireModule(String name, Version minVersion) {
if(context == null) throw new IllegalStateException("requireModule must be used in init() phase");
LauncherModule module = context.getModulesManager().getModule(name);
requireModule(module, minVersion, name);
return module;
}
protected final <T extends LauncherModule> T requireModule(Class<? extends T> clazz, Version minVersion) {
if(context == null) throw new IllegalStateException("requireModule must be used in init() phase");
T module = context.getModulesManager().getModule(clazz);
requireModule(module, minVersion, clazz.getName());
return module;
}
private void requireModule(LauncherModule module, Version minVersion, String requiredModuleName) {
if(module == null)
throw new RuntimeException(String.format("Module %s required %s v%s or higher", moduleInfo.name, requiredModuleName, minVersion.getVersionString()));
else if(module.moduleInfo.version.isLowerThan(minVersion))
throw new RuntimeException(String.format("Module %s required %s v%s or higher (current version %s)", moduleInfo.name, requiredModuleName, minVersion.getVersionString(), module.moduleInfo.version.getVersionString()));
}
/**
* The internal method used by the ModuleManager
* DO NOT TOUCH
@ -86,7 +117,7 @@ public void preInitAction() {
//NOP
}
public LauncherModule preInit() {
public final LauncherModule preInit() {
if (!initStatus.equals(InitStatus.PRE_INIT_WAIT))
throw new IllegalStateException("PreInit not allowed in current state");
initStatus = InitStatus.PRE_INIT;
@ -121,7 +152,8 @@ public LauncherModule preInit() {
* @return true if adding a handler was successful
*/
protected <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<T> tClass) {
eventMap.put(tClass, handle);
EventEntity<T> eventEntity = new EventEntity<T>(handle, tClass);
eventList.add(eventEntity);
return true;
}
@ -134,10 +166,11 @@ protected <T extends Event> boolean registerEvent(EventHandler<T> handle, Class<
@SuppressWarnings("unchecked")
public final <T extends Event> void callEvent(T event) {
Class<? extends Event> tClass = event.getClass();
for (@SuppressWarnings("rawtypes") Map.Entry<Class<? extends Event>, EventHandler> e : eventMap.entrySet()) {
for (EventEntity<? extends Event> entity : eventList) {
if (e.getKey().isAssignableFrom(tClass)) {
e.getValue().event(event);
if (entity.clazz.isAssignableFrom(tClass)) {
//noinspection RedundantCast
((EventEntity<T>)entity).handler.event(event);
if (event.isCancel()) return;
}
}

View file

@ -37,6 +37,8 @@ default <T extends LauncherModule> boolean containsModule(Class<? extends T> cla
<T extends LauncherModule> T findModule(Class<? extends T> clazz, Predicate<Version> versionPredicate);
LauncherModule findModule(String name, Predicate<Version> versionPredicate);
/**
* Invoke event processing for all modules.
* Event processing is carried out in the order of the modules in the list (sorted by priority)

View file

@ -266,6 +266,16 @@ public <T extends LauncherModule> T findModule(Class<? extends T> clazz, Predica
return null;
}
@Override
public LauncherModule findModule(String name, Predicate<Version> versionPredicate) {
for (LauncherModule module : modules) {
LauncherModuleInfo info = module.getModuleInfo();
if (!versionPredicate.test(info.version)) continue;
if (name.equals(info.name)) return module;
}
return null;
}
@Override
public <T extends LauncherModule.Event> void invokeEvent(T event) {
for (LauncherModule module : modules) {

View file

@ -1,8 +1,10 @@
package pro.gravit.launcher.impl;
import org.junit.jupiter.api.Assertions;
import pro.gravit.launcher.modules.LauncherInitContext;
import pro.gravit.launcher.modules.LauncherModule;
import pro.gravit.launcher.modules.LauncherModuleInfo;
import pro.gravit.utils.Version;
public class Depend2Module extends LauncherModule {
public Depend2Module() {
@ -17,5 +19,18 @@ public void preInitAction() {
@Override
public void init(LauncherInitContext initContext) {
requireModule("depend1", new Version(1,0,0));
try {
requireModule("dependNotFound", new Version(1,0,0));
Assertions.fail("dependNotFound");
} catch (RuntimeException ignored) {
}
try {
requireModule("depend1", new Version(10,0,0));
Assertions.fail("depend1 high version");
} catch (RuntimeException ignored) {
}
}
}

View file

@ -2,7 +2,7 @@
import java.util.*;
public final class Version {
public final class Version implements Comparable<Version> {
public static final int MAJOR = 5;
public static final int MINOR = 2;
@ -24,6 +24,18 @@ public Version(int major, int minor, int patch) {
release = Type.UNKNOWN;
}
public static Version of(int major, int minor, int patch) {
return new Version(major, minor, patch);
}
public static Version of(int major, int minor, int patch, int build) {
return new Version(major, minor, patch, build);
}
public static Version of(int major, int minor, int patch, int build, Type release) {
return new Version(major, minor, patch, build, release);
}
public Version(int major, int minor, int patch, int build) {
this.major = major;
@ -81,6 +93,22 @@ public String toString() {
return String.format("%d.%d.%d-%d %s", major, minor, patch, build, getReleaseStatus());
}
@Override
public int compareTo(Version version) {
if(version.major != major) return Integer.compare(major, version.major);
if(version.minor != minor) return Integer.compare(minor, version.minor);
if(version.patch != patch) return Integer.compare(patch, version.patch);
return 0;
}
public boolean isUpperThan(Version version) {
return this.compareTo(version) > 0;
}
public boolean isLowerThan(Version version) {
return this.compareTo(version) < 0;
}
public enum Type {
LTS,

View file

@ -0,0 +1,16 @@
package pro.gravit.launcher;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import pro.gravit.utils.Version;
public class VersionCompareTest {
@Test
public void compareTest() {
Assertions.assertTrue(new Version(1,0,0).compareTo(new Version(1,1,0)) < 0);
Assertions.assertTrue(new Version(1,1,0).compareTo(new Version(1,0,0)) > 0);
Assertions.assertTrue(new Version(1,0,0).isLowerThan(new Version(1,1,0)));
Assertions.assertTrue(new Version(1,0,1).isUpperThan(new Version(1,0,0)));
}
}