Introduced AbstractTool

Introduced AbstractTool to take over some of the tool backend boilerplate code
This commit is contained in:
Collin Smith
2020-11-24 17:12:02 -08:00
parent 62dd6e3be6
commit a1ed24e688
5 changed files with 111 additions and 63 deletions

View File

@ -44,11 +44,11 @@ import com.riiablo.loader.PaletteLoader;
import com.riiablo.logger.LogManager; import com.riiablo.logger.LogManager;
import com.riiablo.logger.Logger; import com.riiablo.logger.Logger;
import com.riiablo.mpq.MPQFileHandleResolver; import com.riiablo.mpq.MPQFileHandleResolver;
import com.riiablo.tool.BaseTool;
import com.riiablo.tool.LwjglTool; import com.riiablo.tool.LwjglTool;
import com.riiablo.tool.Tool;
import com.riiablo.util.InstallationFinder; import com.riiablo.util.InstallationFinder;
public class FontMetricsTool extends BaseTool { public class FontMetricsTool extends Tool {
private static final Logger log = LogManager.getLogger(FontMetricsTool.class); private static final Logger log = LogManager.getLogger(FontMetricsTool.class);
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -96,12 +96,12 @@ import com.riiablo.logger.Logger;
import com.riiablo.map.DT1.Tile; import com.riiablo.map.DT1.Tile;
import com.riiablo.map.pfa.GraphPath; import com.riiablo.map.pfa.GraphPath;
import com.riiablo.mpq.MPQFileHandleResolver; import com.riiablo.mpq.MPQFileHandleResolver;
import com.riiablo.tool.BaseTool;
import com.riiablo.tool.LwjglTool; import com.riiablo.tool.LwjglTool;
import com.riiablo.tool.Tool;
import com.riiablo.util.DebugUtils; import com.riiablo.util.DebugUtils;
import com.riiablo.util.InstallationFinder; import com.riiablo.util.InstallationFinder;
public class MapViewer extends BaseTool { public class MapViewer extends Tool {
private static final Logger log = LogManager.getLogger(MapViewer.class); private static final Logger log = LogManager.getLogger(MapViewer.class);
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -0,0 +1,67 @@
package com.riiablo.tool;
import java.lang.reflect.Constructor;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.lang3.exception.ExceptionUtils;
import com.badlogic.gdx.Application;
public abstract class AbstractTool<A extends Application> {
public abstract static class ToolBuilder<
A extends Application,
T extends Tool,
C,
B extends ToolBuilder<A, T, C, B>
> {
protected final Class<T> toolClass;
protected final String cmd;
protected final String[] args;
protected final C config;
protected ToolBuilder(Class<T> toolClass, String cmd, String[] args, C config) {
this.toolClass = toolClass;
this.cmd = cmd;
this.args = args;
this.config = config;
}
public B defaults() {
return (B) this;
}
public B config(ToolConfigurator<C> configurator) {
configurator.config(config);
return (B) this;
}
public abstract A newInstance(T toolInstance, C config);
public A start() {
try {
Constructor<T> defaultConstructor = toolClass.getDeclaredConstructor();
defaultConstructor.setAccessible(true);
defaultConstructor.newInstance((Object[]) null);
T toolInstance = defaultConstructor.newInstance((Object[]) null);
Options options = new Options();
toolInstance.createCliOptions(options);
try {
CommandLine cli = toolInstance.parseCliOptions(options, args);
toolInstance.handleCliOptions(cmd, options, cli);
} catch (Throwable t) {
toolInstance.handleCliError(cmd, options, t);
return ExceptionUtils.wrapAndThrow(t);
}
return newInstance(toolInstance, config);
} catch (Throwable t) {
return ExceptionUtils.wrapAndThrow(t);
}
}
}
public interface ToolConfigurator<C> {
void config(C config);
}
}

View File

@ -1,50 +1,56 @@
package com.riiablo.tool; package com.riiablo.tool;
import java.lang.reflect.Constructor;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.lang3.exception.ExceptionUtils;
import com.badlogic.gdx.Files; import com.badlogic.gdx.Files;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication; import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration; import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
public class LwjglTool extends LwjglApplication { public class LwjglTool extends AbstractTool<LwjglApplication> {
LwjglTool(BaseTool tool, LwjglApplicationConfiguration config) { public static <T extends Tool>
super(tool, config); LwjglToolBuilder<T> create(
} Class<T> toolClass,
public static LwjglToolBuilder create(
Class<? extends BaseTool> toolClass,
String cmd, String cmd,
String[] args String[] args
) { ) {
return create(toolClass, cmd, args, new LwjglApplicationConfiguration()).defaults(); return create(toolClass, cmd, args, new LwjglApplicationConfiguration()).defaults();
} }
public static LwjglToolBuilder create( public static <T extends Tool>
Class<? extends BaseTool> toolClass, LwjglToolBuilder<T> create(
Class<T> toolClass,
String cmd, String cmd,
String[] args, String[] args,
LwjglApplicationConfiguration config LwjglApplicationConfiguration config
) { ) {
return new LwjglToolBuilder(toolClass, cmd, args, config); return new LwjglToolBuilder<>(toolClass, cmd, args, config);
} }
public static final class LwjglToolBuilder { public static final class LwjglToolBuilder<T extends Tool>
final Class<? extends BaseTool> toolClass; extends ToolBuilder<
final String cmd; LwjglApplication,
final String[] args; T,
final LwjglApplicationConfiguration config; LwjglApplicationConfiguration,
LwjglToolBuilder<T>
LwjglToolBuilder(Class<? extends BaseTool> toolClass, String cmd, String[] args, LwjglApplicationConfiguration config) { >
this.toolClass = toolClass; {
this.cmd = cmd; LwjglToolBuilder(
this.args = args; Class<T> toolClass,
this.config = config; String cmd,
String[] args,
LwjglApplicationConfiguration config
) {
super(toolClass, cmd, args, config);
} }
public LwjglToolBuilder defaults() { @Override
public LwjglApplication newInstance(
T toolInstance,
LwjglApplicationConfiguration config
) {
return new LwjglApplication(toolInstance, config);
}
@Override
public LwjglToolBuilder<T> defaults() {
config.title = toolClass.getSimpleName(); config.title = toolClass.getSimpleName();
config.width = 800; config.width = 800;
config.height = 600; config.height = 600;
@ -57,47 +63,22 @@ public class LwjglTool extends LwjglApplication {
return this; return this;
} }
public LwjglToolBuilder config(LwjglToolConfigurator configurator) { public LwjglToolBuilder<T> title(String title) {
configurator.config(config);
return this;
}
public LwjglToolBuilder title(String title) {
config.title = title; config.title = title;
return this; return this;
} }
public LwjglToolBuilder size(int width, int height) { public LwjglToolBuilder<T> size(int width, int height) {
config.width = width; config.width = width;
config.height = height; config.height = height;
return this; return this;
} }
public LwjglTool start() {
try {
Constructor<? extends BaseTool> defaultConstructor = toolClass.getDeclaredConstructor();
defaultConstructor.setAccessible(true);
defaultConstructor.newInstance((Object[]) null);
BaseTool toolInstance = defaultConstructor.newInstance((Object[]) null);
Options options = new Options();
toolInstance.createCliOptions(options);
try {
CommandLine cli = toolInstance.parseCliOptions(options, args);
toolInstance.handleCliOptions(cmd, options, cli);
} catch (Throwable t) {
toolInstance.handleCliError(cmd, options, t);
return ExceptionUtils.wrapAndThrow(t);
}
return new LwjglTool(toolInstance, config);
} catch (Throwable t) {
return ExceptionUtils.wrapAndThrow(t);
}
}
} }
public interface LwjglToolConfigurator { public interface LwjglToolConfigurator
extends ToolConfigurator<LwjglApplicationConfiguration>
{
@Override
void config(LwjglApplicationConfiguration config); void config(LwjglApplicationConfiguration config);
} }
} }

View File

@ -10,7 +10,7 @@ import org.apache.commons.cli.ParseException;
import com.badlogic.gdx.ApplicationListener; import com.badlogic.gdx.ApplicationListener;
public class BaseTool implements ApplicationListener { public class Tool implements ApplicationListener {
protected void createCliOptions(Options options) { protected void createCliOptions(Options options) {
options.addOption(Option.builder("h") options.addOption(Option.builder("h")
.longOpt("help") .longOpt("help")