From 78884719823fb73d268bf9767189e85e7f916e41 Mon Sep 17 00:00:00 2001 From: snowleo Date: Sun, 23 Oct 2011 21:45:01 +0200 Subject: Statemachine for installation wizard (WIP) --- .../essentials/update/states/AbstractState.java | 67 ++++++++++++ .../update/states/AbstractYesNoState.java | 49 +++++++++ .../essentials/update/states/EssentialsChat.java | 46 ++++++++ .../earth2me/essentials/update/states/Modules.java | 7 -- .../essentials/update/states/StateMachine.java | 118 +++++++++++++++++++++ 5 files changed, 280 insertions(+), 7 deletions(-) create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractYesNoState.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java delete mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java create mode 100644 EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java (limited to 'EssentialsUpdate/src/com/earth2me/essentials/update/states') diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java new file mode 100644 index 000000000..b217ebd4b --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractState.java @@ -0,0 +1,67 @@ +package com.earth2me.essentials.update.states; + +import com.earth2me.essentials.update.WorkListener; +import org.bukkit.entity.Player; + + +public abstract class AbstractState +{ + private transient boolean abortion = false; + + public abstract AbstractState getNextState(); + + /** + * Check if we already know the answer, so the user does not have to answer the question. + * + * @return true, if the answer could be guessed. + */ + public boolean guessAnswer() + { + return false; + } + + /** + * Ask the user the question. + * @param sender + */ + public abstract void askQuestion(Player sender); + + /** + * React on the answer and set internal variables + * @param answer + * @return true, if the answer could be recognized as a valid answer + */ + public abstract boolean reactOnAnswer(String answer); + + public final AbstractState reactOnAnswer(final Player sender, final String answer) + { + final String trimmedAnswer = answer.trim(); + if (trimmedAnswer.equalsIgnoreCase("quit") + || trimmedAnswer.equalsIgnoreCase("bye") + || trimmedAnswer.equalsIgnoreCase("abort")) + { + abortion = true; + return null; + } + final boolean found = reactOnAnswer(trimmedAnswer); + if (found) + { + return getNextState(); + } + else + { + sender.sendMessage("Answer not recognized."); + return this; + } + } + + /** + * Do something based on the answer, that the user gave. + */ + public abstract void doWork(WorkListener workListener); + + public boolean isAbortion() + { + return abortion; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractYesNoState.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractYesNoState.java new file mode 100644 index 000000000..67701c8db --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/AbstractYesNoState.java @@ -0,0 +1,49 @@ +package com.earth2me.essentials.update.states; + + +public abstract class AbstractYesNoState extends AbstractState +{ + private boolean answer = false; + private final transient AbstractState yesState; + private final transient AbstractState noState; + + public AbstractYesNoState(final AbstractState yesState, final AbstractState noState) + { + this.yesState = yesState; + this.noState = noState; + } + + @Override + public AbstractState getNextState() + { + return answer ? yesState : noState; + } + + @Override + public boolean reactOnAnswer(final String answer) + { + if (answer.equalsIgnoreCase("yes") + || answer.equalsIgnoreCase("y")) + { + this.answer = true; + return true; + } + if (answer.equalsIgnoreCase("no") + || answer.equalsIgnoreCase("n")) + { + this.answer = false; + return true; + } + return false; + } + + public boolean getAnswer() + { + return answer; + } + + protected void setAnswer(final boolean answer) + { + this.answer = answer; + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java new file mode 100644 index 000000000..6669161d4 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/EssentialsChat.java @@ -0,0 +1,46 @@ +package com.earth2me.essentials.update.states; + +import com.earth2me.essentials.update.WorkListener; +import com.earth2me.essentials.update.tasks.InstallChat; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + + +public class EssentialsChat extends AbstractYesNoState +{ + public EssentialsChat(final AbstractState next) + { + super(next, next); + } + + @Override + public boolean guessAnswer() + { + final Plugin plugin = Bukkit.getPluginManager().getPlugin("EssentialsChat"); + if (plugin != null) + { + setAnswer(true); + return true; + } + return false; + } + + @Override + public void askQuestion(final Player sender) + { + sender.sendMessage("Do you want to install EssentialsChat? (yes/no)"); + sender.sendMessage("Short descriptive text about what EssentialsChat does."); + } + + @Override + public void doWork(final WorkListener listener) + { + if (getAnswer()) + { + new InstallChat(listener).start(); + return; + } + listener.onWorkDone(); + } +} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java deleted file mode 100644 index 56d2445c9..000000000 --- a/EssentialsUpdate/src/com/earth2me/essentials/update/states/Modules.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.earth2me.essentials.update.states; - - -public class Modules -{ - -} diff --git a/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java new file mode 100644 index 000000000..b69ee14a9 --- /dev/null +++ b/EssentialsUpdate/src/com/earth2me/essentials/update/states/StateMachine.java @@ -0,0 +1,118 @@ +package com.earth2me.essentials.update.states; + +import com.earth2me.essentials.update.WorkListener; +import com.earth2me.essentials.update.VersionInfo; +import java.util.ArrayList; +import java.util.List; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + + +public class StateMachine extends WorkListener +{ + public enum MachineResult + { + ABORT, WAIT, DONE + } + private final transient List states = new ArrayList(); + private transient AbstractState current; + private final transient Player player; + + public StateMachine(final Plugin plugin, final Player player, final VersionInfo newVersionInfo) + { + super(plugin, newVersionInfo); + this.player = player; + states.clear(); + final AbstractState state = new EssentialsChat(null); + states.add(state); + current = state; + } + + public MachineResult askQuestion() + { + while (current.guessAnswer()) + { + current = current.getNextState(); + if (current == null) + { + return MachineResult.DONE; + } + } + current.askQuestion(player); + return MachineResult.WAIT; + } + + public MachineResult reactOnMessage(final String message) + { + final AbstractState next = current.reactOnAnswer(player, message); + if (next == null) + { + if (current.isAbortion()) + { + return MachineResult.ABORT; + } + else + { + return MachineResult.DONE; + } + } + current = next; + return askQuestion(); + } + private int position = 0; + + public void startWork() + { + callStateWork(); + } + + private void callStateWork() + { + if (position > states.size()) + { + if (player.isOnline()) + { + player.sendMessage("Installation done."); + } + return; + } + final AbstractState state = states.get(position); + state.doWork(this); + } + + @Override + public void onWorkAbort(final String message) + { + position = 0; + Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() + { + @Override + public void run() + { + if (message != null && !message.isEmpty() && StateMachine.this.player.isOnline()) + { + StateMachine.this.player.sendMessage(message); + } + } + }); + } + + @Override + public void onWorkDone(final String message) + { + position++; + Bukkit.getScheduler().scheduleSyncDelayedTask(getPlugin(), new Runnable() + { + @Override + public void run() + { + if (message != null && !message.isEmpty() && StateMachine.this.player.isOnline()) + { + StateMachine.this.player.sendMessage(message); + } + StateMachine.this.callStateWork(); + } + }); + } +} -- cgit v1.2.3