Skip to content
This repository was archived by the owner on Dec 8, 2020. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
be2cf89
Add server module
JarvisCraft Jun 18, 2019
23c5720
Rework ierarchy of `protocol` Server in order to be more logical
JarvisCraft Jun 18, 2019
7c1e94f
Add Guava dependency to `module-api`
JarvisCraft Jun 19, 2019
7feb2d9
Force usage of `Set` as `AbstractModuleLoader`'s backend
JarvisCraft Jun 19, 2019
76f5269
Make docs of `ModuleLoader`s' `M` generic more clear
JarvisCraft Jun 19, 2019
b59632e
Add `SimpleModuleLoader`
JarvisCraft Jun 19, 2019
3c56567
Add feather-core dependencies to `server`
JarvisCraft Jun 19, 2019
c8b90f8
Add annotation dependencies to `server`
JarvisCraft Jun 19, 2019
ff84bc9
Add root FeatherServer API components
JarvisCraft Jun 19, 2019
bf2c002
Remove delegate in interface `FeatherServer`
JarvisCraft Jun 19, 2019
e3b0c6b
Merge remote-tracking branch 'origin/server-api' into server-api
JarvisCraft Jul 1, 2019
ee88c31
Enable usage of Sonatype snapshots repo
JarvisCraft Jul 1, 2019
b009c97
Add Guava dependency to `shared`
JarvisCraft Jul 2, 2019
a26188d
Add test dependencies to `shared`
JarvisCraft Jul 2, 2019
2fbba28
Implement InvokeUtil
JarvisCraft Jul 2, 2019
ca7eff9
Add test dependencies to `protocol`
JarvisCraft Jul 2, 2019
9c070e4
Rework PacketType to allow annotation-based registration
JarvisCraft Jul 2, 2019
6fc0dff
Add `@PacketId` annotations to all packets
JarvisCraft Jul 2, 2019
2e616f3
Use `final` in catch of SimpleEventManager
JarvisCraft Nov 9, 2019
b2ca2ce
Replace `NamedThreadFactory` with `ThreadFactories`
JarvisCraft Nov 9, 2019
5d53655
Suppress redundant cast inspection in `CommonHandshakePacketRegistry`
JarvisCraft Nov 9, 2019
0a4fd90
Refactor `SharedNettyResources`
JarvisCraft Nov 9, 2019
03a1200
Refactor `TransportType`
JarvisCraft Nov 9, 2019
3dc07a2
Add other constructors to `PacketHandleException`
JarvisCraft Nov 9, 2019
7eaed54
Bump lombok from 1.18.8 to 1.18.10
dependabot-preview[bot] Nov 10, 2019
8bbd9ee
Merge branch 'development' into refactoring
JarvisCraft Nov 10, 2019
391f985
Refactor and fix `SharedNettyResources` amd related
JarvisCraft Nov 10, 2019
c437b32
Merge branch 'refactoring' into server-api
JarvisCraft Nov 15, 2019
c6043e7
Merge pull request #32 from feather-core/server-api
JarvisCraft Nov 15, 2019
a181b4a
Resolve problems with NettyServer infrastructure
JarvisCraft Nov 15, 2019
c0fe6cd
Merge pull request #64 from feather-core/development
JarvisCraft Nov 15, 2019
2920918
Add `jupiter-params` to `module-loader`
JarvisCraft Nov 15, 2019
7f9e591
Rework ModuleLoader API
JarvisCraft Nov 15, 2019
b5f4203
Remind myself about docs of AbstractModuleLoader
JarvisCraft Nov 15, 2019
8fa07ab
Use factory methods for `SimpleModuleLoader`
JarvisCraft Nov 15, 2019
f761e52
Add `padla` version to POM
JarvisCraft Nov 15, 2019
49489f0
Add `java-commons` and `reflector` dependencies
JarvisCraft Nov 15, 2019
4b51285
Add `padla` dependencies to modules with legacy classes continued in it
JarvisCraft Nov 15, 2019
a26c963
Replace legacy classes with their continuations from `padla`
JarvisCraft Nov 15, 2019
96375a2
Merge pull request #50 from feather-core/dependabot/maven/development…
JarvisCraft Nov 15, 2019
3661b38
Bump lombok from 1.18.8 to 1.18.10
dependabot-preview[bot] Nov 18, 2019
06c7dcf
Merge pull request #66 from feather-core/dependabot/maven/development…
JarvisCraft Nov 18, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions eventbus/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
<artifactId>feathercore-eventbus</artifactId>

<dependencies>
<dependency>
<groupId>ru.progrm-jarvis</groupId>
<artifactId>reflector</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,9 @@
import lombok.experimental.FieldDefaults;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import ru.progrm_jarvis.reflector.invoke.InvokeUtil;

import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
Expand Down Expand Up @@ -83,7 +81,14 @@ public void register(@NonNull final Object listener) {
}

EventHandler annotation = method.getAnnotation(EventHandler.class);
register((Class<? extends E>) parameterType, constructConsumer(listener, method), annotation.priority());
register(
(Class<E>) parameterType,
InvokeUtil.<Consumer<E>, Object>invokeFactory()
.boundTo(listener)
.implementing(Consumer.class)
.via(method)
.createUnsafely(),
annotation.priority());
}
}

Expand All @@ -106,23 +111,6 @@ public <T extends E> void call(@NotNull final T event) {
}
}

@SuppressWarnings("unchecked")
protected static <E extends Event> Consumer<E> constructConsumer(Object listener, Method method) {
try {
Lookup lookup = constructLookup(listener.getClass());
return (Consumer<E>) LambdaMetafactory.metafactory(
lookup,
"accept",
MethodType.methodType(Consumer.class, listener.getClass()),
MethodType.methodType(void.class, Object.class),
lookup.unreflect(method),
MethodType.methodType(void.class, method.getParameterTypes()[0])
).getTarget().invoke(listener);
} catch (Throwable t) {
throw new RuntimeException("Could not create event listener", t);
}
}

/**
* We are in need of our own Lookup creation with an argument of given owner class, because we want to be able
* to execute private and any other non-public methods.
Expand Down
14 changes: 14 additions & 0 deletions module-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
<artifactId>feathercore-shared</artifactId>
</dependency>

<dependency>
<groupId>ru.progrm-jarvis</groupId>
<artifactId>java-commons</artifactId>
</dependency>

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
Expand All @@ -45,6 +55,10 @@
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,58 +20,116 @@
import lombok.experimental.FieldDefaults;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Collections;
import java.util.*;

/**
* An abstract implementation of {@link ModuleLoader<M>} sufficient for all operations it requires.
*
* @param <M> super-type of all modules managed
* @param <M> super-type of modules which this module-loader can manage
*
* // TODO: 15.11.2019 Docs
*/
@ToString
@EqualsAndHashCode
@FieldDefaults(level = AccessLevel.PROTECTED, makeFinal = true)
public abstract class AbstractModuleLoader<M extends Module> implements ModuleLoader<M> {
public class AbstractModuleLoader<M extends Module> implements ModuleLoader<M> {

@NonNull Map<Class<? extends M>, M> modules;
/**
* Storage of unique instanced of loaded modules.
*/
@NonNull Set<M> loadedModules, loadedModulesView;

/**
* Creates new instance of module loader using the given {@link Collection collections} for storage of modules.
*
* @param modulesMap set which will be used for storage of associations of module types with their implementations
* @param loadedModulesSet set which will be used for storage of loaded modules
* @throws IllegalArgumentException if the given set is non-empty
*/
public AbstractModuleLoader(@NonNull final Map<Class<? extends M>, M> modulesMap,
@NonNull final Set<M> loadedModulesSet) {
if (!modulesMap.isEmpty()) throw new IllegalArgumentException("modules map should be empty");
if (!loadedModulesSet.isEmpty()) throw new IllegalArgumentException("loaded modules set should be empty");

modules = modulesMap;
loadedModules = loadedModulesSet;
loadedModulesView = Collections.unmodifiableSet(loadedModules);
}

@NonNull Collection<M> modules, modulesView;
/* ************************************************* Callbacks ************************************************* */

public AbstractModuleLoader(@NonNull final Collection<M> modules) {
this.modules = modules;
modulesView = Collections.unmodifiableCollection(modules);
/**
* Callback used by method-loading methods to notify that the module has been loaded.
*
* @param module module which has just been loaded
*/
protected void onModuleLoad(@NotNull final M module) {}

/**
* Callback used by {@link #unloadModule(Class)} to notify that the module has been unloaded.
*
* @param module module which has just been unloaded
*/
protected void onModuleUnload(@NotNull final M module) {}

/* *************************************************** Logic *************************************************** */

@Override
public Collection<M> getModules() {
return loadedModulesView;
}

@Override
public Collection<? extends M> getModules() {
return modulesView;
@SuppressWarnings("unchecked")
public <T extends M> Optional<? extends T> getModule(@NonNull final Class<T> type) {
return Optional.ofNullable((T) modules.get(type));
}

@Override
public <T extends M, C> T loadModule(@NonNull final ModuleInitializer<T, C> initializer, final C configuration) {
public boolean isModuleLoaded(@NonNull final Class<? extends M> type) {
return modules.containsKey(type);
}

@Override
public <T extends M> boolean isModuleLoaded(@NonNull final T module) {
return modules.containsValue(module);
}

@Override
public <T extends M, C> T loadModule(@NonNull final ModuleInitializer<T, C> initializer, final C configuration,
final Iterable<Class<T>> moduleTypes) {
val module = initializer.loadModule(configuration);
if (modules.add(module)) onModuleLoad(module);
for (val moduleType : moduleTypes) modules.put(moduleType, module);
loadedModules.add(module);

onModuleLoad(module);

return module;
}

@Override
public <T extends M> boolean unloadModule(@NonNull final T module) {
val unloaded = modules.remove(module);
if (unloaded) onModuleUnload(module);
public <T extends M> Optional<T> unloadModule(@NonNull final Class<? extends T> moduleType) {
@SuppressWarnings("unchecked") val module = (T) modules.remove(moduleType);
if (module != null) {
if (!modules.containsValue(module)) loadedModules.remove(module);
onModuleUnload(module);

return Optional.of(module);
}

return unloaded;
return Optional.empty();
}

/**
* Callback used by {@link #loadModule(ModuleInitializer, Object)} to notify that the module has been loaded.
*
* @param module module which has just been loaded
*/
protected void onModuleLoad(@NotNull final M module) {}
@Override
public Collection<? extends M> unloadAllModules() {
val modulesUnloaded = new ArrayList<>(loadedModules);

/**
* Callback used by {@link #unloadModule(Module)} to notify that the module has been unloaded.
*
* @param module module which has just been loaded
*/
protected void onModuleUnload(@NotNull final M module) {}
for (val module : modulesUnloaded) onModuleUnload(module);

modules.clear();
loadedModules.clear();

return modulesUnloaded;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

package ru.feathercore.moduleapi;

import org.feathercore.shared.object.ValueContainer;
import org.jetbrains.annotations.NotNull;
import ru.progrm_jarvis.javacommons.object.ValueContainer;

/**
* Initializer of a module which is normally used by {@link ModuleLoader} to load a specific module.
Expand Down
Loading