Skip to content

Instantly share code, notes, and snippets.

@gervaisb
Created September 14, 2018 07:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gervaisb/b26ebfa8bdbd39e70b7d1e9d8226f90c to your computer and use it in GitHub Desktop.
Save gervaisb/b26ebfa8bdbd39e70b7d1e9d8226f90c to your computer and use it in GitHub Desktop.
class AppController {
public static void main(String[] args) {
new AppController(new AppModel(),
new ToDoView(new PrintWriter(System.out)),
new Scanner(System.in))
.start(Arrays.asList(args));
}
private final AppModel model;
private final ToDoView view;
private final Scanner input;
private AppController(AppModel model, ToDoView view, Scanner input) {
this.input = input;
this.model = model;
this.view = view;
}
private void start(List<String> args) {
if (args.contains("-register")) {
execute(new RegistrationController(view, input));
return;
}
if ( args.contains("-u") && args.size()==3 ) {
model.authenticate(args.get(1), args.get(2));
}
do {
if ( model.isAuthenticated() ) {
execute(new TasksController(view, input));
} else {
execute(new AuthenticationController(view, input));
}
} while ( model.getCurrentAction()!=QUIT);
}
private void execute(Consumer<AppModel> subsystem) {
subsystem.accept(model);
}
}
class TasksController implements Consumer<AppModel> {
private enum Menu implements ToDoView.MenuEntry<TasksController> {
List("List tasks", TasksController::list),
Add("Add task", TasksController::add),
Close("Complete task", TasksController::list),
Quit("Quit", (c, m) -> {/*nothing*/});
private final BiConsumer<TasksController, AppModel> code;
private final String label;
Menu(String label, BiConsumer<TasksController, AppModel> code) {
this.label = label;
this.code = code;
}
@Override
public String label() {
return label;
}
@Override
public void accept(TasksController ctrl, AppModel model) {
code.accept(ctrl, model);
}
}
private final ToDoView view;
private final Scanner input;
public TasksController(ToDoView view, Scanner input) {
this.input = input;
this.view = view;
}
@Override
public void accept(AppModel model) {
Menu selection = null;
do {
selection = view.menu(Menu.values(), input);
selection.accept(this, model);
} while (Menu.Quit!=selection);
}
private void list(AppModel model) {
model.getTasks().forEach(this::print);
}
private void print(Task task) {
view.text(format(" - %1$s", task.getTaskName()));
}
private void add(AppModel model) {
String name = view.read("Name", input);
model.add(new Task(name));
}
private void close(AppModel model) {
String name = view.read("Name", input);
model.findTaskByName(name)
.map(t -> {
model.complete(t);
return Void.TYPE;
})
.orElseGet(()->{
view.error(format("No tasks \"%1$s\" found.", name));
return Void.TYPE;
});
}
}
class ToDoView {
interface MenuEntry<T> extends BiConsumer<T, AppModel> {
String label();
}
private final PrintWriter output;
ToDoView(PrintWriter output) {
this.output = output;
}
String read(String label, Scanner in) {
in.reset();
output.printf(" | %1$s :", label).flush();
return in.nextLine();
}
void title(String text) {
output.printf("%n > %1$s%n", text)
.flush();
}
void text(String text) {
output.printf("%1$s%n", text).flush();
}
void error(String text) {
output.printf(" /!\\ %1$s%n", text).flush();
}
void info(String text) {
output.printf("[i] %1$s%n", text).flush();
}
<E extends MenuEntry> E menu(E[] menu, Scanner in) {
for (int i=0; i<menu.length; i++) {
output.printf(" %1$d - %2$s%n", i+1, menu[i].label());
}
output.flush();
int selection;
do {
// https://stackoverflow.com/a/13102066/1632752
selection = Integer.parseInt(in.nextLine())-1;
} while ( selection<0 || selection>menu.length);
return menu[selection];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment