Skip to content

Commit cf34322

Browse files
committed
add: add ListenerType and DataConverterType
1 parent e638d61 commit cf34322

File tree

7 files changed

+130
-20
lines changed

7 files changed

+130
-20
lines changed

src/main/java/top/focess/qq/api/command/CommandType.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package top.focess.qq.api.command;
22

3-
import top.focess.qq.api.plugin.Plugin;
4-
53
import java.lang.annotation.ElementType;
64
import java.lang.annotation.Retention;
75
import java.lang.annotation.RetentionPolicy;
@@ -14,13 +12,6 @@
1412
@Retention(RetentionPolicy.RUNTIME)
1513
public @interface CommandType {
1614

17-
/**
18-
* Set the plugin the command belongs to
19-
*
20-
* @return the plugin the command belongs to
21-
*/
22-
Class<? extends Plugin> plugin();
23-
2415
/**
2516
* Set the name of the command
2617
*
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package top.focess.qq.api.command.converter;
2+
3+
import top.focess.qq.api.command.data.DataBuffer;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* Represent this field is a DataConverter
12+
*/
13+
@Target(value = ElementType.FIELD)
14+
@Retention(RetentionPolicy.RUNTIME)
15+
public @interface DataConverterType {
16+
17+
Class<? extends DataBuffer<?>> buffer();
18+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package top.focess.qq.api.command.converter;
2+
3+
import top.focess.qq.api.command.DataConverter;
4+
5+
/**
6+
* Thrown to indicate this class is not an illegal DataConverter class
7+
*/
8+
public class IllegalDataConverterClassException extends IllegalArgumentException {
9+
10+
/**
11+
* Constructs a IllegalDataConverterClassException
12+
* @param c the illegal DataConverter class
13+
* @param e the cause
14+
*/
15+
public IllegalDataConverterClassException(Class<? extends DataConverter> c, Exception e) {
16+
super("The class " + c.getName() + " is an illegal DataConverter class", e);
17+
}
18+
19+
public IllegalDataConverterClassException(Class<?> c) {
20+
super("The class " + c.getName() + " is an illegal DataConverter class");
21+
}
22+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package top.focess.qq.api.event;
2+
/**
3+
* Thrown to indicate this class is not an illegal Listener class
4+
*/
5+
public class IllegalListenerClassException extends IllegalArgumentException {
6+
/**
7+
* Constructs a IllegalListenerClassException
8+
*
9+
* @param c the illegal listener class
10+
*/
11+
public IllegalListenerClassException(Class<?> c) {
12+
super("The class " + c.getName() + " is an illegal Listener class");
13+
}
14+
15+
/**
16+
* Constructs a IllegalListenerClassException
17+
* @param c the illegal Listener class
18+
* @param e the cause
19+
*/
20+
public IllegalListenerClassException(Class<? extends Listener> c, Exception e) {
21+
super("The class " + c.getName() + " is an illegal Listener class", e);
22+
}
23+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package top.focess.qq.api.event;
2+
3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
7+
8+
/**
9+
* Represent this class is a Listener. It means that this class must implement Listener class.
10+
*/
11+
@Target(value = ElementType.TYPE)
12+
@Retention(RetentionPolicy.RUNTIME)
13+
public @interface ListenerType {
14+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package top.focess.qq.core.plugin;
2+
3+
import java.lang.annotation.Annotation;
4+
import java.lang.reflect.Field;
5+
6+
public interface FieldAnnotationHandler {
7+
8+
void handle(Field field, Annotation annotation, PluginClassLoader pluginClassLoader);
9+
}

src/main/java/top/focess/qq/core/plugin/PluginClassLoader.java

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
import org.jetbrains.annotations.Nullable;
88
import top.focess.qq.FocessQQ;
99
import top.focess.qq.api.command.*;
10-
import top.focess.qq.api.event.EventManager;
11-
import top.focess.qq.api.event.EventSubmitException;
12-
import top.focess.qq.api.event.ListenerHandler;
10+
import top.focess.qq.api.command.converter.DataConverterType;
11+
import top.focess.qq.api.command.converter.IllegalDataConverterClassException;
12+
import top.focess.qq.api.command.data.DataBuffer;
13+
import top.focess.qq.api.event.*;
1314
import top.focess.qq.api.event.plugin.PluginLoadEvent;
1415
import top.focess.qq.api.event.plugin.PluginUnloadEvent;
1516
import top.focess.qq.api.plugin.*;
@@ -25,9 +26,7 @@
2526
import java.io.File;
2627
import java.io.IOException;
2728
import java.lang.annotation.Annotation;
28-
import java.lang.reflect.Field;
29-
import java.lang.reflect.Method;
30-
import java.lang.reflect.Modifier;
29+
import java.lang.reflect.*;
3130
import java.net.MalformedURLException;
3231
import java.net.URL;
3332
import java.net.URLClassLoader;
@@ -55,6 +54,7 @@ public class PluginClassLoader extends URLClassLoader {
5554
private static final Object LOCK = new Object();
5655
private static final Map<String, Set<File>> AFTER_PLUGINS_MAP = Maps.newHashMap();
5756
private static final Map<Class<? extends Annotation>, AnnotationHandler> HANDLERS = Maps.newHashMap();
57+
private static final Map<Class<? extends Annotation>, FieldAnnotationHandler> FIELD_ANNOTATION_HANDLERS = Maps.newHashMap();
5858

5959
private static final List<ResourceHandler> RESOURCE_HANDLERS = Lists.newArrayList();
6060

@@ -137,9 +137,7 @@ public PluginDescription getPluginDescription() {
137137
CommandType commandType = (CommandType) annotation;
138138
if (Command.class.isAssignableFrom(c) && !Modifier.isAbstract(c.getModifiers())) {
139139
try {
140-
Plugin plugin = Plugin.getPlugin(commandType.plugin());
141-
if (plugin == null)
142-
throw new IllegalCommandClassException(c);
140+
Plugin plugin = classLoader.plugin;
143141
Command command = (Command) c.newInstance();
144142
if (!commandType.name().isEmpty()){
145143
COMMAND_NAME_FIELD.set(command,commandType.name());
@@ -153,7 +151,7 @@ public PluginDescription getPluginDescription() {
153151
COMMAND_INITIALIZE_FIELD.set(command,true);
154152
}
155153
}
156-
Command.register(plugin, command);
154+
plugin.registerCommand(command);
157155
return true;
158156
} catch (Exception e) {
159157
if (e instanceof CommandDuplicateException)
@@ -164,6 +162,39 @@ else if (e instanceof CommandLoadException)
164162
}
165163
} else throw new IllegalCommandClassException(c);
166164
});
165+
166+
HANDLERS.put(ListenerType.class, (c, annotation, classLoader) -> {
167+
if (Listener.class.isAssignableFrom(c) && !Modifier.isInterface(c.getModifiers()) && !Modifier.isAbstract(c.getModifiers())) {
168+
try {
169+
Plugin plugin = classLoader.plugin;
170+
Listener listener = (Listener) c.newInstance();
171+
plugin.registerListener(listener);
172+
return true;
173+
} catch (Exception e) {
174+
throw new IllegalListenerClassException((Class<? extends Listener>) c, e);
175+
}
176+
} else throw new IllegalListenerClassException(c);
177+
});
178+
179+
FIELD_ANNOTATION_HANDLERS.put(DataConverterType.class,(field, annotation, classLoader) -> {
180+
DataConverterType dataConverterType = (DataConverterType) annotation;
181+
if (DataConverter.class.isAssignableFrom(field.getType())) {
182+
try {
183+
Plugin plugin = classLoader.plugin;
184+
DataConverter dataConverter = (DataConverter) field.get(null);
185+
Constructor<DataBuffer<?>> constructor = (Constructor<DataBuffer<?>>) dataConverterType.buffer().getDeclaredConstructor(int.class);
186+
plugin.registerBuffer(dataConverter, size -> {
187+
try {
188+
return constructor.newInstance(size);
189+
} catch (Exception e) {
190+
throw new RuntimeException(e);
191+
}
192+
});
193+
} catch (Exception e) {
194+
throw new IllegalDataConverterClassException((Class<? extends DataConverter>) field.getType(), e);
195+
}
196+
} else throw new IllegalDataConverterClassException(field.getType());
197+
});
167198
}
168199

169200
private static final Scheduler SCHEDULER = Schedulers.newThreadPoolScheduler(FocessQQ.getMainPlugin(),2,false,"PluginLoader");
@@ -175,6 +206,8 @@ else if (e instanceof CommandLoadException)
175206
* @param plugin the plugin need to be enabled
176207
* @throws PluginLoaderException if the classloader of the plugin is not {@link PluginClassLoader}
177208
* @throws PluginDuplicateException if the plugin name already exists in the registered plugins
209+
* @throws PluginLoadException if there is an error while enabling the plugin
210+
* @throws PluginUnloadException if the plugin should be unloaded
178211
*/
179212
public static void enablePlugin(Plugin plugin) {
180213
if (plugin.getClass() != FocessQQ.MainPlugin.class) {
@@ -378,7 +411,7 @@ public boolean load() {
378411

379412
for (Class<?> c : loadedClasses)
380413
analyseClass(c);
381-
FocessQQ.getLogger().debugLang("load-command-class");
414+
FocessQQ.getLogger().debugLang("load-class");
382415

383416
FocessQQ.getLogger().debugLang("load-depend-plugin");
384417
for (File file : AFTER_PLUGINS_MAP.getOrDefault(plugin.getName(), Sets.newHashSet())) {

0 commit comments

Comments
 (0)