Skip to content

Commit

Permalink
Scenario lifecycle methods
Browse files Browse the repository at this point in the history
- Add ScenarioContext which knows about View and start/stop
  runnable methods.
- Change Catalog to rely on ScenarioContext and call
  start/stop on an appropriate moment.
- Still keep Scenario.build() around so that we have time
  to refactor in favour of ScenarioContext.buildContext()
  or whatever build() method in it should be.
- Fixes #1004
  • Loading branch information
jvalkeal committed Feb 16, 2024
1 parent d38d0d4 commit 7c91dbf
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 the original author or authors.
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -43,7 +43,6 @@
import org.springframework.shell.component.view.control.MenuView.MenuItemCheckStyle;
import org.springframework.shell.component.view.control.StatusBarView;
import org.springframework.shell.component.view.control.StatusBarView.StatusItem;
import org.springframework.shell.component.view.control.View;
import org.springframework.shell.component.view.control.cell.AbstractListCell;
import org.springframework.shell.component.view.event.EventLoop;
import org.springframework.shell.component.view.event.KeyEvent;
Expand All @@ -56,6 +55,7 @@
import org.springframework.shell.geom.Rectangle;
import org.springframework.shell.geom.VerticalAlign;
import org.springframework.shell.samples.catalog.scenario.Scenario;
import org.springframework.shell.samples.catalog.scenario.Scenario.ScenarioContext;
import org.springframework.shell.samples.catalog.scenario.ScenarioComponent;
import org.springframework.shell.style.ThemeResolver;
import org.springframework.util.ObjectUtils;
Expand All @@ -78,7 +78,7 @@ public class Catalog {

// mapping from category name to scenarios(can belong to multiple categories)
private final Map<String, List<ScenarioData>> categoryMap = new TreeMap<>();
private View currentScenarioView = null;
private ScenarioContext currentScenarioContext = null;
private TerminalUI ui;
private ListView<String> categories;
private ListView<ScenarioData> scenarios;
Expand Down Expand Up @@ -130,8 +130,9 @@ public void run() {
eventLoop.onDestroy(eventLoop.keyEvents()
.doOnNext(m -> {
if (m.getPlainKey() == Key.q && m.hasCtrl()) {
if (currentScenarioView != null) {
currentScenarioView = null;
if (currentScenarioContext != null) {
currentScenarioContext.stop();
currentScenarioContext = null;
ui.setRoot(app, true);
ui.setFocus(categories);
}
Expand Down Expand Up @@ -172,13 +173,11 @@ private AppView buildScenarioBrowser(EventLoop eventLoop, TerminalUI component)
// handle event when scenario is chosen
eventLoop.onDestroy(eventLoop.viewEvents(LISTVIEW_SCENARIO_TYPEREF, scenarios)
.subscribe(event -> {
View view = event.args().item().scenario().configure(ui).build();
ui.configure(view);
// View view = event.args().item().scenario()
// .configure(ui, eventLoop, themeResolver, activeThemeName)
// .build();
component.setRoot(view, true);
currentScenarioView = view;
ScenarioContext context = event.args().item().scenario().configure(ui).buildContext();
ui.configure(context.view());
component.setRoot(context.view(), true);
context.start();
currentScenarioContext = context;
}));


Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 the original author or authors.
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -54,6 +54,11 @@ protected TerminalUI getTerminalUI() {
return ui;
}

@Override
public View build() {
throw new UnsupportedOperationException("Need to implement via 'buildContext'");
}

@Override
public Scenario configure(TerminalUI ui) {
this.ui = ui;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 the original author or authors.
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,8 +15,10 @@
*/
package org.springframework.shell.samples.catalog.scenario;

import org.springframework.lang.Nullable;
import org.springframework.shell.component.view.TerminalUI;
import org.springframework.shell.component.view.control.View;
import org.springframework.shell.samples.catalog.Catalog;

/**
* {@link Scenario} participates in a catalog showcase.
Expand All @@ -28,17 +30,29 @@ public interface Scenario {
// Common category names
public static final String CATEGORY_ALL = "All Scenarios";
public static final String CATEGORY_LISTVIEW = "ListView";
public static final String CATEGORY_PROGRESSVIEW = "ProgressView";
public static final String CATEGORY_BOXVIEW = "BoxView";
public static final String CATEGORY_LAYOUT = "Layout";
public static final String CATEGORY_OTHER = "Other";

/**
* Build a {@link View} to be shown with a scenario.
* Build a {@link View} to be shown with a scenario. Prefer {@link #buildContext()}
* as this method will be deprecated and renamed.
*
* @return view of a scenario
* @see #buildContext()
*/
View build();

/**
* Build a {@link ScenarioContext} wrapping needed view and lifecycle methods.
*
* @return a scenario context
*/
default ScenarioContext buildContext() {
return ScenarioContext.of(build());
}

/**
* Configure scenario.
*
Expand All @@ -47,4 +61,78 @@ public interface Scenario {
*/
Scenario configure(TerminalUI ui);

/**
* Context represents a build {@code View} and lifecycle methods called by a
* catalog app.
*
* For simple {@link View} without any need for lifecycle methods, just call
* {@link #of(View)}.
*/
public interface ScenarioContext {

/**
* Get a view represented by a {@link Scenario}.
*
* @return a scenario view
*/
View view();

/**
* Called by a {@link Catalog} when its ready to show a {@link View} build from
* a {@link Scenario}.
*/
void start();

/**
* Called by a {@link Catalog} when its ready to discard a {@link View} build from
* a {@link Scenario}.
*/
void stop();

/**
* Utility method to build a {@code ScenarioContext} of {@link View} without
* lifecycle callbacks.
*
* @param view the main view
* @return a scenario context
*/
public static ScenarioContext of(View view) {
return of(view, null, null);
}

/**
* Utility method to build a {@code ScenarioContext}.
*
* @param view the main view
* @param start the start callback
* @param stop the stop callback
* @return a scenario context
*/
public static ScenarioContext of(View view, @Nullable Runnable start, @Nullable Runnable stop) {
return new ScenarioContext() {

@Override
public View view() {
return view;
}

@Override
public void start() {
if (start != null) {
start.run();
}
}

@Override
public void stop() {
if (stop != null) {
stop.run();
}
}

};
}

}

}

0 comments on commit 7c91dbf

Please sign in to comment.