Skip to content

Commit

Permalink
Add support for AsyncActions and BroadcastActions
Browse files Browse the repository at this point in the history
- Bump to 0.2.0 because it breaks some 0.1.0 apis
- AsyncAction: Runs up to 4 actions
  - StartAction (optional)
  - Action itself (async task) as well as the dispatcher logic for it
  - FailAction or SuccessAction

- BroadcastAction: explicitly mark an action as Component-only (default) or Broadcast through this marker interface:wq
  • Loading branch information
dvekeman committed Mar 22, 2019
1 parent 6671f57 commit e8eadad
Show file tree
Hide file tree
Showing 15 changed files with 212 additions and 95 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.MD
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog

## Version 0.1.3:
## Version 0.2.0:

- Support Async actions

Expand Down
11 changes: 10 additions & 1 deletion examples/example1-simple-counter/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,13 @@ Its layout has 5 components
- A PlusX component
- A MinusX component

This demostrates how to compose an application out of subcomponents: PlusX and MinusX are themselves MVU components holding their own state and containing their own actions.
This demostrates how to compose an application out of subcomponents: PlusX and MinusX are themselves MVU components holding their own state and containing their own actions.

## Notes

This example uses version 0.1.0

## TODO

[] More documentation on the example
[] Upgrade to 0.2.0 (or later)
10 changes: 9 additions & 1 deletion examples/example2-rest-binding/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,12 @@ For an introduction the MVU pattern for Vaadin, see my [vaadin-mvu][https://gith

## Example 2: Grid with REST binding

_NOTE_ This example in incomplete!
_NOTE_ This example in incomplete!

## Notes

This example uses version 0.2.0

## TODO

[] More documentation on the example
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import java.util.List;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Consumer;
import java.util.function.Function;

import com.vaadin.data.Binder;
Expand All @@ -16,8 +15,9 @@

import mvu.sample.model.Person;
import mvu.support.Action;
import mvu.support.BroadcastAction;
import mvu.support.Dispatcher;
import mvu.support.ModelViewBinder;
import mvu.support.SingletonDispatcher;
import mvu.support.extra.BoundGrid;
import mvu.support.extra.BoundLabel;

Expand Down Expand Up @@ -88,12 +88,12 @@ Model build() {
/* VIEW
/* ************************************************************************************************************** */

static Component view(Consumer<Action> mainUpdater) {
return ModelViewBinder.bindModelAndViewV2(SingletonDispatcher.wrap(mainUpdater), Model.initialModel(), HerosGrid::view, HerosGrid::update);
static Component view(Dispatcher mainUpdater) {
return ModelViewBinder.bindModelAndViewV2(mainUpdater, Model.initialModel(), HerosGrid::view, HerosGrid::update);
}


private static Component view(Binder<Model> binder, List<Consumer<Action>> dispatchers) {
private static Component view(Binder<Model> binder, Dispatcher dispatcher) {
VerticalLayout layout = new VerticalLayout();

Label info = new Label();
Expand All @@ -106,7 +106,7 @@ private static Component view(Binder<Model> binder, List<Consumer<Action>> dispa
+ "<br/>"
);

Component loadBar = LoadBar.view(dispatchers);
Component loadBar = LoadBar.view(dispatcher);

Grid<Person> herosGrid = BoundGrid.builder(binder, Person.class)
.withValueProvider(model -> model.heros)
Expand All @@ -131,15 +131,19 @@ private static Component view(Binder<Model> binder, List<Consumer<Action>> dispa
/* UPDATE
/* ************************************************************************************************************** */

static class HerosLoaded implements Action {
static class HerosLoading implements BroadcastAction {

}

static class HerosLoaded implements BroadcastAction {
private final List<Person> heros;

HerosLoaded(List<Person> heros) {
this.heros = heros;
}
}

static class LoadError implements Action {
static class LoadError implements BroadcastAction {
private final String error;

LoadError(String error) {
Expand All @@ -157,11 +161,11 @@ private static Model update(Action action, Model oldModel) {
return Model.copy(oldModel, oldModel.builder
.withStatus("Loading heros failed: " + ((LoadError) action).error)
);
// } else if (action instanceof LoadBar.LoadHeros) {
// return Model.copy(oldModel, oldModel.builder
// .withStatus("Loading...")
// .withHeros(new ArrayList<>())
// );
} else if (action instanceof HerosLoading) {
return Model.copy(oldModel, oldModel.builder
.withStatus("Loading...")
.withHeros(new ArrayList<>())
);
} else {
return oldModel;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import com.vaadin.data.Binder;
Expand All @@ -24,6 +23,7 @@
import mvu.support.Action;
import mvu.support.AsyncAction;
import mvu.support.AsyncActionResult;
import mvu.support.Dispatcher;
import mvu.support.ModelViewBinder;
import mvu.support.extra.BoundTextField;
import mvu.support.extra.DispatchButton;
Expand Down Expand Up @@ -84,19 +84,19 @@ Model build() {
/* VIEW
/* ************************************************************************************************************** */

static Component view(List<Consumer<Action>> mainUpdater) {
return ModelViewBinder.bindModelAndViewV2(mainUpdater, Model.initialModel(), LoadBar::view, LoadBar::update);
static Component view(Dispatcher parentDispatcher) {
return ModelViewBinder.bindModelAndViewV2(parentDispatcher, Model.initialModel(), LoadBar::view, LoadBar::update);
}


private static Component view(Binder<Model> binder, List<Consumer<Action>> dispatchers) {
private static Component view(Binder<Model> binder, Dispatcher dispatcher) {
HorizontalLayout loadLayout = new HorizontalLayout();
TextField url = BoundTextField.builder(binder)
.withDispatchers(dispatchers)
.withDispatcher(dispatcher)
.withValueConsumer(SetUrl::new)
.withValueProvider(model -> model.url)
.build();
Button loadHeros = DispatchButton.builder(dispatchers)
Button loadHeros = DispatchButton.builder(dispatcher)
.withCaption("Load heros")
.withAction(() -> new LoadHeros(binder.getBean().url))
.build();
Expand All @@ -119,7 +119,7 @@ private static class SetUrl implements Action {
}
}

static class LoadHeros implements Action, AsyncAction<HerosGrid.LoadError, HerosGrid.HerosLoaded> {
static class LoadHeros implements Action, AsyncAction<HerosGrid.HerosLoading, HerosGrid.LoadError, HerosGrid.HerosLoaded> {
final String url;

LoadHeros(String url) {
Expand All @@ -130,6 +130,11 @@ static class LoadHeros implements Action, AsyncAction<HerosGrid.LoadError, Heros
public AsyncActionResult<HerosGrid.LoadError, HerosGrid.HerosLoaded> perform() {
return fetchHeros(this.url);
}

@Override
public HerosGrid.HerosLoading getStartAction() {
return new HerosGrid.HerosLoading();
}
}

private static Model update(Action action, Model oldModel) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package mvu.sample;

import java.util.function.Consumer;

import com.vaadin.data.Binder;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;

import mvu.support.Action;
import mvu.support.Dispatcher;
import mvu.support.ModelViewBinder;

class Main {
Expand Down Expand Up @@ -50,7 +49,7 @@ static Component view() {
return ModelViewBinder.bindModelAndView(initialModel, Main::view, Main::update);
}

private static Component view(Binder<MainModel> binder, Consumer<Action> dispatcher) {
private static Component view(Binder<MainModel> binder, Dispatcher dispatcher) {
HorizontalLayout layout = new HorizontalLayout();

layout.addComponent(HerosGrid.view(dispatcher));
Expand Down
12 changes: 11 additions & 1 deletion examples/example3-calculator/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,14 @@ Its layout has .. components

This gives you an idea how an MVP implementation (see [Vaadin _Advanced Application Architectures_][1]) would compare to an MVU implementation.

[1]: https://vaadin.com/docs/v8/framework/advanced/advanced-architecture.html
## Notes

This example uses version 0.1.0

## TODO

[] More documentation on the example
[] Upgrade to 0.2.0 (or later)

[1]: https://vaadin.com/docs/v8/framework/advanced/advanced-architecture.html

11 changes: 10 additions & 1 deletion examples/example4-combo/README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,13 @@ This will do a gradle build and start a Jetty server with the Vaadin application

Navigate to `http://localhost:8080/example4-combo`

This application combines some of the previous components and show how to compose applications out of individual components.
This application combines some of the previous components and show how to compose applications out of individual components.

## Notes

This example uses *version 0.1.0*

## TODO

[] More documentation on the example
[] Upgrade to 0.2.0 (or later)
4 changes: 3 additions & 1 deletion src/main/java/mvu/support/AsyncAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
/**
* Marker interface for Async Actions such as loading data from a remote backend.
*/
public interface AsyncAction<LEFTACTION extends Action, RIGHTACTION extends Action> extends Action {
public interface AsyncAction<STARTACTION extends Action, LEFTACTION extends Action, RIGHTACTION extends Action> extends Action {

AsyncActionResult<LEFTACTION, RIGHTACTION> perform();

STARTACTION getStartAction();

}
10 changes: 10 additions & 0 deletions src/main/java/mvu/support/BroadcastAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package mvu.support;

/**
*
* Marker interface for Actions which are broadcasted to all dispatchers
*
* Note: When applied to an AsyncAction, this means the async action will run for all dispatchers!
*
*/
public interface BroadcastAction extends Action {}
40 changes: 40 additions & 0 deletions src/main/java/mvu/support/Dispatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package mvu.support;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Dispatcher {

final List<Consumer<Action>> parentDispatchers;

final Consumer<Action> dispatcher;

public Dispatcher(Consumer<Action> dispatcher){
this(new ArrayList<>(), dispatcher);
}

public Dispatcher(List<Consumer<Action>> parentDispatchers, Consumer<Action> dispatcher){
this.parentDispatchers = parentDispatchers;
this.dispatcher = dispatcher;
}

public static Dispatcher empty() {
return new Dispatcher(new ArrayList<>(), action -> {});
}

public List<Consumer<Action>> getParentDispatchers() {
return parentDispatchers;
}

public Consumer<Action> getDispatcher() {
return dispatcher;
}

public List<Consumer<Action>> getAllDispatchers(){
List<Consumer<Action>> allDispatchers = new ArrayList<>();
allDispatchers.add(dispatcher);
allDispatchers.addAll(parentDispatchers);
return allDispatchers;
}
}
Loading

0 comments on commit e8eadad

Please sign in to comment.