Skip to content

Commit

Permalink
Merge pull request #13 from HgeX/di
Browse files Browse the repository at this point in the history
Use dependency injection framework
  • Loading branch information
adamtomi authored Dec 22, 2022
2 parents 2825fdc + 255baef commit 936102f
Show file tree
Hide file tree
Showing 40 changed files with 429 additions and 155 deletions.
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ version '0.0.10'
repositories {
mavenCentral()
}

dependencies {
implementation 'javax.inject:javax.inject:1'
implementation 'com.google.dagger:dagger:2.44.2'
annotationProcessor 'com.google.dagger:dagger-compiler:2.44.2'
}
93 changes: 93 additions & 0 deletions src/main/java/com/vamk/tbg/Bootstrap.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package com.vamk.tbg;

import com.vamk.tbg.command.CommandManager;
import com.vamk.tbg.config.Config;
import com.vamk.tbg.config.Keys;
import com.vamk.tbg.game.Game;
import com.vamk.tbg.game.GameState;
import com.vamk.tbg.ui.GameWindow;
import com.vamk.tbg.util.LogUtil;
import com.vamk.tbg.util.SerialUtil;

import javax.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;

public class Bootstrap {
private static final Logger LOGGER = LogUtil.getLogger(Bootstrap.class);
private final Config config;
private final Game game;
private final CommandManager cmdManager;
private final GameWindow window;

@Inject
public Bootstrap(Config config, Game game, CommandManager cmdManager, GameWindow.Factory windowFactory) {
this.config = config;
this.game = game;
this.cmdManager = cmdManager;
this.window = windowFactory.create(this::handleForceShutdown);
}

/**
* Tries to load the configuration. If that fails, exit.
* After that, register the command listener (if dev mode
* is enabled), then launch the game. Once the game loop
* finishes, dismantle the window and the command manager
* and exit.
*/
public void launch() {
try {
this.config.load();
} catch (Exception ex) {
LOGGER.severe("Failed to load configuration, exiting");
ex.printStackTrace();
System.exit(-1);
}

// Setup command listener on a separate thread
if (this.config.get(Keys.DEV_MODE)) CompletableFuture.runAsync(this.cmdManager::listen);

attemptRestore();
this.game.launch();
this.window.dispose();
this.cmdManager.stop();
}

/**
* Tries to read a previous game state from the configured
* file. If the file doesn't exist, return. Otherwise,
* load the state and import it into {@link this#game}.
*/
private void attemptRestore() {
File file = new File(this.config.get(Keys.BACKUP_LOCATION));
if (!file.exists()) return;

try {
GameState state = SerialUtil.readObject(GameState.class, file);
this.game.importState(state);
file.delete();
} catch (ClassNotFoundException | IOException ex) {
LOGGER.severe("Failed to read game state from file");
ex.printStackTrace();
}
}

/**
* This method will be called if the opened JFrame is closed.
* The current game state will be written to the configured
* file. If the file already exists, the contents of it
* will be replaced.
*/
private void handleForceShutdown() {
LOGGER.info("Force shutdown initiated, writing game state to file");
GameState state = this.game.exportState();
try {
SerialUtil.writeObject(state, new File(this.config.get(Keys.BACKUP_LOCATION)));
} catch (IOException ex) {
LOGGER.severe("Failed to write game state to file");
ex.printStackTrace();
}
}
}
96 changes: 4 additions & 92 deletions src/main/java/com/vamk/tbg/Main.java
Original file line number Diff line number Diff line change
@@ -1,100 +1,12 @@
package com.vamk.tbg;

import com.vamk.tbg.command.CommandManager;
import com.vamk.tbg.config.Config;
import com.vamk.tbg.config.Keys;
import com.vamk.tbg.game.Game;
import com.vamk.tbg.game.GameState;
import com.vamk.tbg.signal.SignalDispatcher;
import com.vamk.tbg.ui.GameWindow;
import com.vamk.tbg.util.LogUtil;
import com.vamk.tbg.util.SerialUtil;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Logger;
import com.vamk.tbg.di.DaggerGameComponent;
import com.vamk.tbg.di.GameComponent;

public class Main {

public static void main(String[] args) {
new Bootstrap().launch();
}

private static final class Bootstrap {
private static final Logger LOGGER = LogUtil.getLogger(Bootstrap.class);
private final Config config;
private final Game game;
private final GameWindow window;
private final CommandManager cmdManager;

private Bootstrap() {
SignalDispatcher dispatcher = new SignalDispatcher();
this.config = new Config();
this.game = new Game(dispatcher, this.config);
this.window = new GameWindow(dispatcher, this.config, this::handleForceShutdown);
this.cmdManager = new CommandManager(this.game);
}

/**
* Tries to load the configuration. If that fails, exit.
* After that, register the command listener (if dev mode
* is enabled), then launch the game. Once the game loop
* finishes, dismantle the window and the command manager
* and exit.
*/
private void launch() {
try {
this.config.load();
} catch (Exception ex) {
LOGGER.severe("Failed to load configuration, exiting");
ex.printStackTrace();
System.exit(-1);
}

// Setup command listener on a separate thread
if (this.config.get(Keys.DEV_MODE)) CompletableFuture.runAsync(this.cmdManager::listen);

attemptRestore();
this.game.launch();
this.window.dispose();
this.cmdManager.stop();
}

/**
* Tries to read a previous game state from the configured
* file. If the file doesn't exist, return. Otherwise,
* load the state and import it into {@link this#game}.
*/
private void attemptRestore() {
File file = new File(this.config.get(Keys.BACKUP_LOCATION));
if (!file.exists()) return;

try {
GameState state = SerialUtil.readObject(GameState.class, file);
this.game.importState(state);
file.delete();
} catch (ClassNotFoundException | IOException ex) {
LOGGER.severe("Failed to read game state from file");
ex.printStackTrace();
}
}

/**
* This method will be called if the opened JFrame is closed.
* The current game state will be written to the configured
* file. If the file already exists, the contents of it
* will be replaced.
*/
private void handleForceShutdown() {
LOGGER.info("Force shutdown initiated, writing game state to file");
GameState state = this.game.exportState();
try {
SerialUtil.writeObject(state, new File(this.config.get(Keys.BACKUP_LOCATION)));
} catch (IOException ex) {
LOGGER.severe("Failed to write game state to file");
ex.printStackTrace();
}
}
GameComponent component = DaggerGameComponent.create();
component.bootstrap().launch();
}
}
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/BuffMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.vamk.tbg.game.MoveContext;
import com.vamk.tbg.util.LogUtil;

import javax.inject.Inject;
import java.util.EnumSet;
import java.util.logging.Logger;

Expand All @@ -20,6 +21,7 @@ public class BuffMove extends AbstractBuffMove {
StatusEffect.REGENERATION, StatusEffect.LIFESTEAL, StatusEffect.CAFFEINATED
);

@Inject
public BuffMove(Config config) {
super("BUFF", false, config, Keys.BUFF_CHANCES, POTENTIAL_EFFECTS);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/CureMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
import com.vamk.tbg.game.MoveContext;
import com.vamk.tbg.util.LogUtil;

import javax.inject.Inject;
import java.util.logging.Logger;

public class CureMove extends AbstractMove {
private static final Logger LOGGER = LogUtil.getLogger(CureMove.class);

@Inject
public CureMove() {
super("CURE", false);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/DamageMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.vamk.tbg.util.LogUtil;
import com.vamk.tbg.util.RandomUtil;

import javax.inject.Inject;
import java.util.Map;
import java.util.logging.Logger;

Expand All @@ -20,6 +21,7 @@ public class DamageMove extends AbstractMove {
private static final Logger LOGGER = LogUtil.getLogger(DamageMove.class);
private final Config config;

@Inject
public DamageMove(Config config) {
super("DAMAGE", true);
this.config = config;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/DebuffMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.vamk.tbg.game.MoveContext;
import com.vamk.tbg.util.LogUtil;

import javax.inject.Inject;
import java.util.EnumSet;
import java.util.logging.Logger;

Expand All @@ -21,6 +22,7 @@ public class DebuffMove extends AbstractBuffMove {
StatusEffect.BLEEDING, StatusEffect.CONFUSED, StatusEffect.FROZEN
);

@Inject
public DebuffMove(Config config) {
super("DEBUFF", true, config, Keys.DEBUFF_CHANCES, POTENTIAL_EFFECTS);
}
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/HealAllMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.vamk.tbg.game.MoveContext;
import com.vamk.tbg.util.LogUtil;

import javax.inject.Inject;
import java.util.Map;
import java.util.logging.Logger;

Expand All @@ -18,6 +19,7 @@ public class HealAllMove extends AbstractMove {
private static final Logger LOGGER = LogUtil.getLogger(HealAllMove.class);
private final Config config;

@Inject
public HealAllMove(Config config) {
super("HEAL_ALL", false);
this.config = config;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/HealMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.vamk.tbg.util.LogUtil;
import com.vamk.tbg.util.RandomUtil;

import javax.inject.Inject;
import java.util.Map;
import java.util.logging.Logger;

Expand All @@ -18,6 +19,7 @@ public class HealMove extends AbstractMove {
private static final Logger LOGGER = LogUtil.getLogger(HealMove.class);
private final Config config;

@Inject
public HealMove(Config config) {
super("HEAL", false);
this.config = config;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/vamk/tbg/combat/SplashDamageMove.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.vamk.tbg.util.LogUtil;
import com.vamk.tbg.util.RandomUtil;

import javax.inject.Inject;
import java.util.Map;
import java.util.logging.Logger;

Expand All @@ -20,6 +21,7 @@ public class SplashDamageMove extends AbstractMove {
private static final Logger LOGGER = LogUtil.getLogger(SplashDamageMove.class);
private final Config config;

@Inject
public SplashDamageMove(Config config) {
super("SPLASH_DAMAGE", true);
this.config = config;
Expand Down
39 changes: 9 additions & 30 deletions src/main/java/com/vamk/tbg/command/CommandManager.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
package com.vamk.tbg.command;

import com.vamk.tbg.command.impl.DamageCommand;
import com.vamk.tbg.command.impl.HealCommand;
import com.vamk.tbg.command.impl.KillCommand;
import com.vamk.tbg.command.impl.ListCommand;
import com.vamk.tbg.command.impl.ListEffectsCommand;
import com.vamk.tbg.command.impl.ListMovesCommand;
import com.vamk.tbg.command.impl.RemoveEffectCommand;
import com.vamk.tbg.command.impl.SetEffectCommand;
import com.vamk.tbg.command.mapper.ArgumentMapper;
import com.vamk.tbg.command.mapper.EntityMapper;
import com.vamk.tbg.command.mapper.IntMapper;
import com.vamk.tbg.command.mapper.StatusEffectMapper;
import com.vamk.tbg.game.Game;
import com.vamk.tbg.di.qualifier.CommandSet;
import com.vamk.tbg.di.qualifier.MapperSet;
import com.vamk.tbg.util.CollectionUtil;
import com.vamk.tbg.util.LogFormatter;
import com.vamk.tbg.util.LogUtil;

import javax.inject.Inject;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.StringJoiner;
import java.util.logging.Logger;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -54,24 +46,11 @@ public class CommandManager {
/* This state will be changed by this#listen and this#stop */
private boolean listening;

public CommandManager(Game game) {
this.knownMappers = CollectionUtil.mapOf(
ArgumentMapper::type,
new EntityMapper(game),
new IntMapper(),
new StatusEffectMapper()
);
this.knownCommands = CollectionUtil.mapOf(
Command::getName,
new DamageCommand(),
new HealCommand(),
new KillCommand(),
new ListCommand(game),
new ListEffectsCommand(),
new ListMovesCommand(),
new RemoveEffectCommand(),
new SetEffectCommand()
);
@Inject
public CommandManager(@MapperSet Set<ArgumentMapper<?>> mappers,
@CommandSet Set<Command> commands) {
this.knownMappers = CollectionUtil.mapOf(ArgumentMapper::type, mappers);
this.knownCommands = CollectionUtil.mapOf(Command::getName, commands);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/main/java/com/vamk/tbg/command/impl/DamageCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
import com.vamk.tbg.command.CommandException;
import com.vamk.tbg.game.Entity;

import javax.inject.Inject;

public class DamageCommand extends Command {

@Inject
public DamageCommand() {
super(
"dmg",
Expand Down
Loading

0 comments on commit 936102f

Please sign in to comment.