Skip to content

Commit ccf0ff3

Browse files
committed
Cleanup plugin API:
- Remove QuiltPluginTask This was never implemented properly, and I'm unsure if hiding CompletableFuture is even a good idea. Plus, I haven't actually implemented any multithreading yet - and it will be better to add proper a multithreading API along with the implementation, not a theoretical one beforehand. - Properly implement TentativeLoadOption. This part is still untested, but it should work in theory? Either way it no longer requires plugins to deal with tasks. - Remove GUI reference. I'm unsure how we should implement plugin gui requests - they could just use the existing gui API instead of needing something specific to plugins.
1 parent f9174c7 commit ccf0ff3

File tree

10 files changed

+37
-277
lines changed

10 files changed

+37
-277
lines changed

src/main/java/org/quiltmc/loader/api/plugin/QuiltLoaderPlugin.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,11 @@ default void finish(ModSolveResult result) {}
163163
// Solving
164164
// #######
165165

166-
/** Resolves a single {@link TentativeLoadOption} that was added via
167-
* {@link QuiltPluginContext#addTentativeOption(LoadOption)}. This is only called if the option was selected by the
168-
* solver - unselected options are not resolved.
169-
* <p>
170-
* Long-running operations should use {@link QuiltPluginContext#submit(java.util.concurrent.Callable)} to perform
171-
* those tasks in the future, and possibly on different threads. Operations that require use of the gui should use
172-
* {@link QuiltPluginContext#addGuiRequest()} instead, and call submit after that has been accepted or denied.
173-
*
174-
* @return A {@link QuiltPluginTask} containing (or will contain) the {@link LoadOption} that will replace the
175-
* {@link TentativeLoadOption} next cycle. */
176-
default QuiltPluginTask<? extends LoadOption> resolve(TentativeLoadOption from) {
177-
throw new IllegalStateException(
178-
getClass() + " has added a TentativeLoadOption (" + from.getClass() + ") but can't resolve it!"
179-
);
166+
/** Called once before {@link TentativeLoadOption}s are resolved. This is intended to allow plugins to queue
167+
* downloads, or begin other long-running activities that would benefit from running simultaneously. This is only
168+
* called with load options are selected by the solver - unselected options are excluded from this list. */
169+
default void preResolve(List<TentativeLoadOption> optionsToResolve) {
170+
// Nothing to do by default
180171
}
181172

182173
/** @return True if this plugin did something which will solve / change the error in future, and so loader won't ask

src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginContext.java

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -98,43 +98,6 @@ public interface QuiltPluginContext {
9898
* stacktrace to the crash report. */
9999
void haltLoading();
100100

101-
// ##############
102-
// # Scheduling #
103-
// ##############
104-
105-
/** Submits a task to be completed after plugin resolution, but before the current cycle ends. The task may be
106-
* executed on a different thread, depending on loaders config options.
107-
* <p>
108-
* This should only be called by {@link QuiltLoaderPlugin#resolve(TentativeLoadOption)},
109-
* {@link QuiltLoaderPlugin#finish(org.quiltmc.loader.api.plugin.solver.ModSolveResult)}, or by any tasks that are
110-
* passed to this function during their execution.
111-
*
112-
* @return A {@link QuiltPluginTask} which will contain the result of the task, or the failure state if something
113-
* went wrong. */
114-
<V> QuiltPluginTask<V> submit(Callable<V> task);
115-
116-
/** Submits a task to be completed after plugin resolution, and additionally after the given tasks have completed,
117-
* but before the current cycle ends. The task may be executed on a different thread, depending on loaders config
118-
* options. Note that the task will still be executed, <em>even if the dependencies failed.</em> This is to allow
119-
* the task to handle errors directly.
120-
*
121-
* @param deps The tasks that must complete before the given task can be executed.
122-
* @return A {@link QuiltPluginTask} which will contain the result of the task, or the failure state if something
123-
* went wrong. */
124-
<V> QuiltPluginTask<V> submitAfter(Callable<V> task, QuiltPluginTask<?>... deps);
125-
126-
// #######
127-
// # Gui #
128-
// #######
129-
130-
/** Used to ask the real user of something. Normally this will append something to the existing gui rather than
131-
* opening a new gui each time this is called.
132-
* <p>
133-
* TODO: Create all gui stuff! for now this just throws an {@link AbstractMethodError} */
134-
default <V> QuiltPluginTask<V> addGuiRequest() {
135-
throw new AbstractMethodError("// TODO: Add gui support!");
136-
}
137-
138101
// ###########
139102
// # Solving #
140103
// ###########

src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginManager.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -54,25 +54,6 @@ public interface QuiltPluginManager {
5454
// Loading
5555
// #######
5656

57-
/** Returns a task which will load the specified zip file and returns a path to the root of it's contents.
58-
* <p>
59-
* How the given zip is loaded depends on loaders config settings - in particular the zip could be extracted to a
60-
* temporary folder on the same filesystem as the original zip.
61-
* <p>
62-
* WARNING: if this method allocates a new {@link FileSystem} then that will be closed, <em>unless</em> at least one
63-
* of the {@link QuiltLoaderPlugin}s {@link QuiltPluginContext#lockZip(Path) locks} it, or if a chosen mod is loaded
64-
* from it.
65-
* <p>
66-
* The returned task may throw the following exceptions:
67-
* <ul>
68-
* <li>{@link IOException} if something went wrong while loading the file.</li>
69-
* <li>{@link NonZipException} if {@link FileSystems#newFileSystem(Path, ClassLoader)} throws a
70-
* {@link ProviderNotFoundException}.</li>
71-
* </ul>
72-
*
73-
* @see #loadZipNow(Path) */
74-
QuiltPluginTask<Path> loadZip(Path zip);
75-
7657
/** Loads the specified zip file and returns a path to the root of it's contents.
7758
* <p>
7859
* How the given zip is loaded depends on loaders config settings - in particular the zip could be extracted to a
@@ -84,8 +65,7 @@ public interface QuiltPluginManager {
8465
*
8566
* @throws IOException if something went wrong while loading the file.
8667
* @throws NonZipException if {@link FileSystems#newFileSystem(Path, ClassLoader)} throws a
87-
* {@link ProviderNotFoundException}.
88-
* @see #loadZip(Path) */
68+
* {@link ProviderNotFoundException}. */
8969
Path loadZipNow(Path zip) throws IOException, NonZipException;
9070

9171
/** Creates a new in-memory read-write file system. This can be used for mods that aren't loaded from zips.

src/main/java/org/quiltmc/loader/api/plugin/QuiltPluginTask.java

Lines changed: 0 additions & 56 deletions
This file was deleted.

src/main/java/org/quiltmc/loader/api/plugin/gui/package-info.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,5 @@
1414
* limitations under the License.
1515
*/
1616

17-
/**
18-
* The package for
19-
*/
17+
/** Deprecated package. Plugins should use {@link org.quiltmc.loader.api.gui.QuiltLoaderGui} instead. */
2018
package org.quiltmc.loader.api.plugin.gui;

src/main/java/org/quiltmc/loader/api/plugin/solver/TentativeLoadOption.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616

1717
package org.quiltmc.loader.api.plugin.solver;
1818

19+
import org.quiltmc.loader.api.plugin.QuiltLoaderPlugin;
1920
import org.quiltmc.loader.impl.util.QuiltLoaderInternal;
2021
import org.quiltmc.loader.impl.util.QuiltLoaderInternalType;
2122

2223
/** {@link LoadOption}s can implement this if they must be processed before they can be used, if they are selected.
2324
* <p>
24-
* Unselected {@link TentativeLoadOption}s are left alone at the end of the cycle, and are not resolved.
25-
*/
25+
* Unselected {@link TentativeLoadOption}s are left alone at the end of the cycle, and are not resolved. */
2626
@QuiltLoaderInternal(QuiltLoaderInternalType.PLUGIN_API)
2727
public interface TentativeLoadOption {
2828

29+
/** Resolves this to a real {@link LoadOption}. This is only invoked after
30+
* {@link QuiltLoaderPlugin#preResolve(java.util.List)} has already been called.
31+
*
32+
* @return a new {@link LoadOption} which can be loaded as-is. (It must not be another
33+
* {@link TentativeLoadOption}) */
34+
LoadOption resolve();
2935
}

src/main/java/org/quiltmc/loader/impl/plugin/BasePluginContext.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,13 @@
1818

1919
import java.nio.file.Path;
2020
import java.util.Collection;
21-
import java.util.concurrent.Callable;
2221

2322
import org.quiltmc.loader.api.plugin.QuiltPluginContext;
2423
import org.quiltmc.loader.api.gui.QuiltDisplayedError;
2524
import org.quiltmc.loader.api.gui.QuiltLoaderText;
2625
import org.quiltmc.loader.api.gui.QuiltTreeNode;
2726
import org.quiltmc.loader.api.gui.QuiltTreeNode.SortOrder;
2827
import org.quiltmc.loader.api.plugin.QuiltPluginManager;
29-
import org.quiltmc.loader.api.plugin.QuiltPluginTask;
3028
import org.quiltmc.loader.api.plugin.gui.PluginGuiTreeNode;
3129
import org.quiltmc.loader.api.plugin.solver.LoadOption;
3230
import org.quiltmc.loader.api.plugin.solver.ModLoadOption;
@@ -102,16 +100,6 @@ public void haltLoading() {
102100
manager.haltLoading(this);
103101
}
104102

105-
@Override
106-
public <V> QuiltPluginTask<V> submit(Callable<V> task) {
107-
return manager.submit(this, task);
108-
}
109-
110-
@Override
111-
public <V> QuiltPluginTask<V> submitAfter(Callable<V> task, QuiltPluginTask<?>... deps) {
112-
return manager.submitAfter(this, task, deps);
113-
}
114-
115103
@Override
116104
public RuleContext ruleContext() {
117105
return ruleContext;

src/main/java/org/quiltmc/loader/impl/plugin/PerCycleStep.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.quiltmc.loader.impl.plugin;
1818

1919
import org.quiltmc.loader.api.plugin.solver.ModSolveResult;
20-
import org.quiltmc.loader.api.plugin.solver.TentativeLoadOption;
2120
import org.quiltmc.loader.impl.util.QuiltLoaderInternal;
2221
import org.quiltmc.loader.impl.util.QuiltLoaderInternalType;
2322

@@ -31,9 +30,6 @@ enum PerCycleStep {
3130
/** Indicates that we've called {@link BuiltinQuiltPlugin#beforeSolve()}, and now we're solving. */
3231
SOLVE,
3332

34-
/** Indicates that solving has finished, and now we're resolving {@link TentativeLoadOption}s. */
35-
POST_SOLVE_TENTATIVE,
36-
3733
/** Indicates that solving was successful, and we have a resulting {@link ModSolveResult} to end loading with. */
3834
SUCCESS;
3935
}

src/main/java/org/quiltmc/loader/impl/plugin/QuiltPluginManagerImpl.java

Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@
7373
import org.quiltmc.loader.api.plugin.QuiltLoaderPlugin;
7474
import org.quiltmc.loader.api.plugin.QuiltPluginContext;
7575
import org.quiltmc.loader.api.plugin.QuiltPluginManager;
76-
import org.quiltmc.loader.api.plugin.QuiltPluginTask;
7776
import org.quiltmc.loader.api.plugin.gui.PluginGuiManager;
7877
import org.quiltmc.loader.api.plugin.gui.PluginGuiTreeNode;
7978
import org.quiltmc.loader.api.plugin.gui.PluginGuiTreeNode.WarningLevel;
@@ -238,18 +237,6 @@ private BuiltinPluginContext addBuiltinPlugin(BuiltinQuiltPlugin plugin, String
238237
// Loading
239238
// #######
240239

241-
@Override
242-
public QuiltPluginTask<Path> loadZip(Path zip) {
243-
if (config.singleThreadedLoading) {
244-
try {
245-
return QuiltPluginTask.createFinished(loadZipNow(zip));
246-
} catch (IOException | NonZipException e) {
247-
return QuiltPluginTask.createFailed(e);
248-
}
249-
}
250-
return submit(null, () -> loadZipNow(zip));
251-
}
252-
253240
/** Kept for backwards compatibility with the first versions of RGML-Quilt, as it invoked this using reflection. */
254241
@Deprecated
255242
private Path loadZip0(Path zip) throws IOException, NonZipException {
@@ -1356,7 +1343,7 @@ private ModSolveResultImpl runSingleCycle() throws ModResolutionException, Timeo
13561343
ModSolveResultImpl partialResult = getPartialSolution();
13571344

13581345
if (processTentatives(partialResult)) {
1359-
this.perCycleStep = step = PerCycleStep.POST_SOLVE_TENTATIVE;
1346+
this.perCycleStep = step = PerCycleStep.START;
13601347
} else {
13611348
this.perCycleStep = step = PerCycleStep.SUCCESS;
13621349
result = partialResult;
@@ -1371,10 +1358,6 @@ private ModSolveResultImpl runSingleCycle() throws ModResolutionException, Timeo
13711358
return null;
13721359
}
13731360
}
1374-
case POST_SOLVE_TENTATIVE: {
1375-
// TODO: Deal with tentative load options!
1376-
return null;
1377-
}
13781361
case SUCCESS: {
13791362

13801363
cleanup();
@@ -1585,9 +1568,29 @@ private boolean processTentatives(ModSolveResult partialResult) {
15851568
return false;
15861569
} else {
15871570

1571+
Map<QuiltPluginContext, List<TentativeLoadOption>> pluginsToOptions = new HashMap<>();
1572+
15881573
for (TentativeLoadOption option : tentatives) {
15891574
QuiltPluginContext pluginSrc = tentativeLoadOptions.get(option);
1590-
QuiltPluginTask<? extends LoadOption> resolution = pluginSrc.plugin().resolve(option);
1575+
pluginsToOptions.computeIfAbsent(pluginSrc, s -> new ArrayList<>()).add(option);
1576+
}
1577+
1578+
for (Map.Entry<QuiltPluginContext, List<TentativeLoadOption>> entry : pluginsToOptions.entrySet()) {
1579+
entry.getKey().plugin().preResolve(entry.getValue());
1580+
}
1581+
1582+
for (Map.Entry<QuiltPluginContext, List<TentativeLoadOption>> entry : pluginsToOptions.entrySet()) {
1583+
for (TentativeLoadOption option : entry.getValue()) {
1584+
LoadOption replacement = option.resolve();
1585+
if (replacement instanceof TentativeLoadOption) {
1586+
throw new IllegalStateException(
1587+
"The TentativeLoadOption " + option.getClass()
1588+
+ " resolved into another TentativeLoadOption " + replacement.getClass() + "!"
1589+
);
1590+
}
1591+
removeLoadOption((LoadOption) option);
1592+
addLoadOption(replacement, (BasePluginContext) entry.getKey());
1593+
}
15911594
}
15921595

15931596
return true;
@@ -1792,18 +1795,6 @@ private static void forceGcButBadly() {
17921795
System.gc();
17931796
}
17941797

1795-
// #########
1796-
// # Tasks #
1797-
// #########
1798-
1799-
<V> QuiltPluginTask<V> submit(BasePluginContext ctx, Callable<V> task) {
1800-
throw new AbstractMethodError("// TODO: Implement plugin tasks!");
1801-
}
1802-
1803-
<V> QuiltPluginTask<V> submitAfter(BasePluginContext ctx, Callable<V> task, QuiltPluginTask<?>... deps) {
1804-
throw new AbstractMethodError("// TODO: Implement plugin tasks!");
1805-
}
1806-
18071798
// ########
18081799
// # Mods #
18091800
// ########

0 commit comments

Comments
 (0)