TaskMap.java 5.69 KB
Newer Older
Yazawazi's avatar
Yazawazi committed
1
2
3
package emu.grasscutter.task;

import emu.grasscutter.Grasscutter;
Yazawazi's avatar
Yazawazi committed
4
5

import org.quartz.*;
Yazawazi's avatar
Yazawazi committed
6
7
8
9
10
11
12
13
14
import org.quartz.impl.StdSchedulerFactory;
import org.reflections.Reflections;

import java.util.*;

@SuppressWarnings({"UnusedReturnValue", "unused"})
public final class TaskMap {
    private final Map<String, TaskHandler> tasks = new HashMap<>();
    private final Map<String, Task> annotations = new HashMap<>();
Yazawazi's avatar
Yazawazi committed
15
    private final Map<String, TaskHandler> afterReset = new HashMap<>();
Yazawazi's avatar
Yazawazi committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    private final SchedulerFactory schedulerFactory = new StdSchedulerFactory();
    
    public TaskMap() {
        this(false);
    }

    public TaskMap(boolean scan) {
        if (scan) this.scan();
    }

    public static TaskMap getInstance() {
        return Grasscutter.getGameServer().getTaskMap();
    }

Yazawazi's avatar
Yazawazi committed
30
31
32
    public void resetNow() {
        // Unregister all tasks
        for (TaskHandler task : this.tasks.values()) {
Yazawazi's avatar
Yazawazi committed
33
            unregisterTask(task);
Yazawazi's avatar
Yazawazi committed
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
        }

        // Run all afterReset tasks
        for (TaskHandler task : this.afterReset.values()) {
            try {
                task.restartExecute();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // Remove all afterReset tasks
        this.afterReset.clear();

        // Register all tasks
        for (TaskHandler task : this.tasks.values()) {
            registerTask(task.getClass().getAnnotation(Task.class).taskName(), task);
        }
    }

Yazawazi's avatar
Yazawazi committed
54
55
56
    public TaskMap unregisterTask(TaskHandler task) {
        this.tasks.remove(task.getClass().getAnnotation(Task.class).taskName());
        this.annotations.remove(task.getClass().getAnnotation(Task.class).taskName());
Yazawazi's avatar
Yazawazi committed
57
58
59

        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
Yazawazi's avatar
Yazawazi committed
60
            scheduler.deleteJob(new JobKey(task.getClass().getAnnotation(Task.class).taskName()));
Yazawazi's avatar
Yazawazi committed
61
62
63
64
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

Yazawazi's avatar
Yazawazi committed
65
66
        task.onDisable();

Yazawazi's avatar
Yazawazi committed
67
68
69
        return this;
    }

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
    public boolean pauseTask(String taskName) {
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            scheduler.pauseJob(new JobKey(taskName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean resumeTask(String taskName) {
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            scheduler.resumeJob(new JobKey(taskName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public boolean cancelTask(String taskName) {
        Task task = this.annotations.get(taskName);
        if (task == null) return false;
        try {
            this.unregisterTask(this.tasks.get(taskName));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

Yazawazi's avatar
Yazawazi committed
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    public TaskMap registerTask(String taskName, TaskHandler task) {
        Task annotation = task.getClass().getAnnotation(Task.class);
        this.annotations.put(taskName, annotation);
        this.tasks.put(taskName, task);

        // register task
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            JobDetail job = JobBuilder
                        .newJob(task.getClass())
                        .withIdentity(taskName)
                        .build();
            
            Trigger convTrigger = TriggerBuilder.newTrigger()
                        .withIdentity(annotation.triggerName())
                        .withSchedule(CronScheduleBuilder.cronSchedule(annotation.taskCronExpression()))
                        .build();
            
            scheduler.scheduleJob(job, convTrigger);
Yazawazi's avatar
Yazawazi committed
123
124
125
126

            if (annotation.executeImmediately()) {
                task.execute(null);
            }
Yazawazi's avatar
Yazawazi committed
127
            task.onEnable();
Yazawazi's avatar
Yazawazi committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

        return this;
    }

    public List<TaskHandler> getHandlersAsList() {
        return new LinkedList<>(this.tasks.values());
    }

    public HashMap<String, TaskHandler> getHandlers() {
        return new LinkedHashMap<>(this.tasks);
    }

    public TaskHandler getHandler(String taskName) {
        return this.tasks.get(taskName);
    }

    private void scan() {
        Reflections reflector = Grasscutter.reflector;
        Set<Class<?>> classes = reflector.getTypesAnnotatedWith(Task.class);
        classes.forEach(annotated -> {
            try {
                Task taskData = annotated.getAnnotation(Task.class);
153
                Object object = annotated.getDeclaredConstructor().newInstance();
Yazawazi's avatar
Yazawazi committed
154
                if (object instanceof TaskHandler) {
Yazawazi's avatar
Yazawazi committed
155
                    this.registerTask(taskData.taskName(), (TaskHandler) object);
Yazawazi's avatar
Yazawazi committed
156
157
158
159
160
161
                    if (taskData.executeImmediatelyAfterReset()) {
                        this.afterReset.put(taskData.taskName(), (TaskHandler) object);
                    }
                } else {
                    Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a TaskHandler!");
                }
Yazawazi's avatar
Yazawazi committed
162
163
164
165
            } catch (Exception exception) {
                Grasscutter.getLogger().error("Failed to register task handler for " + annotated.getSimpleName(), exception);
            }
        });
Yazawazi's avatar
Yazawazi committed
166
167
168
169
170
171
172
        try {
            Scheduler scheduler = schedulerFactory.getScheduler();
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

Yazawazi's avatar
Yazawazi committed
173
174
    }
}