Skip to content

Commit

Permalink
feat: FlowAdapter 增加
Browse files Browse the repository at this point in the history
  • Loading branch information
aqiu-alibaba committed Jun 8, 2021
1 parent 157df76 commit 12eb6fc
Show file tree
Hide file tree
Showing 30 changed files with 671 additions and 160 deletions.
1 change: 1 addition & 0 deletions example/.flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/linyunhe/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/linyunhe/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]}],"date_created":"2021-06-08 17:37:57.339650","version":"1.22.6-xianyu"}
17 changes: 17 additions & 0 deletions example/lib/todo_list_page/flow_adapter/adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';
import 'reducer.dart';
import 'connector.dart';

FlowAdapter<PageState> get adapter =>
FlowAdapter<PageState>(
reducer: buildReducer(),
view: (PageState state) =>
DependentArray<PageState>(
length: state.itemCount,
builder: (int index) {
return ToDoConnector(index: index) + ToDoComponent();
},
));
25 changes: 25 additions & 0 deletions example/lib/todo_list_page/flow_adapter/connector.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';

class ToDoConnector
extends ConnOp<PageState, ToDoState> {

ToDoConnector({this.index});

final int index;

@override
ToDoState get(PageState state) {
if (index >= state.toDos.length) {
return null;
}
return state.toDos[index];
}

@override
void set(PageState state, ToDoState subState) {
state.toDos[index] = subState;
}
}
25 changes: 25 additions & 0 deletions example/lib/todo_list_page/flow_adapter/reducer.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:fish_redux/fish_redux.dart';

import '../list_adapter/action.dart';
import '../state.dart';
import '../todo_component/action.dart' as todo_action;
import '../todo_component/component.dart';

Reducer<PageState> buildReducer() {
return asReducer(<Object, Reducer<PageState>>{
ToDoListAction.add: _add,
todo_action.ToDoAction.remove: _remove
});
}

PageState _add(PageState state, Action action) {
final ToDoState toDo = action.payload;
return state.clone()..toDos = (state.toDos.toList()..add(toDo));
}

PageState _remove(PageState state, Action action) {
final String unique = action.payload;
return state.clone()
..toDos = (state.toDos.toList()
..removeWhere((ToDoState state) => state.uniqueId == unique));
}
3 changes: 2 additions & 1 deletion example/lib/todo_list_page/page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:fish_redux/fish_redux.dart';

import 'effect.dart';
import 'list_adapter/adapter.dart';
import 'flow_adapter/adapter.dart';
import 'reducer.dart';
import 'report_component/component.dart';
import 'state.dart';
Expand All @@ -16,7 +17,7 @@ class ToDoListPage extends Page<PageState, Map<String, dynamic>> {
reducer: buildReducer(),
view: buildView,
dependencies: Dependencies<PageState>(
adapter: NoneConn<PageState>() + ToDoListAdapter(),
adapter: const NoneConn<PageState>() + adapter,//NoneConn<PageState>() + ToDoListAdapter(),
slots: <String, Dependent<PageState>>{
'report': ReportConnector() + ReportComponent()
}),
Expand Down
7 changes: 5 additions & 2 deletions example/lib/todo_list_page/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import '../global_store/state.dart';
import 'report_component/component.dart';
import 'todo_component/component.dart';

class PageState extends MutableSource
class PageState extends ItemListLike
implements GlobalBaseState, Cloneable<PageState> {
List<ToDoState> toDos;

Expand All @@ -29,7 +29,10 @@ class PageState extends MutableSource
int get itemCount => toDos?.length ?? 0;

@override
void setItemData(int index, Object data) => toDos[index] = data;
ItemListLike updateItemData(int index, Object data, bool isStateCopied) {
toDos[index] = data;
return this;
}
}

PageState initState(Map<String, dynamic> args) {
Expand Down
1 change: 1 addition & 0 deletions lib/fish_redux.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'src/extensions/extendsions.dart';
export 'src/redux/redux.dart';
export 'src/redux_adapter/redux_adapter.dart';
export 'src/redux_aop/redux_aop.dart';
Expand Down
128 changes: 128 additions & 0 deletions lib/src/extensions/adapter_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/foundation.dart';

import '../redux/basic.dart';
import '../redux_adapter/redux_adapter.dart';
import '../redux_component/redux_component.dart';
import '../redux_connector/redux_connector.dart';
import 'connector_extensions.dart';

class SimpleFlowAdapter<T> extends FlowAdapter<T> {
SimpleFlowAdapter({
@required FlowAdapterView<T> view,
ReducerFilter<T> filter,
Reducer<T> reducer,
Effect<T> effect,
@deprecated Object Function(T state) key,
}) : super(
view: view,
filter: filter,
reducer: reducer,
effect: effect,
key: key,
);

SimpleFlowAdapter.static({
@required List<Dependent<T>> children,
ReducerFilter<T> filter,
Reducer<T> reducer,
Effect<T> effect,
@deprecated Object Function(T state) key,
}) : this(
view: _buildByStatic(children),
filter: filter,
reducer: reducer,
effect: effect,
key: key,
);

SimpleFlowAdapter.dynamic({
@required Map<String, AbstractLogic<Object>> pool,
@required AbstractConnector<T, List<ItemBean>> connector,
ReducerFilter<T> filter,
Reducer<T> reducer,
Effect<T> effect,
@deprecated Object Function(T state) key,
}) : this(
view: _buildByDynamic(pool: pool, connector: connector),
filter: filter,
reducer: reducer,
effect: effect,
key: key,
);

SimpleFlowAdapter.listLike({
@required Map<String, AbstractLogic<Object>> pool,
@required AbstractConnector<T, MutableItemListLike> connector,
ReducerFilter<T> filter,
Reducer<T> reducer,
Effect<T> effect,
@deprecated Object Function(T state) key,
}) : this(
view: _buildByListLike(pool: pool, connector: connector),
filter: filter,
reducer: reducer,
effect: effect,
key: key,
);
}

FlowAdapterView<T> _buildByStatic<T>(List<Dependent<T>> children) {
return (T state) {
return DependentArray<T>.fromList(children
.where((Dependent<T> dep) => dep.subGetter(() => state).call() != null)
.toList());
};
}

FlowAdapterView<T> _buildByListLike<T>({
@required Map<String, AbstractLogic<Object>> pool,
@required AbstractConnector<T, MutableItemListLike> connector,
}) {
return (T state) {
final MutableItemListLike source = connector.get(state);
final DependentArray<T> depList = DependentArray<T>(
length: source.itemCount,
builder: (int index) {
final String type = source.getItemType(index);
final Dependent<T> dep = ConnHelper.join(
ConnHelper.to(
connector,
IndexedListLikeConn<MutableItemListLike>(index),
),
pool[type],
);
return dep;
},
);
return depList;
};
}

FlowAdapterView<T> _buildByDynamic<T>({
@required Map<String, AbstractLogic<Object>> pool,
@required AbstractConnector<T, List<ItemBean>> connector,
}) {
return (T state) {
final List<ItemBean> list = connector.get(state);
final DependentArray<T> depList = DependentArray<T>(
length: list.length,
builder: (int index) {
assert(index < list.length);
if (index < list.length) {
final ItemBean ib = list[index];
assert(ib != null);
return ConnHelper.join<T, Object>(
ConnHelper.to<T, List<ItemBean>, Object>(
connector,
IndexedListConn<ItemBean>(index),
),
pool[ib.type],
);
}
return null;
},
);
return depList;
};
}
44 changes: 44 additions & 0 deletions lib/src/extensions/component_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart' hide Action;

abstract class SimpleComponent<T> extends Component<T> {
SimpleComponent({
ReducerFilter<T> filter,
Dependencies<T> dependencies,
ShouldUpdate<T> shouldUpdate,
WidgetWrapper wrapper,
@deprecated Key Function(T) key,
bool clearOnDependenciesChanged = false,
}) : super(
view: null,
reducer: null,
effect: null,
filter: filter,
dependencies: dependencies,
shouldUpdate: shouldUpdate,
wrapper: wrapper,
key: key,
clearOnDependenciesChanged: clearOnDependenciesChanged,
);

@override
ViewBuilder<T> get protectedView => view;

@override
Reducer<T> get protectedReducer => reducer;

@override
Effect<T> get protectedEffect => effect;

Widget view(T state, Dispatch dispatch, ViewService viewService);

T reducer(T state, Action action) {
return state;
}

/// interrupted if not [false, null]
dynamic effect(Action action, Context<T> ctx) {
return true;
}
}
89 changes: 89 additions & 0 deletions lib/src/extensions/connector_extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:fish_redux/fish_redux.dart';

import '../redux/redux.dart';
import '../redux_component/basic.dart';
import '../redux_connector/redux_connector.dart';

mixin IndexedConnMixin<T, P> on AbstractConnector<T, P> {
P _cached;

int get index;

P getByIndex(T state, int index);

@override
P get(T state) {
final P newState = getByIndex(state, index);
return checkNextState(newState);
}

/// fix get 存在状态不同步
P checkNextState(Object newState) {
final Object lastState = _cached;
final Object nextState =
((newState is! P || newState.runtimeType != lastState.runtimeType)
? false
: (newState is StateKey ? newState.key() : null) ==
(lastState is StateKey ? lastState.key() : null))
? newState
: lastState;
return _cached = nextState;
}
}

abstract class ImmutableIndexedConn<T, P> extends ImmutableConn<T, P>
with ConnOpMixin<T, P>, IndexedConnMixin<T, P> {
@override
final int index;
ImmutableIndexedConn(this.index);

T setByIndex(T state, P subState, int index);

@override
T set(T state, P subState) => setByIndex(state, subState, index);
}

abstract class MutableIndexedConn<T, P> extends MutableConn<T, P>
with ConnOpMixin<T, P>, IndexedConnMixin<T, P> {
@override
final int index;
MutableIndexedConn(this.index);

void setByIndex(T state, P subState, int index);

@override
void set(T state, P subState) => setByIndex(state, subState, index);
}

///////////////////////////////////////////////////////////////////////////////
class IndexedListConn<P> extends MutableIndexedConn<List<P>, P>
with ConnOpMixin<List<P>, P>, IndexedConnMixin<List<P>, P> {
IndexedListConn(int index) : super(index);

@override
P getByIndex(List<P> state, int index) {
final P newState = state[index];
return checkNextState(newState);
}

@override
void setByIndex(List<P> state, Object subState, int index) {
state[index] = subState;
}
}

class IndexedListLikeConn<T extends MutableItemListLike>
extends MutableIndexedConn<T, Object> with ConnOpMixin<T, Object> {
IndexedListLikeConn(int index) : super(index);

@override
Object getByIndex(T state, int index) {
final Object newState = state.getItemData(index);
return checkNextState(newState);
}

@override
void setByIndex(T state, Object subState, int index) {
state.setItemData(index, subState);
}
}
3 changes: 3 additions & 0 deletions lib/src/extensions/extendsions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export 'adapter_extensions.dart';
export 'component_extensions.dart';
export 'connector_extensions.dart';
Loading

0 comments on commit 12eb6fc

Please sign in to comment.