Showing preview only (326K chars total). Download the full file or copy to clipboard to get everything.
Repository: izumin5210/Droidux
Branch: master
Commit: 8510117dae0a
Files: 183
Total size: 265.8 KB
Directory structure:
gitextract_k8nenrgu/
├── .gitignore
├── .travis.yml
├── LICENSE.md
├── README.md
├── build.gradle
├── droidux/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── main/
│ │ └── java/
│ │ └── info/
│ │ └── izumin/
│ │ └── android/
│ │ └── droidux/
│ │ ├── Action.java
│ │ ├── BaseStore.java
│ │ ├── Dispatcher.java
│ │ ├── History.java
│ │ ├── Middleware.java
│ │ ├── OnStateChangedListener.java
│ │ ├── StoreImpl.java
│ │ ├── UndoableState.java
│ │ ├── UndoableStoreImpl.java
│ │ ├── action/
│ │ │ ├── HistoryAction.java
│ │ │ ├── RedoAction.java
│ │ │ └── UndoAction.java
│ │ ├── annotation/
│ │ │ ├── Dispatchable.java
│ │ │ ├── Reducer.java
│ │ │ ├── Store.java
│ │ │ └── Undoable.java
│ │ └── exception/
│ │ └── NotInitializedException.java
│ └── test/
│ └── groovy/
│ └── info/
│ └── izumin/
│ └── android/
│ └── droidux/
│ ├── DispatcherTest.groovy
│ ├── HistoryTest.groovy
│ └── action/
│ └── HistoryActionTest.groovy
├── droidux-processor/
│ ├── .gitignore
│ ├── build.gradle
│ ├── libs/
│ │ └── databinding-library.jar
│ └── src/
│ ├── main/
│ │ └── java/
│ │ └── info/
│ │ └── izumin/
│ │ └── android/
│ │ └── droidux/
│ │ └── processor/
│ │ ├── AbstractProcessingStep.java
│ │ ├── DroiduxProcessor.java
│ │ ├── ReducerProcessingStep.java
│ │ ├── StoreProcessingStep.java
│ │ ├── exception/
│ │ │ ├── InvalidDispatchableDeclarationException.java
│ │ │ ├── InvalidReducerDeclarationException.java
│ │ │ └── InvalidStoreDelcarationException.java
│ │ ├── generator/
│ │ │ ├── StoreBuilderClassGenerator.java
│ │ │ ├── StoreClassGenerator.java
│ │ │ └── StoreImplClassGenerator.java
│ │ ├── model/
│ │ │ ├── BuilderModel.java
│ │ │ ├── DispatchableModel.java
│ │ │ ├── DispatcherModel.java
│ │ │ ├── ReducerModel.java
│ │ │ ├── StoreImplModel.java
│ │ │ ├── StoreMethodModel.java
│ │ │ └── StoreModel.java
│ │ ├── util/
│ │ │ ├── AnnotationUtils.java
│ │ │ ├── PoetUtils.java
│ │ │ └── StringUtils.java
│ │ └── validator/
│ │ ├── DispatchableValidator.java
│ │ ├── ReducerValidator.java
│ │ └── StoreValidator.java
│ └── test/
│ └── java/
│ └── info/
│ └── izumin/
│ └── android/
│ └── droidux/
│ └── processor/
│ ├── DroiduxProcessorTest.java
│ └── fixture/
│ ├── Counter.java
│ ├── CounterReducer.java
│ ├── Source.java
│ ├── TodoList.java
│ ├── TodoListReducer.java
│ └── action/
│ ├── AddTodoItemAction.java
│ ├── ClearCountAction.java
│ ├── CompleteTodoItemAction.java
│ ├── IncrementCountAction.java
│ ├── InitializeCountAction.java
│ └── SquareCountAction.java
├── examples/
│ ├── counter/
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── example/
│ │ │ └── counter/
│ │ │ ├── Counter.java
│ │ │ ├── CounterReducer.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MainEventHandlers.java
│ │ │ ├── RootStore.java
│ │ │ └── action/
│ │ │ ├── DecrementCountAction.java
│ │ │ └── IncrementCountAction.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── todomvc/
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── ApplicationTest.java
│ │ └── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── example/
│ │ │ └── todomvc/
│ │ │ ├── App.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MainActivityHelper.java
│ │ │ ├── RootStore.java
│ │ │ ├── TodoListAdapter.java
│ │ │ ├── action/
│ │ │ │ ├── AddTodoAction.java
│ │ │ │ ├── ClearCompletedTodoAction.java
│ │ │ │ ├── DeleteTodoAction.java
│ │ │ │ └── ToggleCompletedTodoAction.java
│ │ │ ├── entity/
│ │ │ │ └── TodoList.java
│ │ │ ├── middleware/
│ │ │ │ └── Logger.java
│ │ │ └── reducer/
│ │ │ └── TodoListReducer.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── list_item_todo.xml
│ │ ├── menu/
│ │ │ └── main_manu.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ ├── values-v21/
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ ├── todos-with-dagger/
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src/
│ │ ├── androidTest/
│ │ │ └── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── example/
│ │ │ └── todoswithdagger/
│ │ │ └── ApplicationTest.java
│ │ ├── main/
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java/
│ │ │ │ └── info/
│ │ │ │ └── izumin/
│ │ │ │ └── android/
│ │ │ │ └── droidux/
│ │ │ │ └── example/
│ │ │ │ └── todoswithdagger/
│ │ │ │ ├── App.java
│ │ │ │ ├── AppComponent.java
│ │ │ │ ├── AppModule.java
│ │ │ │ ├── RootStore.java
│ │ │ │ ├── action/
│ │ │ │ │ ├── AddTodoAction.java
│ │ │ │ │ ├── ClearCompletedTodoAction.java
│ │ │ │ │ ├── ClearNewTodoTextAction.java
│ │ │ │ │ ├── DeleteTodoAction.java
│ │ │ │ │ ├── ToggleCompletedTodoAction.java
│ │ │ │ │ └── UpdateNewTodoTextAction.java
│ │ │ │ ├── adapter/
│ │ │ │ │ └── TodoListAdapter.java
│ │ │ │ ├── entity/
│ │ │ │ │ └── TodoList.java
│ │ │ │ ├── module/
│ │ │ │ │ └── main/
│ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ ├── MainComponent.java
│ │ │ │ │ ├── MainEventHandlers.java
│ │ │ │ │ ├── MainModule.java
│ │ │ │ │ ├── MainPresenter.java
│ │ │ │ │ └── MainView.java
│ │ │ │ ├── reducer/
│ │ │ │ │ └── TodoListReducer.java
│ │ │ │ └── util/
│ │ │ │ └── ViewBindingUtils.java
│ │ │ └── res/
│ │ │ ├── layout/
│ │ │ │ ├── activity_main.xml
│ │ │ │ └── list_item_todo.xml
│ │ │ ├── menu/
│ │ │ │ └── main_manu.xml
│ │ │ ├── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ │ └── values-w820dp/
│ │ │ └── dimens.xml
│ │ └── test/
│ │ └── java/
│ │ └── info/
│ │ └── izumin/
│ │ └── android/
│ │ └── droidux/
│ │ └── example/
│ │ └── todoswithdagger/
│ │ └── ExampleUnitTest.java
│ └── todos-with-undo/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── info/
│ │ └── izumin/
│ │ └── android/
│ │ └── droidux/
│ │ └── example/
│ │ └── todoswithundo/
│ │ └── ApplicationTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── example/
│ │ │ └── todoswithundo/
│ │ │ ├── App.java
│ │ │ ├── MainActivity.java
│ │ │ ├── MainActivityHelper.java
│ │ │ ├── RootStore.java
│ │ │ ├── TodoListAdapter.java
│ │ │ ├── action/
│ │ │ │ ├── AddTodoAction.java
│ │ │ │ ├── ClearCompletedTodoAction.java
│ │ │ │ ├── DeleteTodoAction.java
│ │ │ │ └── ToggleCompletedTodoAction.java
│ │ │ ├── entity/
│ │ │ │ └── TodoList.java
│ │ │ ├── middleware/
│ │ │ │ └── Logger.java
│ │ │ └── reducer/
│ │ │ └── TodoListReducer.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ └── list_item_todo.xml
│ │ ├── menu/
│ │ │ └── main_manu.xml
│ │ ├── values/
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── values-w820dp/
│ │ └── dimens.xml
│ └── test/
│ └── java/
│ └── info/
│ └── izumin/
│ └── android/
│ └── droidux/
│ └── example/
│ └── todoswithundo/
│ └── ExampleUnitTest.java
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── middlewares/
│ └── droidux-thunk/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── info/
│ │ │ └── izumin/
│ │ │ └── android/
│ │ │ └── droidux/
│ │ │ └── thunk/
│ │ │ ├── AsyncAction.java
│ │ │ └── ThunkMiddleware.java
│ │ └── res/
│ │ └── values/
│ │ └── strings.xml
│ └── test/
│ └── groovy/
│ └── info/
│ └── izumin/
│ └── android/
│ └── droidux/
│ └── thunk/
│ └── ThunkMiddlewareTest.groovy
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io/api/android,intellij,gradle
### Android ###
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
### Android Patch ###
gen-external-apklibs
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Gradle ###
.gradle
build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
================================================
FILE: .travis.yml
================================================
language: android
jdk: oraclejdk8
android:
components:
- tools
- build-tools-27.0.3
- android-27
- extra-android-support
- extra-android-m2repository
licenses:
- 'android-sdk-preview-license-52d11cd2'
- 'android-sdk-license-.+'
- 'google-gdk-license-.+'
before_install:
- yes | sdkmanager "platforms;android-27"
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
script:
- ./gradlew --full-stacktrace -q test
================================================
FILE: LICENSE.md
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: HOW TO APPLY THE APACHE LICENSE TO YOUR WORK
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
```
Copyright 2015 izumin5210
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
================================================
FILE: README.md
================================================
# Droidux
[](https://travis-ci.org/izumin5210/Droidux)
[ ](https://bintray.com/izumin5210/maven/droidux/_latestVersion)
[](https://github.com/izumin5210/Droidux/blob/master/LICENSE.md)
[](http://android-arsenal.com/details/1/2892)
Droidux is "predictable state container" implementation, inspired by **[Redux][redux]**.
## Features
Droidux is influenced by [Three principles][three-principles] of Redux.
> * Single source of truth
> - The state of your whole application is stored in an object tree inside a single store.
> * State is read-only
> - The only way to mutate the state is to emit an action, an object describing what happened.
> * Mutations are written as pure functions
> - To specify how the state tree is transformed by actions, you write pure reducers.
>
> [Three Principles | Redux][three-principles]
Features of Droidux are following:
* All mutations can be observed via Flowable from [RxJava][rxjava]
* All mutations are automatically notified to views via [Data Binding][databinding]
### Data flow

see also: [Introduction to Redux // Speaker Deck](https://speakerdeck.com/axross/introduction-to-redux) (in Japanese)
## Installation
Droidux depends on [RxJava][rxjava] and [Data Binding][databinding].
Add to your project build.gradle file:
```groovy
apply plugin: 'com.android.application'
dependencies {
compile 'info.izumin.android:droidux:0.6.0'
compile 'io.reactivex.rxjava2:rxjava:2.1.8'
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
annotationProcessor 'info.izumin.android:droidux-processor:0.6.0'
}
```
And also you need to setup [Data Binding][databinding].
When you use `AsyncAction`, you need to add [droidux-thunk](https://github.com/izumin5210/Droidux/tree/master/middlewares/droidux-thunk).
```groovy
compile 'info.izumin.android:droidux-thunk:0.3.0'
```
## Usage
### Quick example
```java
/**
* This is a state class.
* It can be as simple as possible implementation, like POJO, or immutable object.
*/
public class Counter {
private final int count;
public Counter(int count) {
this.count = count;
}
public int getCount() {
return count;
}
}
/**
* This is a reducer class.
* It should be applied @Reducer annotation is given a state class as an argument.
* It describe whether the reducer should handle which actions.
*/
@Reducer(Counter.class)
public class CounterReducer {
/**
* This is a method to handle actions.
* It should be applied @Dispatchable annotation is given an action class as an parameter.
* It describe how to transform the state into the next state when dispatched actions.
* It should return the next state instance, and it is preferred instantiate the new state.
*
* This example handle IncrementCountAction,
+ and it returns new counter instance that state is incremented.
*/
@Dispatchable(IncrementCountAction.class)
public Counter increment(Counter state) {
return new Counter(state.getCount() + 1);
}
@Dispatchable(DecrementCountAction.class)
public Counter decrement(Counter state) {
return new Counter(state.getCount() - 1);
}
@Dispatchable(ClearCountAction.class)
public Counter clear() {
return new Counter(0);
}
}
/**
* This is a store interface.
* It should be applied @Store annotation and passing reducer classes as parameters.
* Droidux generates an implementation of getter method, observe method and dispatch method from user-defined interface.
*/
@Store(CounterReducer.class)
public interface CounterStore extends BaseStore {
Counter getCounter();
Flowable<Counter> observeCounter();
}
/**
* They are action classes. They should extend Action class.
*/
public class IncrementCountAction implements Action {}
public class DecrementCountAction implements Action {}
public class ClearCountAction implements Action {}
// Instantiate a Droidux store holding the state of your app.
// Its class is generated automatically from Reducer class.
//
// The instantiating should use Builder class,
// and it should register a reducer instance and an initial state.
//
// Its APIs in this example are following:
// - Flowable<Action> dispatch(Action action)
// - Flowable<Counter> observeCounter()
// - Counter getCounter()
CounterStore store = DroiduxCounterStore.builder()
.setReducer(new CounterReducer(), new Counter(0))
.build(); // Counter: 0
// You can observe to the updates using RxJava interface.
store.observe((counter) -> Log.d(TAG, counter.toString()));
// The only way to mutate the internal state is to dispatch an action.
store.dispatch(new IncrementCountAction()).subscribe(); // Counter: 1
store.dispatch(new IncrementCountAction()).subscribe(); // Counter: 2
store.dispatch(new IncrementCountAction()).subscribe(); // Counter: 3
store.dispatch(new DecrementCountAction()).subscribe(); // Counter: 2
store.dispatch(new ClearCountAction()).subscribe(); // Counter: 0
```
### Data Binding
```java
// If you use databinding, yor store interface must extend `android.databinding.Observable`.
@Store(CounterReducer.class)
public interface CounterStore extends BaseStore, android.databinding.Observable {
// You should annotate the getter method with @Bindable
@Bindable Counter getCounter();
}
CounterStore store = DroiduxCounterStore.builder()
// Pass the field id generated by DataBinding annotation processor.
.setReducer(new CounterReducer(), new Counter(0), BR.counter)
.build();
```
Layout file is following:
```xml
<layout>
<data>
<variable android:name="store" android:type="CounterStore" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@{store.counter}" />
</RelativeLayout>
</layout>
```
### Combined store
```java
@Store({CounterReducer.class, TodoListReducer.class})
class RootStore extends BaseStore {
Counter getCounter();
Flowable<Counter> observeCounter();
TodoList getTodoList();
Flowable<TodoList> observeTodoList();
}
RootStore store = DroiduxRootStore.builder()
.setReducer(new CounterReducer(), new Counter(0))
.setReducer(new TodoListReducer(), new TodoList())
.addMiddleware(new Logger())
.build();
store.dispatch(new IncrementCountAction()).subscribe(); // Counter: 1, Todo: 0
store.dispatch(new AddTodoAction("new task")).subscribe(); // Counter: 1, Todo: 1
```
### Middleware
```java
class Logger extends Middleware<CounterStore> {
@Override
public Flowable<Action> beforeDispatch(Action action) {
Log.d("[prev counter]", String.valueOf(getStore().count()));
Log.d("[action]", action.getClass().getSimpleName());
return Flowable.just(action);
}
@Override
public Flowable<Action> afterDispatch(Action action) {
Log.d("[next counter]", String.valueOf(getStore().count()));
return Flowable.just(action);
}
}
// Instantiate store class
CounterStore store = DroiduxCounterStore.builder()
.setReducer(new CounterReducer(), new Counter(0))
.addMiddleware(new Logger()) // apply logger middleware
.build(); // Counter: 0
store.dispatch(new IncrementCountAction()).subscribe();
// logcat:
// [prev counter]: 0
// [action]: IncrementCountAction
// [next counter]: 1
store.dispatch(new IncrementCountAction()).subscribe();
// logcat:
// [prev counter]: 1
// [action]: IncrementCountAction
// [next counter]: 2
store.dispatch(new ClearCountAction()).subscribe();
// logcat:
// [prev counter]: 2
// [action]: ClearCountAction
// [next counter]: 0
```
### Undo / Redo
```java
class TodoList extends ArrayList<TodoList.Todo> implements UndoableState<TodoList> {
@Override
public TodoList clone() {
// ...
}
public static Todo {
// ...
}
}
@Undoable
@Reducer(TodoList.class)
class TodoListReducer {
@Dispatchable(AddTodoAction.class)
public TodoList add(TodoList state, AddTodoAction action) {
// ...
}
@Dispatchable(CompleteTodoAction.class)
public TodoList complete(TodoList state, CompleteTodoAction action) {
// ...
}
}
@Store(TodoListReducer.class)
public interface TodoListStore {
TodoList todoList();
Flowable<TodoList> observeTodoList();
}
class AddTodoAction implements Action {
// ...
}
class CompleteTodoAction implements Action {
// ...
}
TodoListStore store = DroiduxTodoListStore.builder()
.setReducer(new TodoListReducer(), new TodoList())
.build();
store.dispatch(new AddTodoAction("item 1")).subscribe(); // ["item 1"]
store.dispatch(new AddTodoAction("item 2")).subscribe(); // ["item 1", "item 2"]
store.dispatch(new AddTodoAction("item 3")).subscribe(); // ["item 1", "item 2", "item 3"]
store.dispatch(new CompleteTodoAction("item 2")).subscribe(); // ["item 1", "item 3"]
store.dispatch(new AddTodoAction("item 4")).subscribe(); // ["item 1", "item 3", "item 4"]
store.dispatch(new UndoAction(TodoList.class)).subscribe();
// => ["item 1", "item 3"]
store.dispatch(new UndoAction(TodoList.class)).subscribe();
// => ["item 1", "item 2", "item 3"]
store.dispatch(new RedoAction(TodoList.class)).subscribe();
// => ["item 1", "item 3"]
```
### Async action
Use [droidux-thunk](https://github.com/izumin5210/Droidux/tree/master/middlewares/droidux-thunk).
```java
class FetchTodoListAction implements AsyncAction {
private final TodoListApi client;
public FetchTodoListAction(TodoListApi client) {
this.client = client;
}
public Flowable<ReceiveTodoListAction> call(Dispatcher dispatcher) {
return dispatcher.dispatch(new DoingFetchAction())
.flatMap(_action -> client.fetch())
.map(todoList -> {
this.todoList = todoList;
return new ReceiveTodoListAction(todoList);
});
}
}
class ReceiveTodoListAction implements Action {
private final TodoList todoList;
public ReceiveTodoListAction(TodoList todoList) {
this.todoList = todoList;
}
public TodoList getTodoList() {
return todoList;
}
}
TodoListStore store = DroiduxTodoListStore.builder()
.setReducer(new TodoListReducer(), new TodoList())
.addMiddleware(new ThunkMiddleware())
.build();
store.dispatch(new FetchTodoListAction(client)).subscribe();
```
## Examples
* [Counter](https://github.com/izumin5210/Droidux/tree/master/examples/counter)
* [TodoMVC](https://github.com/izumin5210/Droidux/tree/master/examples/todomvc)
* [Todos with Undo](https://github.com/izumin5210/Droidux/tree/master/examples/todos-with-undo)
* [Todos with Dagger 2](https://github.com/izumin5210/Droidux/tree/master/examples/todos-with-dagger)
## License
```
Copyright 2015 izumin5210
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```
[redux]: https://github.com/reactjs/redux
[rxjava]: https://github.com/ReactiveX/RxJava
[three-principles]: http://redux.js.org/docs/introduction/ThreePrinciples.html
[databinding]: http://developer.android.com/tools/data-binding/guide.html
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
maven { url "https://jitpack.io" }
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.novoda:bintray-release:0.3.4'
classpath 'com.github.groovy:groovy-android-gradle-plugin:1b77dd6763'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
google()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
ext {
def versionMajor = 0
def versionMinor = 6
def versionPatch = 0
versionName = "${versionMajor}.${versionMinor}.${versionPatch}"
compileSdkVersion = 27
buildToolsVersion = '27.0.3'
minSdkVersion = 15
targetSdkVersion = compileSdkVersion
databindingBaseLibraryVersion = '1.0'
databindingLibraryVersion = '1.0-rc3'
supportLibrariesVersion = '23.1.1'
rxJava2Version = '2.1.8'
rxAndroid2Version = '2.0.1'
spockCoreVersion = '1.0-groovy-2.4'
cglibVersion = '2.2'
}
================================================
FILE: droidux/.gitignore
================================================
/build
================================================
FILE: droidux/build.gradle
================================================
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'com.novoda.bintray-release'
targetCompatibility = JavaVersion.VERSION_1_7
sourceCompatibility = JavaVersion.VERSION_1_7
dependencies {
compile "io.reactivex.rxjava2:rxjava:${project.rxJava2Version}"
testCompile "org.spockframework:spock-core:${project.spockCoreVersion}"
testCompile "cglib:cglib-nodep:${project.cglibVersion}"
}
publish {
userOrg = project_bintray_org
groupId = project_group
artifactId = 'droidux'
version = project.versionName
description = '"Predictable state container" implementation, inspired by Redux for JS.'
website = project_url
}
================================================
FILE: droidux/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
-dontwarn android.databinding.**
-dontwarn java.lang.invoke.*
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/Action.java
================================================
package info.izumin.android.droidux;
/**
* Created by izumin on 11/2/15.
*/
public interface Action {
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/BaseStore.java
================================================
package info.izumin.android.droidux;
import io.reactivex.Flowable;
import io.reactivex.Single;
/**
* Created by izumin on 12/6/15.
*/
public interface BaseStore {
Flowable<Action> dispatch(Action action);
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/Dispatcher.java
================================================
package info.izumin.android.droidux;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import io.reactivex.Flowable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
/**
* Created by izumin on 11/28/15.
*/
public class Dispatcher {
public static final String TAG = Dispatcher.class.getSimpleName();
private final List<Middleware> middlewares;
private final List<StoreImpl> storeImpls;
public Dispatcher(List<Middleware> middlewares, StoreImpl... storeImpls) {
this.middlewares = middlewares;
this.storeImpls = Arrays.asList(storeImpls);
}
public Flowable<Action> dispatch(Action action) {
return Flowable.just(action)
.flatMap(new Function<Action, Flowable<? extends Action>>() {
@Override
public Flowable<? extends Action> apply(Action action) throws Exception {
return applyMiddlewaresBeforeDispatch(action);
}
}).doOnNext(new Consumer<Action>() {
@Override
public void accept(Action action) throws Exception {
for (StoreImpl store : storeImpls) {
store.dispatch(action);
}
}
})
.flatMap(new Function<Action, Flowable<? extends Action>>() {
@Override
public Flowable<? extends Action> apply(Action action) throws Exception {
return applyMiddlewaresAfterDispatch(action);
}
});
}
private Flowable<Action> applyMiddlewaresBeforeDispatch(Action action) {
Flowable<Action> o = Flowable.just(action);
for (final Middleware<?> mw : middlewares) {
o = o.flatMap(new Function<Action, Flowable<? extends Action>>() {
@Override
public Flowable<Action> apply(Action a) throws Exception {
return mw.beforeDispatch(a);
}
});
}
return o;
}
private Flowable<Action> applyMiddlewaresAfterDispatch(Action action) {
Flowable<Action> o = Flowable.just(action);
ListIterator<Middleware> iterator = middlewares.listIterator(middlewares.size());
while(iterator.hasPrevious()) {
final Middleware<?> mw = iterator.previous();
o = o.flatMap(new Function<Action, Flowable<? extends Action>>() {
@Override
public Flowable<Action> apply(Action a) throws Exception {
return mw.afterDispatch(a);
}
});
}
return o;
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/History.java
================================================
package info.izumin.android.droidux;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* Created by izumin on 11/23/15.
*/
public class History<T extends UndoableState<T>> {
public static final String TAG = History.class.getSimpleName();
private static final int DEFAULT_LIMIT = 100;
private final Deque<T> past;
private final Deque<T> future;
private T present;
private int limit = DEFAULT_LIMIT;
public History(T initialState) {
past = new ArrayDeque<>();
future = new ArrayDeque<>();
present = initialState;
}
public T getPresent() {
return present;
}
public void insert(T state) {
past.addFirst(present);
if (past.size() > limit) {
past.removeLast();
}
future.clear();
present = state;
}
public T undo() {
if (isUndoable()) {
future.addFirst(present);
present = past.removeFirst();
}
return present;
}
public T redo() {
if (isRedoable()) {
past.addFirst(present);
present = future.removeFirst();
}
return present;
}
public boolean isUndoable() {
return past.size() > 0;
}
public boolean isRedoable() {
return future.size() > 0;
}
public void setLimit(int limit) {
this.limit = limit;
while (past.size() > limit) { past.removeLast(); }
while (future.size() > limit) { future.removeLast(); }
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/Middleware.java
================================================
package info.izumin.android.droidux;
import io.reactivex.Flowable;
/**
* Created by izumin on 11/2/15.
*/
public abstract class Middleware<S extends BaseStore> {
public static final String TAG = Middleware.class.getSimpleName();
private S store;
private Dispatcher dispatcher;
public void onAttach(S store, Dispatcher dispatcher) {
this.store = store;
this.dispatcher = dispatcher;
}
protected S getStore() {
return store;
}
protected Dispatcher getDispatcher() {
return dispatcher;
}
public abstract Flowable<Action> beforeDispatch(Action action);
public abstract Flowable<Action> afterDispatch(Action action);
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/OnStateChangedListener.java
================================================
package info.izumin.android.droidux;
/**
* Created by izumin on 12/6/15.
*/
public interface OnStateChangedListener<T> {
void onStateChanged(T state);
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/StoreImpl.java
================================================
package info.izumin.android.droidux;
import java.util.HashSet;
import java.util.Set;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.subjects.BehaviorSubject;
/**
* Created by izumin on 11/2/15.
*/
public abstract class StoreImpl<T, R> {
public static final String TAG = StoreImpl.class.getSimpleName();
private final BehaviorSubject<T> subject;
private T state;
private final R reducer;
private final Set<OnStateChangedListener<T>> listeners;
protected StoreImpl(T state, R reducer) {
this.state = state;
this.reducer = reducer;
subject = BehaviorSubject.create();
listeners = new HashSet<>();
}
public Flowable<T> observe() {
return observe(BackpressureStrategy.DROP);
}
public Flowable<T> observe(BackpressureStrategy strategy) {
return subject.toFlowable(strategy);
}
public T getState() {
return state;
}
protected void setState(T state) {
this.state = state;
subject.onNext(state);
for (OnStateChangedListener<T> listener : listeners) {
listener.onStateChanged(state);
}
}
protected R getReducer() {
return reducer;
}
public void addListener(OnStateChangedListener<T> listener) {
listeners.add(listener);
}
protected abstract void dispatch(Action action);
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/UndoableState.java
================================================
package info.izumin.android.droidux;
/**
* Created by izumin on 11/24/15.
*/
public interface UndoableState<T> extends Cloneable {
T clone();
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/UndoableStoreImpl.java
================================================
package info.izumin.android.droidux;
import info.izumin.android.droidux.action.HistoryAction;
/**
* Created by izumin on 11/25/15.
*/
public abstract class UndoableStoreImpl<T extends UndoableState<T>, R> extends StoreImpl<T, R> {
public static final String TAG = UndoableStoreImpl.class.getSimpleName();
private final History<T> history;
protected UndoableStoreImpl(T state, R reducer) {
super(state, reducer);
history = new History<>(state);
}
@Override
protected void dispatch(Action action) {
if (HistoryAction.class.isAssignableFrom(action.getClass())) {
HistoryAction historyAction = (HistoryAction) action;
if (((HistoryAction) action).isAssignableTo(getReducer())) {
setStateWithoutKeepingHistory(historyAction.handle(history));
}
}
}
protected void setStateWithoutKeepingHistory(T state) {
super.setState(state);
}
@Override
protected void setState(T state) {
history.insert(state);
super.setState(state);
}
@Override
public T getState() {
return history.getPresent();
}
public History<T> getHistory() {
return history;
}
public boolean isUndoable() {
return history.isUndoable();
}
public boolean isRedoable() {
return history.isRedoable();
}
public void setLimit(int limit) {
history.setLimit(limit);
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/action/HistoryAction.java
================================================
package info.izumin.android.droidux.action;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import info.izumin.android.droidux.Action;
import info.izumin.android.droidux.History;
import info.izumin.android.droidux.UndoableState;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Undoable;
/**
* Created by izumin on 11/24/15.
*/
public class HistoryAction implements Action {
public static final String TAG = HistoryAction.class.getSimpleName();
enum Kind {
UNDO {
@Override
<T extends UndoableState<T>> T handle(History<T> history) {
return history.undo();
}
},
REDO {
@Override
<T extends UndoableState<T>> T handle(History<T> history) {
return history.redo();
}
};
abstract <T extends UndoableState<T>> T handle(History<T> history);
}
private final Kind kind;
private final Class targetReducerType;
public HistoryAction(Kind kind, Class targetReducerType) {
for (Class<? extends Annotation> annotationType : getNecessaryAnnotationTypes()) {
if (targetReducerType.getAnnotation(annotationType) == null) {
throw new IllegalArgumentException();
}
}
this.kind = kind;
this.targetReducerType = targetReducerType;
}
public <R> boolean isAssignableTo(R reducer) {
return targetReducerType.equals(reducer.getClass());
}
public <T extends UndoableState<T>> T handle(History<T> history) {
return kind.handle(history);
}
protected Set<Class<? extends Annotation>> getNecessaryAnnotationTypes() {
return new HashSet<Class<? extends Annotation>>() {{
add(Reducer.class);
add(Undoable.class);
}};
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/action/RedoAction.java
================================================
package info.izumin.android.droidux.action;
/**
* Created by izumin on 11/24/15.
*/
public class RedoAction extends HistoryAction {
public static final String TAG = RedoAction.class.getSimpleName();
public RedoAction(Class targetReducerType) {
super(Kind.REDO, targetReducerType);
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/action/UndoAction.java
================================================
package info.izumin.android.droidux.action;
/**
* Created by izumin on 11/24/15.
*/
public class UndoAction extends HistoryAction {
public static final String TAG = UndoAction.class.getSimpleName();
public UndoAction(Class targetReducerType) {
super(Kind.UNDO, targetReducerType);
}
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/annotation/Dispatchable.java
================================================
package info.izumin.android.droidux.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by izumin on 11/2/15.
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD)
public @interface Dispatchable {
Class<?> value();
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/annotation/Reducer.java
================================================
package info.izumin.android.droidux.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by izumin on 11/2/15.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Reducer {
Class<?> value();
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/annotation/Store.java
================================================
package info.izumin.android.droidux.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by izumin on 11/2/15.
*/
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Store {
Class<?>[] value() default {};
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/annotation/Undoable.java
================================================
package info.izumin.android.droidux.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Created by izumin on 11/23/15.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Undoable {
}
================================================
FILE: droidux/src/main/java/info/izumin/android/droidux/exception/NotInitializedException.java
================================================
package info.izumin.android.droidux.exception;
/**
* Created by izumin on 11/8/15.
*/
public class NotInitializedException extends RuntimeException {
public NotInitializedException(String message) {
super(message);
}
}
================================================
FILE: droidux/src/test/groovy/info/izumin/android/droidux/DispatcherTest.groovy
================================================
package info.izumin.android.droidux
import io.reactivex.Flowable
import spock.lang.Specification
/**
* Created by izumin on 11/24/15.
*/
class DispatcherTest extends Specification {
def store1
def store2
def middleware1
def middleware2
def action
def dispatcher
def setup() {
store1 = Mock(StoreImpl.class, constructorArgs: [null, null])
store2 = Mock(StoreImpl.class, constructorArgs: [null, null])
middleware1 = Mock(Middleware.class)
middleware2 = Mock(Middleware.class)
action = Mock(Action.class)
def middlewares = new ArrayList<Middleware>()
middlewares.add(middleware1)
middlewares.add(middleware2)
dispatcher = new Dispatcher(middlewares, store1, store2)
}
def "#dispatch()"() {
when:
dispatcher.dispatch(action).subscribe()
then:
1 * middleware1.beforeDispatch(action) >> Flowable.just(action)
then:
1 * middleware2.beforeDispatch(action) >> Flowable.just(action)
then:
1 * store1.dispatch(action)
then:
1 * store2.dispatch(action)
then:
1 * middleware2.afterDispatch(action) >> Flowable.just(action)
then:
1 * middleware1.afterDispatch(action) >> Flowable.just(action)
}
}
================================================
FILE: droidux/src/test/groovy/info/izumin/android/droidux/HistoryTest.groovy
================================================
package info.izumin.android.droidux
import spock.lang.Specification;
/**
* Created by izumin on new Counter(1)new Counter(1)/new Counter(2)new Counter(4)/new Counter(1)new Counter(5).
*/
class HistoryTest extends Specification {
def history
def past
def future
static class Counter implements UndoableState<Counter> {
def count
Counter(count) {
this.count = count
}
@Override
boolean equals(Object o) {
return (o instanceof Counter) && (o.hashCode() == hashCode())
}
@Override
int hashCode() {
return count
}
@Override
Counter clone() {
return new Counter(count)
}
}
def setup() {
history = new History<Counter>(new Counter(0))
past = History.metaClass.getAttribute(history, "past")
future = History.metaClass.getAttribute(history, "future")
}
def getPresent() {
History.metaClass.getAttribute(history, "present")
}
def "#insert()"() {
when:
history.insert(new Counter(1))
then:
getPresent() == new Counter(1)
when:
history.insert(new Counter(3))
then:
getPresent() == new Counter(3)
}
def "#undo()"() {
when:
history.insert(new Counter(1))
then:
past.size() == 1
history.undo() == new Counter(0)
past.size() == 0
when:
history.insert(new Counter(3))
history.insert(new Counter(5))
then:
past.size() == 2
history.undo() == new Counter(3)
past.size() == 1
history.undo() == new Counter(0)
past.size() == 0
history.undo() == new Counter(0)
}
def "#redo()"() {
when:
history.insert(new Counter(1))
history.undo()
then:
future.size() == 1
history.redo() == new Counter(1)
future.size() == 0
when:
history.insert(new Counter(3))
history.insert(new Counter(5))
history.undo()
history.undo()
then:
future.size() == 2
history.redo() == new Counter(3)
future.size() == 1
history.redo() == new Counter(5)
future.size() == 0
history.redo() == new Counter(5)
when:
history.insert(new Counter(8))
history.insert(new Counter(7))
history.undo()
history.undo()
then:
future.size() == 2
history.insert(new Counter(4))
future.size() == 0
}
def "#setLimit()"() {
when:
history.setLimit(3)
history.insert(new Counter(1))
then:
past.size() == 1
when:
history.insert(new Counter(2))
then:
past.size() == 2
when:
history.insert(new Counter(3))
then:
past.size() == 3
when:
history.insert(new Counter(4))
then:
past.size() == 3
history.undo() == new Counter(3)
history.undo() == new Counter(2)
history.undo() == new Counter(1)
history.undo() == new Counter(1)
when:
history.insert(new Counter(7))
history.insert(new Counter(8))
history.insert(new Counter(6))
history.insert(new Counter(5))
then:
past.size() == 3
history.setLimit(2)
past.size() == 2
history.undo() == new Counter(6)
history.undo() == new Counter(8)
history.undo() == new Counter(8)
}
}
================================================
FILE: droidux/src/test/groovy/info/izumin/android/droidux/action/HistoryActionTest.groovy
================================================
package info.izumin.android.droidux.action
import info.izumin.android.droidux.UndoableState
import info.izumin.android.droidux.annotation.Reducer
import info.izumin.android.droidux.annotation.Undoable
import spock.lang.Specification
/**
* Created by izumin on 12/5/15.
*/
class HistoryActionTest extends Specification {
class Counter implements UndoableState<Counter> {
@Override Counter clone() {
return new Counter()
}
}
class SubUndoableDummyReducer extends UndoableDummyReducer {}
@Undoable @Reducer(Counter.class)
class UndoableDummyReducer {}
@Reducer(String.class)
class DummyReducer {}
class DummyClass {}
def "when pass the class annotated with @Reducer and @Undoable to the constructor"() {
when:
new HistoryAction(HistoryAction.Kind.UNDO, UndoableDummyReducer.class)
then:
noExceptionThrown()
}
def "when pass the class is not annotated with @Reducer to the constructor"() {
when:
new HistoryAction(HistoryAction.Kind.UNDO, DummyReducer.class)
then:
thrown(IllegalArgumentException.class)
}
def "when pass the class that has no annotations to the constructor"() {
when:
new HistoryAction(HistoryAction.Kind.UNDO, DummyClass.class)
then:
thrown(IllegalArgumentException.class)
}
def "isAssignableTo()"() {
setup:
def action = new HistoryAction(HistoryAction.Kind.UNDO, UndoableDummyReducer.class)
expect:
action.isAssignableTo(reducer) == result
where:
reducer | result
new UndoableDummyReducer() | true
new Object() | false
new DummyReducer() | false
new SubUndoableDummyReducer() | false
}
}
================================================
FILE: droidux-processor/.gitignore
================================================
/build
================================================
FILE: droidux-processor/build.gradle
================================================
import org.gradle.internal.jvm.Jvm
apply plugin: 'java'
apply plugin: 'com.novoda.bintray-release'
targetCompatibility = JavaVersion.VERSION_1_7
sourceCompatibility = JavaVersion.VERSION_1_7
sourceSets {
main {
java {
srcDirs = ['src/main/java', '../droidux/src/main/java']
}
}
}
dependencies {
compile 'com.squareup:javapoet:1.7.0'
compile 'com.google.auto:auto-common:0.6'
compile 'com.google.auto.service:auto-service:1.0-rc2'
compile "io.reactivex.rxjava2:rxjava:${project.rxJava2Version}"
compile "com.android.databinding:baseLibrary:${project.databindingBaseLibraryVersion}"
compile fileTree(dir: './libs', includes: ['*.jar'])
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:2.2.0'
testCompile 'org.mockito:mockito-core:1.10.19'
testCompile 'com.google.testing.compile:compile-testing:0.6'
testCompile files(Jvm.current().getToolsJar())
testCompile 'com.google.android:android:4.1.1.4'
}
publish {
userOrg = project_bintray_org
groupId = project_group
artifactId = 'droidux-processor'
version = project.versionName
description = 'Code generator for info.izumin.android.droidux'
website = project_url
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/AbstractProcessingStep.java
================================================
package info.izumin.android.droidux.processor;
import com.google.auto.common.BasicAnnotationProcessor;
import com.squareup.javapoet.JavaFile;
import java.io.IOException;
import javax.annotation.processing.Filer;
/**
* Created by izumin on 11/26/15.
*/
public abstract class AbstractProcessingStep implements BasicAnnotationProcessor.ProcessingStep {
public static final String TAG = AbstractProcessingStep.class.getSimpleName();
private final Filer filer;
public AbstractProcessingStep(Filer filer) {
this.filer = filer;
}
protected void write(JavaFile file) {
try {
file.writeTo(filer);
} catch (IOException e) {
e.printStackTrace();
}
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/DroiduxProcessor.java
================================================
package info.izumin.android.droidux.processor;
import com.google.auto.common.BasicAnnotationProcessor;
import com.google.auto.service.AutoService;
import com.google.common.collect.ImmutableList;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
@AutoService(Processor.class)
public class DroiduxProcessor extends BasicAnnotationProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
@Override
protected Iterable<? extends ProcessingStep> initSteps() {
return ImmutableList.<ProcessingStep>of(
new ReducerProcessingStep(getFiler()),
new StoreProcessingStep(getFiler())
);
}
private Filer getFiler() {
return processingEnv.getFiler();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/ReducerProcessingStep.java
================================================
package info.izumin.android.droidux.processor;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import info.izumin.android.droidux.annotation.Reducer;
/**
* Created by izumin on 11/26/15.
*/
public class ReducerProcessingStep extends AbstractProcessingStep {
public static final String TAG = ReducerProcessingStep.class.getSimpleName();
public ReducerProcessingStep(Filer filer) {
super(filer);
}
@Override
public Set<? extends Class<? extends Annotation>> annotations() {
return ImmutableSet.<Class<? extends Annotation>>of(Reducer.class);
}
@Override
public Set<Element> process(SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
// for (Element element : elementsByAnnotation.get(Reducer.class)) {
// write(new StoreImplClassGenerator(new ReducerModel((TypeElement) element)).createJavaFile());
// }
return new HashSet<>();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/StoreProcessingStep.java
================================================
package info.izumin.android.droidux.processor;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;
import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.processing.Filer;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import info.izumin.android.droidux.annotation.Store;
import info.izumin.android.droidux.processor.generator.StoreClassGenerator;
import info.izumin.android.droidux.processor.generator.StoreImplClassGenerator;
import info.izumin.android.droidux.processor.model.StoreImplModel;
import info.izumin.android.droidux.processor.model.StoreModel;
/**
* Created by izumin on 11/26/15.
*/
public class StoreProcessingStep extends AbstractProcessingStep {
public static final String TAG = StoreProcessingStep.class.getSimpleName();
public StoreProcessingStep(Filer filer) {
super(filer);
}
@Override
public Set<? extends Class<? extends Annotation>> annotations() {
return ImmutableSet.<Class<? extends Annotation>>of(Store.class);
}
@Override
public Set<Element> process(SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
for (Element element : elementsByAnnotation.get(Store.class)) {
StoreModel model = new StoreModel((TypeElement) element);
for (StoreImplModel storeImplModel : model.getStoreImplModels()) {
write(new StoreImplClassGenerator(storeImplModel).createJavaFile());
}
write(new StoreClassGenerator(model).createJavaFile());
}
return new HashSet<>();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidDispatchableDeclarationException.java
================================================
package info.izumin.android.droidux.processor.exception;
/**
* Created by izumin on 11/7/15.
*/
public class InvalidDispatchableDeclarationException extends RuntimeException {
public InvalidDispatchableDeclarationException(String message) {
super(message);
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidReducerDeclarationException.java
================================================
package info.izumin.android.droidux.processor.exception;
/**
* Created by izumin on 11/8/15.
*/
public class InvalidReducerDeclarationException extends RuntimeException {
public InvalidReducerDeclarationException(String message) {
super(message);
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidStoreDelcarationException.java
================================================
package info.izumin.android.droidux.processor.exception;
/**
* Created by izumin on 11/24/15.
*/
public class InvalidStoreDelcarationException extends RuntimeException {
public InvalidStoreDelcarationException(String message) {
super(message);
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreBuilderClassGenerator.java
================================================
package info.izumin.android.droidux.processor.generator;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Modifier;
import info.izumin.android.droidux.Middleware;
import info.izumin.android.droidux.exception.NotInitializedException;
import info.izumin.android.droidux.processor.model.BuilderModel;
import info.izumin.android.droidux.processor.model.ReducerModel;
import info.izumin.android.droidux.processor.model.StoreImplModel;
import info.izumin.android.droidux.processor.model.StoreModel;
import static info.izumin.android.droidux.processor.util.PoetUtils.getParameterSpec;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
/**
* Created by izumin on 11/2/15.
*/
public class StoreBuilderClassGenerator {
public static final String TAG = StoreBuilderClassGenerator.class.getSimpleName();
static final String ERROR_MESSAGE_NOT_INITIALIZED_EXCEPTION = "$T has not been initialized.";
private final BuilderModel builderModel;
public StoreBuilderClassGenerator(StoreModel storeModel) {
builderModel = storeModel.getBuilderModel();
}
public TypeSpec createBuilderTypeSpec() {
return TypeSpec.classBuilder(builderModel.getClassName().simpleName())
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
.addFields(createFieldSpecs())
.addMethod(createAddMiddlewareMethodSpec())
.addMethod(createBuilderConstructor())
.addMethods(createReducerSetterMethodSpecs())
.addMethods(createReducerAndStateSetterMethodSpecs())
.addMethod(createBuildMethodSpec())
.build();
}
private List<FieldSpec> createFieldSpecs() {
List<FieldSpec> specs = new ArrayList<>();
specs.add(FieldSpec.builder(BuilderModel.MIDDLEWARES_TYPE,
BuilderModel.MIDDLEWARES_VARIABLE_NAME, Modifier.FINAL, Modifier.PRIVATE).build());
specs.addAll(FluentIterable.from(builderModel.getReducerModels())
.transform(new Function<ReducerModel, FieldSpec>() {
@Override
public FieldSpec apply(ReducerModel input) {
return FieldSpec.builder(input.getClassName(),
input.getVariableName(), Modifier.PRIVATE).build();
}
})
.toList());
specs.addAll(FluentIterable.from(builderModel.getReducerModels())
.transform(new Function<ReducerModel, FieldSpec>() {
@Override
public FieldSpec apply(ReducerModel input) {
return FieldSpec.builder(input.getState(),
input.getStateVariableName(), Modifier.PRIVATE).build();
}
})
.toList());
specs.addAll(FluentIterable.from(builderModel.getStoreModel().getStoreImplModels())
.filter(new Predicate<StoreImplModel>() {
@Override
public boolean apply(StoreImplModel input) {
return input.isBindable();
}
})
.transform(new Function<StoreImplModel, FieldSpec>() {
@Override
public FieldSpec apply(StoreImplModel input) {
return FieldSpec.builder(TypeName.INT, input.getFieldIdName(), Modifier.PRIVATE)
.build();
}
})
.toList());
return specs;
}
private MethodSpec createBuilderConstructor() {
return MethodSpec.constructorBuilder()
.addModifiers(Modifier.PRIVATE)
.addStatement("$N = new $T<>()", BuilderModel.MIDDLEWARES_VARIABLE_NAME, ArrayList.class)
.build();
}
private MethodSpec createAddMiddlewareMethodSpec() {
return MethodSpec.methodBuilder(BuilderModel.ADD_MIDDLEWARE_METHOD_NAME)
.addModifiers(Modifier.PUBLIC)
.returns(builderModel.getClassName())
.addParameter(getParameterSpec(Middleware.class))
.addStatement("$N.add($N)", BuilderModel.MIDDLEWARES_VARIABLE_NAME,
getLowerCamelFromUpperCamel(Middleware.class.getName()))
.addStatement("return this")
.build();
}
private List<MethodSpec> createReducerSetterMethodSpecs() {
return FluentIterable.from(builderModel.getStoreModel().getStoreImplModels())
.transform(new Function<StoreImplModel, MethodSpec>() {
@Override
public MethodSpec apply(StoreImplModel input) {
MethodSpec.Builder builder = MethodSpec.methodBuilder(BuilderModel.REDUCER_SETTER_METHOD_NAME)
.addModifiers(Modifier.PUBLIC)
.returns(builderModel.getClassName())
.addParameter(getParameterSpec(input.getReducerModel().getClassName()));
if (input.isBindable()) {
builder = builder.addParameter(TypeName.INT, input.getFieldIdName())
.addStatement("this.$N = $N", input.getFieldIdName(), input.getFieldIdName());
}
return builder.addStatement("this.$N = $N", input.getReducerModel().getVariableName(), input.getReducerModel().getVariableName())
.addStatement("return this")
.build();
}
})
.toList();
}
private List<MethodSpec> createReducerAndStateSetterMethodSpecs() {
return FluentIterable.from(builderModel.getStoreModel().getStoreImplModels())
.transform(new Function<StoreImplModel, MethodSpec>() {
@Override
public MethodSpec apply(StoreImplModel input) {
MethodSpec.Builder builder = MethodSpec.methodBuilder(BuilderModel.REDUCER_SETTER_METHOD_NAME)
.addModifiers(Modifier.PUBLIC)
.returns(builderModel.getClassName())
.addParameter(getParameterSpec(input.getReducerModel().getClassName()))
.addParameter(getParameterSpec(input.getState()));
if (input.isBindable()) {
builder = builder.addParameter(TypeName.INT, input.getFieldIdName());
}
builder = builder.addStatement("this.$N = $N", input.getStateVariableName(), input.getStateVariableName());
if (input.isBindable()) {
builder = builder.addStatement("return $N($N, $N)", BuilderModel.REDUCER_SETTER_METHOD_NAME, input.getReducerModel().getVariableName(), input.getFieldIdName());
} else {
builder = builder.addStatement("return $N($N)", BuilderModel.REDUCER_SETTER_METHOD_NAME, input.getReducerModel().getVariableName());
}
return builder.build();
}
})
.toList();
}
private MethodSpec createBuildMethodSpec() {
MethodSpec.Builder builder = MethodSpec.methodBuilder(BuilderModel.BUILD_METHOD_NAME)
.addModifiers(Modifier.PUBLIC)
.returns(builderModel.getStoreModel().getClassName());
for (ReducerModel reducerModel : builderModel.getReducerModels()) {
builder = builder
.beginControlFlow("if ($N == null)", reducerModel.getVariableName())
.addStatement("throw new $T(\"" + ERROR_MESSAGE_NOT_INITIALIZED_EXCEPTION + "\")",
NotInitializedException.class, reducerModel.getClassName())
.endControlFlow();
}
return builder
.addStatement("return new $T(this)", builderModel.getStoreModel().getClassName())
.build();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreClassGenerator.java
================================================
package info.izumin.android.droidux.processor.generator;
import android.databinding.BaseObservable;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Modifier;
import info.izumin.android.droidux.Action;
import info.izumin.android.droidux.Middleware;
import info.izumin.android.droidux.OnStateChangedListener;
import info.izumin.android.droidux.processor.model.BuilderModel;
import info.izumin.android.droidux.processor.model.DispatcherModel;
import info.izumin.android.droidux.processor.model.StoreImplModel;
import info.izumin.android.droidux.processor.model.StoreMethodModel;
import info.izumin.android.droidux.processor.model.StoreModel;
import io.reactivex.Flowable;
import io.reactivex.Single;
import static info.izumin.android.droidux.processor.util.PoetUtils.getOverrideAnnotation;
import static info.izumin.android.droidux.processor.util.PoetUtils.getParameterSpec;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
/**
* Created by izumin on 11/3/15.
*/
public class StoreClassGenerator {
public static final String TAG = StoreClassGenerator.class.getSimpleName();
private final StoreModel storeModel;
public StoreClassGenerator(StoreModel storeModel) {
this.storeModel = storeModel;
}
public JavaFile createJavaFile() {
return JavaFile.builder(storeModel.getClassName().packageName(), createTypeSpec())
.skipJavaLangImports(true).build();
}
private TypeSpec createTypeSpec() {
return TypeSpec.classBuilder(storeModel.getClassName().simpleName())
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addSuperinterface(storeModel.getInterfaceName())
.superclass(TypeName.get(BaseObservable.class))
.addFields(createFieldSpecs())
.addMethod(createConstructor())
.addMethod(createBuilderMethodSpec())
.addMethods(createGetterMethodSpecs())
.addMethod(createDispatchMethodSpec())
.addType(new StoreBuilderClassGenerator(storeModel).createBuilderTypeSpec())
.build();
}
private List<FieldSpec> createFieldSpecs() {
List<FieldSpec> specs = new ArrayList<>();
specs.addAll(FluentIterable.from(storeModel.getStoreImplModels())
.transform(new Function<StoreImplModel, FieldSpec>() {
@Override
public FieldSpec apply(StoreImplModel input) {
return FieldSpec.builder(input.getClassName(), input.getVariableName(),
Modifier.PRIVATE, Modifier.FINAL).build();
}
}).toList());
specs.add(DispatcherModel.fieldSpec());
return specs;
}
private MethodSpec createConstructor() {
MethodSpec.Builder builder = MethodSpec.constructorBuilder()
.addModifiers(Modifier.PROTECTED)
.addParameter(getParameterSpec(storeModel.getBuilderModel().getClassName(), Modifier.FINAL));
for (StoreImplModel storeImpl : storeModel.getStoreImplModels()) {
builder = builder.addStatement("$N = new $T($N.$N, $N.$N)",
storeImpl.getVariableName(), storeImpl.getClassName(),
BuilderModel.VARIABLE_NAME, storeImpl.getStateVariableName(),
BuilderModel.VARIABLE_NAME, storeImpl.getReducerModel().getVariableName());
if (storeImpl.isBindable()) {
TypeSpec listener = TypeSpec.anonymousClassBuilder("")
.addSuperinterface(ParameterizedTypeName.get(ClassName.get(OnStateChangedListener.class), storeImpl.getState()))
.addMethod(
MethodSpec.methodBuilder(StoreImplModel.ON_STATE_CHANGED_METHOD_NAME)
.addAnnotation(getOverrideAnnotation())
.addModifiers(Modifier.PUBLIC)
.addParameter(getParameterSpec(storeImpl.getState()))
.addStatement("$N($N.$N)",
StoreImplModel.NOTIFY_PROPERTY_CHANGED_METHOD_NAME,
BuilderModel.VARIABLE_NAME,
storeImpl.getFieldIdName())
.build()
)
.build();
builder = builder.addStatement("$N.$N($L)", storeImpl.getVariableName(),
StoreImplModel.ADD_LISTENER_METHOD_NAME, listener);
}
}
final String middlewareFiledName = "middleware";
return builder
.addStatement("$N = new $N($N.$N, $N)",
DispatcherModel.VARIABLE_NAME, DispatcherModel.CLASS_NAME,
BuilderModel.VARIABLE_NAME, BuilderModel.MIDDLEWARES_VARIABLE_NAME,
FluentIterable.from(storeModel.getStoreImplModels())
.transform(new Function<StoreImplModel, String>() {
@Override
public String apply(StoreImplModel input) {
return input.getVariableName();
}
}).join(Joiner.on(", ")))
.beginControlFlow("for ($T $N : $N.$N)", Middleware.class, middlewareFiledName,
BuilderModel.VARIABLE_NAME, StoreModel.MIDDLEWARES_FIELD_NAME)
.addStatement("$N.$N(this, $N)", middlewareFiledName,
StoreModel.ATTACH_MIDDLEWARE_METHOD_NAME, DispatcherModel.VARIABLE_NAME)
.endControlFlow()
.build();
}
private MethodSpec createBuilderMethodSpec() {
return MethodSpec.methodBuilder(StoreModel.BUILDER_METHOD_NAME)
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(storeModel.getBuilderModel().getClassName())
.addStatement("return new $T()", storeModel.getBuilderModel().getClassName())
.build();
}
private List<MethodSpec> createGetterMethodSpecs() {
return FluentIterable.from(storeModel.getMethodModels())
.transform(new Function<StoreMethodModel, MethodSpec>() {
@Override
public MethodSpec apply(StoreMethodModel input) {
return MethodSpec.methodBuilder(input.getName())
.addAnnotation(getOverrideAnnotation())
.addModifiers(Modifier.PUBLIC)
.returns(TypeName.get(input.getReturnType()))
.addParameters(input.getParameters())
.addCode(input.getCodeBlock())
.build();
}
})
.toList();
}
private MethodSpec createDispatchMethodSpec() {
return MethodSpec.methodBuilder(StoreModel.DISPATCH_METHOD_NAME)
.addAnnotation(getOverrideAnnotation())
.addModifiers(Modifier.PUBLIC)
.returns(ParameterizedTypeName.get(ClassName.get(Flowable.class), ClassName.get(Action.class)))
.addParameter(getParameterSpec(Action.class))
.addStatement("return $N.$N($N)",
DispatcherModel.VARIABLE_NAME, DispatcherModel.DISPATCH_METHOD_NAME,
getLowerCamelFromUpperCamel(ClassName.get(Action.class).simpleName()))
.build();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreImplClassGenerator.java
================================================
package info.izumin.android.droidux.processor.generator;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.ParameterizedTypeName;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.Modifier;
import info.izumin.android.droidux.Action;
import info.izumin.android.droidux.StoreImpl;
import info.izumin.android.droidux.UndoableStoreImpl;
import info.izumin.android.droidux.processor.model.DispatchableModel;
import info.izumin.android.droidux.processor.model.StoreImplModel;
import static info.izumin.android.droidux.processor.util.PoetUtils.getOverrideAnnotation;
import static info.izumin.android.droidux.processor.util.PoetUtils.getParameterSpec;
/**
* Created by izumin on 11/2/15.
*/
public class StoreImplClassGenerator {
public static final String TAG = StoreImplClassGenerator.class.getSimpleName();
private final StoreImplModel storeImplModel;
public StoreImplClassGenerator(StoreImplModel storeImplModel) {
this.storeImplModel = storeImplModel;
}
public JavaFile createJavaFile() {
return JavaFile.builder(storeImplModel.getPackageName(), createTypeSpec())
.skipJavaLangImports(true).build();
}
private TypeSpec createTypeSpec() {
return TypeSpec.classBuilder(storeImplModel.getClassName().simpleName())
.addModifiers(Modifier.FINAL)
.superclass(ParameterizedTypeName.get(ClassName.get(storeImplModel.isUndoable() ? UndoableStoreImpl.class : StoreImpl.class),
storeImplModel.getState(), storeImplModel.getReducerModel().getClassName()))
.addMethod(createConstructor())
.addMethod(createMethodSpec())
.build();
}
private MethodSpec createConstructor() {
return MethodSpec.constructorBuilder()
.addModifiers(Modifier.PROTECTED)
.addParameter(storeImplModel.getState(), StoreImplModel.STATE_VARIABLE_NAME)
.addParameter(storeImplModel.getReducerModel().getClassName(), StoreImplModel.REDUCER_VARIABLE_NAME)
.addStatement("super($N, $N)", StoreImplModel.STATE_VARIABLE_NAME, StoreImplModel.REDUCER_VARIABLE_NAME)
.build();
}
private MethodSpec createMethodSpec() {
return MethodSpec.methodBuilder(StoreImplModel.DISPATCH_METHOD_NAME)
.addAnnotation(getOverrideAnnotation())
.addModifiers(Modifier.PROTECTED)
.returns(TypeName.VOID)
.addParameter(getParameterSpec(Action.class))
.addCode(createCodeBlock())
.build();
}
private CodeBlock createCodeBlock() {
CodeBlock.Builder builder = CodeBlock.builder();
final String ACTION_FIELD = "action";
final String ACTION_CLASS_FIELD = "actionClass";
final String RESULT_FIELD = "result";
final String STATE_GETTER = storeImplModel.isUndoable() ? "getState().clone()" : "getState()";
if (storeImplModel.isUndoable()) {
builder = builder.addStatement("super.$N($N)",
StoreImplModel.DISPATCH_METHOD_NAME, ACTION_FIELD);
}
builder = builder.addStatement("Class<? extends $T> $N = $N.getClass()",
Action.class, ACTION_CLASS_FIELD, ACTION_FIELD)
.addStatement("$T $N = null", storeImplModel.getState(), RESULT_FIELD);
for (final DispatchableModel dispatchableModel : storeImplModel.getReducerModel().getDispatchableModels()) {
final List<Object> args = new ArrayList<>();
args.add(RESULT_FIELD);
args.add(StoreImplModel.REDUCER_GETTER_METHOD_NAME);
args.add(dispatchableModel.getMethodName());
final String format = "$N = $N().$N(" + FluentIterable.from(dispatchableModel.getArguments())
.transform(new Function<ClassName, String>() {
@Override
public String apply(ClassName input) {
if (input.simpleName().equals(dispatchableModel.getAction().simpleName())) {
args.add(dispatchableModel.getAction());
args.add(ACTION_FIELD);
return "($T) $N";
} else if (input.simpleName().equals(storeImplModel.getState().simpleName())) {
return STATE_GETTER;
} else {
return "";
}
}
}).join(Joiner.on(", ")) + ")";
builder = builder.beginControlFlow("if ($T.class.isAssignableFrom($N))",
dispatchableModel.getAction(), ACTION_CLASS_FIELD)
.addStatement(format, args.toArray())
.endControlFlow();
}
return builder
.beginControlFlow("if ($N != null)", RESULT_FIELD)
.addStatement("setState($N)", RESULT_FIELD)
.endControlFlow()
.build();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/BuilderModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterizedTypeName;
import java.util.List;
import info.izumin.android.droidux.Middleware;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
/**
* Created by izumin on 11/28/15.
*/
public class BuilderModel {
public static final String TAG = BuilderModel.class.getSimpleName();
public static final String CLASS_NAME = "Builder";
public static final String VARIABLE_NAME = getLowerCamelFromUpperCamel(CLASS_NAME);
public static final String ADD_MIDDLEWARE_METHOD_NAME = "addMiddleware";
public static final String STATE_SETTER_METHOD_NAME = "setInitialState";
public static final String REDUCER_SETTER_METHOD_NAME = "setReducer";
public static final String BUILD_METHOD_NAME = "build";
public static final ParameterizedTypeName MIDDLEWARES_TYPE =
ParameterizedTypeName.get(List.class, Middleware.class);
public static final String MIDDLEWARES_VARIABLE_NAME = "middlewares";
private final ClassName className;
private final StoreModel storeModel;
private final List<ReducerModel> reducerModels;
public BuilderModel(StoreModel storeModel) {
this.storeModel = storeModel;
this.className = storeModel.getClassName().nestedClass(CLASS_NAME);
this.reducerModels = storeModel.getReducerModels();
}
public StoreModel getStoreModel() {
return storeModel;
}
public ClassName getClassName() {
return className;
}
public List<ReducerModel> getReducerModels() {
return reducerModels;
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatchableModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import java.util.List;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.processor.validator.DispatchableValidator;
import static com.google.auto.common.MoreTypes.asTypeElement;
import static info.izumin.android.droidux.processor.util.AnnotationUtils.getTypeFromAnnotation;
/**
* Created by izumin on 11/3/15.
*/
public class DispatchableModel {
public static final String TAG = DispatchableModel.class.getSimpleName();
private final ExecutableElement element;
private final ReducerModel reducerModel;
private final ClassName action;
private final String methodName;
private final List<ClassName> arguments;
public DispatchableModel(ExecutableElement element, ReducerModel reducerModel) {
this.element = element;
this.reducerModel = reducerModel;
this.methodName = element.getSimpleName().toString();
this.action = ClassName.get(asTypeElement(getTypeFromAnnotation(element, Dispatchable.class, "value")));
this.arguments = FluentIterable.from(element.getParameters())
.transform(new Function<VariableElement, ClassName>() {
@Override
public ClassName apply(VariableElement input) {
return ClassName.get(MoreTypes.asTypeElement(input.asType()));
}
}).toList();
DispatchableValidator.validate(this);
}
public ClassName getAction() {
return action;
}
public String getMethodName() {
return methodName;
}
public int argumentCount() {
return element.getParameters().size();
}
public ExecutableElement getElement() {
return element;
}
public List<ClassName> getArguments() {
return arguments;
}
public ClassName getReducerClassName() {
return reducerModel.getClassName();
}
public ClassName getState() {
return reducerModel.getState();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatcherModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.squareup.javapoet.FieldSpec;
import javax.lang.model.element.Modifier;
import info.izumin.android.droidux.Dispatcher;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
/**
* Created by izumin on 11/28/15.
*/
public class DispatcherModel {
public static final String TAG = DispatcherModel.class.getSimpleName();
public static final Class CLASS = Dispatcher.class;
public static final String CLASS_NAME = "Dispatcher";
public static final String VARIABLE_NAME = getLowerCamelFromUpperCamel(CLASS_NAME);
public static final String DISPATCH_METHOD_NAME = "dispatch";
public static FieldSpec fieldSpec() {
return FieldSpec.builder(CLASS, VARIABLE_NAME, Modifier.PRIVATE, Modifier.FINAL).build();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/ReducerModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.squareup.javapoet.ClassName;
import java.util.ArrayList;
import java.util.List;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Undoable;
import info.izumin.android.droidux.processor.util.StringUtils;
import info.izumin.android.droidux.processor.validator.ReducerValidator;
import static com.google.auto.common.MoreTypes.asTypeElement;
import static info.izumin.android.droidux.processor.util.AnnotationUtils.findMethodsByAnnotation;
import static info.izumin.android.droidux.processor.util.AnnotationUtils.getTypeFromAnnotation;
/**
* Created by izumin on 11/3/15.
*/
public class ReducerModel {
public static final String TAG = ReducerModel.class.getSimpleName();
public static final String CLASS_NAME_SUFFIX = "Reducer";
private final TypeElement element;
private final TypeElement stateElement;
private final ClassName state;
private final ClassName className;
private final String qualifiedName;
private final String packageName;
private final String variableName;
private String stateName;
private String stateVariableName;
private final boolean isUndoable;
private List<DispatchableModel> dispatchableModels;
public ReducerModel(TypeElement element) {
this.element = element;
this.stateElement = asTypeElement(getTypeFromAnnotation(element, Reducer.class, "value"));
this.state = ClassName.get(stateElement);
this.stateName = state.simpleName();
this.stateVariableName = StringUtils.getLowerCamelFromUpperCamel(stateName);
this.isUndoable = element.getAnnotation(Undoable.class) != null;
this.className = ClassName.get(element);
this.qualifiedName = element.getQualifiedName().toString();
this.packageName = StringUtils.getPackageName(qualifiedName);
this.variableName = StringUtils.getLowerCamelFromUpperCamel(className.simpleName());
this.dispatchableModels = new ArrayList<>();
for (ExecutableElement el : findMethodsByAnnotation(element, Dispatchable.class)) {
dispatchableModels.add(new DispatchableModel(el, this));
}
ReducerValidator.validate(this);
}
public TypeElement getElement() {
return element;
}
public TypeElement getStateElement() {
return stateElement;
}
public ClassName getState() {
return state;
}
public ClassName getClassName() {
return className;
}
public String getQualifiedName() {
return qualifiedName;
}
public String getPackageName() {
return packageName;
}
public String getVariableName() {
return variableName;
}
public String getStateName() {
return stateName;
}
public String getStateVariableName() {
return stateVariableName;
}
public List<DispatchableModel> getDispatchableModels() {
return dispatchableModels;
}
public boolean isUndoable() {
return isUndoable;
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreImplModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.squareup.javapoet.ClassName;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
import static info.izumin.android.droidux.processor.util.StringUtils.replaceSuffix;
/**
* Created by izumin on 11/3/15.
*/
public class StoreImplModel {
public static final String TAG = StoreImplModel.class.getSimpleName();
public static final String REDUCER_VARIABLE_NAME = "reducer";
public static final String STATE_VARIABLE_NAME = "state";
public static final String DISPATCH_METHOD_NAME = "dispatch";
public static final String STATE_GETTER_METHOD_NAME = "getState";
public static final String REDUCER_GETTER_METHOD_NAME = "getReducer";
public static final String STATE_OBSERVE_METHOD_NAME = "observe";
public static final String ADD_LISTENER_METHOD_NAME = "addListener";
public static final String ON_STATE_CHANGED_METHOD_NAME = "onStateChanged";
public static final String NOTIFY_PROPERTY_CHANGED_METHOD_NAME = "notifyPropertyChanged";
private static final String CLASS_NAME_SUFFIX = "StoreImpl";
private static final String REDUCER_CLASS_NAME_SUFFIX = "Reducer";
private static final String FIELD_ID_SUFFIX = "FieldId";
private final ClassName className;
private final String variableName;
private final String storeImplName;
private final StoreModel storeModel;
private final ReducerModel reducerModel;
private boolean isBindable = false;
public StoreImplModel(StoreModel storeModel, ReducerModel reducerModel) {
this.storeModel = storeModel;
this.reducerModel = reducerModel;
this.storeImplName = replaceSuffix(reducerModel.getClassName().simpleName(),
REDUCER_CLASS_NAME_SUFFIX, CLASS_NAME_SUFFIX);
this.variableName = getLowerCamelFromUpperCamel(storeImplName);
this.className = ClassName.bestGuess(storeModel.getClassName() + "_" + storeImplName);
}
public ClassName getState() {
return reducerModel.getState();
}
public String getPackageName() {
return storeModel.getClassName().packageName();
}
public String getStateName() {
return reducerModel.getStateName();
}
public String getStateVariableName() {
return reducerModel.getStateVariableName();
}
public boolean isUndoable() {
return reducerModel.isUndoable();
}
public String getStoreImplName() {
return storeImplName;
}
public ClassName getClassName() {
return className;
}
public String getVariableName() {
return variableName;
}
public ReducerModel getReducerModel() {
return reducerModel;
}
public String getFieldIdName() {
return getStateVariableName() + FIELD_ID_SUFFIX;
}
public boolean isBindable() {
return isBindable;
}
public void setIsBindable(boolean isBindable) {
this.isBindable = isBindable;
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreMethodModel.java
================================================
package info.izumin.android.droidux.processor.model;
import android.databinding.Bindable;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.CodeBlock;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeName;
import java.util.List;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
/**
* Created by izumin on 11/28/15.
*/
public class StoreMethodModel {
public static final String TAG = StoreMethodModel.class.getSimpleName();
enum Kind {
DISPATCH,
GETTER,
OBSERVE,
OBSERVE_WITH_BPS,
UNKNOWN
}
private static final Class OBSERVE_METHOD_CLASS = Flowable.class;
private static final Class BACKPRESSURE_STRATEGY_PARAM_CLASS = BackpressureStrategy.class;
private final ExecutableElement element;
private final StoreModel storeModel;
private final Kind kind;
private final DeclaredType returnType;
private boolean isBindable = false;
private String bpsParamName = "";
public StoreMethodModel(ExecutableElement element, StoreModel storeModel) {
this.element = element;
this.storeModel = storeModel;
List<TypeName> states = FluentIterable.from(storeModel.getStoreImplModels())
.transform(new Function<StoreImplModel, TypeName>() {
@Override
public TypeName apply(StoreImplModel input) {
return input.getState();
}
}).toList();
returnType = MoreTypes.asDeclared(element.getReturnType());
if (states.contains(ClassName.get(returnType))) {
kind = Kind.GETTER;
isBindable = element.getAnnotation(Bindable.class) != null;
} else if (getName().equals(DispatcherModel.DISPATCH_METHOD_NAME)) {
kind = Kind.DISPATCH;
} else if (MoreTypes.isTypeOf(OBSERVE_METHOD_CLASS, returnType.asElement().asType())
&& states.contains(ClassName.get(returnType.getTypeArguments().get(0)))) {
if (element.getParameters() != null
&& !element.getParameters().isEmpty()
&& MoreTypes.isTypeOf(BACKPRESSURE_STRATEGY_PARAM_CLASS, element.getParameters().get(0).asType())) {
bpsParamName = element.getParameters().get(0).getSimpleName().toString();
kind = Kind.OBSERVE_WITH_BPS;
} else {
kind = Kind.OBSERVE;
}
} else {
kind = Kind.UNKNOWN;
}
}
public String getName() {
return element.getSimpleName().toString();
}
public DeclaredType getReturnType() {
return returnType;
}
public CodeBlock getCodeBlock() {
switch (kind) {
case GETTER:
return CodeBlock.builder().addStatement("return $N.$N()",
FluentIterable.from(storeModel.getStoreImplModels())
.filter(new Predicate<StoreImplModel>() {
@Override
public boolean apply(StoreImplModel input) {
return ClassName.get(returnType).equals(input.getState());
}
})
.get(0).getVariableName(),
StoreImplModel.STATE_GETTER_METHOD_NAME).build();
case OBSERVE:
return CodeBlock.builder().addStatement("return $N.$N()",
FluentIterable.from(storeModel.getStoreImplModels())
.filter(new Predicate<StoreImplModel>() {
@Override
public boolean apply(StoreImplModel input) {
return ClassName.get(returnType.getTypeArguments().get(0)).equals(input.getState());
}
})
.get(0).getVariableName(),
StoreImplModel.STATE_OBSERVE_METHOD_NAME).build();
case OBSERVE_WITH_BPS:
return CodeBlock.builder().addStatement("return $N.$N(" + bpsParamName + ")",
FluentIterable.from(storeModel.getStoreImplModels())
.filter(new Predicate<StoreImplModel>() {
@Override
public boolean apply(StoreImplModel input) {
return ClassName.get(returnType.getTypeArguments().get(0)).equals(input.getState());
}
})
.get(0).getVariableName(),
StoreImplModel.STATE_OBSERVE_METHOD_NAME).build();
case DISPATCH:
return CodeBlock.builder()
.addStatement("return $N.$N($N)", DispatcherModel.VARIABLE_NAME,
DispatcherModel.DISPATCH_METHOD_NAME, getParameters().get(0).name)
.build();
}
return CodeBlock.builder().build();
}
public List<ParameterSpec> getParameters() {
return FluentIterable.from(element.getParameters())
.transform(new Function<VariableElement, ParameterSpec>() {
@Override
public ParameterSpec apply(VariableElement input) {
return ParameterSpec.builder(TypeName.get(input.asType()),
input.getSimpleName().toString()).build();
}
}).toList();
}
public boolean isBindable() {
return isBindable;
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreModel.java
================================================
package info.izumin.android.droidux.processor.model;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import java.util.List;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import info.izumin.android.droidux.annotation.Store;
import info.izumin.android.droidux.processor.validator.StoreValidator;
import static com.google.auto.common.MoreTypes.asTypeElement;
import static info.izumin.android.droidux.processor.util.AnnotationUtils.getTypesFromAnnotation;
/**
* Created by izumin on 11/3/15.
*/
public class StoreModel {
public static final String TAG = StoreModel.class.getSimpleName();
public static final String MIDDLEWARES_FIELD_NAME = "middlewares";
public static final String ATTACH_MIDDLEWARE_METHOD_NAME = "onAttach";
public static final String BUILDER_METHOD_NAME = "builder";
public static final String DISPATCH_METHOD_NAME = "dispatch";
private static final String CLASS_NAME_PREFIX = "Droidux";
private final TypeElement element;
private final ClassName interfaceName;
private final ClassName className;
private final List<ReducerModel> reducerModels;
private final List<StoreImplModel> storeImplModels;
private final List<StoreMethodModel> methodModels;
private final BuilderModel builderModel;
public StoreModel(TypeElement element) {
this.element = element;
this.interfaceName = ClassName.get(element);
this.className = ClassName.get(interfaceName.packageName(), CLASS_NAME_PREFIX + interfaceName.simpleName());
StoreValidator.validate(this);
reducerModels = FluentIterable.from(getTypesFromAnnotation(element, Store.class, "value"))
.transform(new Function<TypeMirror, ReducerModel>() {
@Override
public ReducerModel apply(TypeMirror input) {
return new ReducerModel(asTypeElement(input));
}
}).toList();
storeImplModels = FluentIterable.from(reducerModels)
.transform(new Function<ReducerModel, StoreImplModel>() {
@Override
public StoreImplModel apply(ReducerModel input) {
return new StoreImplModel(StoreModel.this, input);
}
}).toList();
methodModels = FluentIterable.from(element.getEnclosedElements())
.filter(ExecutableElement.class)
.transform(new Function<ExecutableElement, StoreMethodModel>() {
@Override
public StoreMethodModel apply(ExecutableElement input) {
return new StoreMethodModel(input, StoreModel.this);
}
})
.toList();
for (final StoreImplModel storeImplModel : storeImplModels) {
storeImplModel.setIsBindable(FluentIterable.from(methodModels)
.filter(new Predicate<StoreMethodModel>() {
@Override
public boolean apply(StoreMethodModel input) {
return ClassName.get(input.getReturnType()).equals(storeImplModel.getState());
}
})
.anyMatch(new Predicate<StoreMethodModel>() {
@Override
public boolean apply(StoreMethodModel input) {
return input.isBindable();
}
}));
}
this.builderModel = new BuilderModel(this);
}
public TypeElement getElement() {
return element;
}
public ClassName getInterfaceName() {
return interfaceName;
}
public ClassName getClassName() {
return className;
}
public List<ReducerModel> getReducerModels() {
return reducerModels;
}
public List<StoreImplModel> getStoreImplModels() {
return storeImplModels;
}
public List<StoreMethodModel> getMethodModels() {
return methodModels;
}
public BuilderModel getBuilderModel() {
return builderModel;
}
public boolean isBindable() {
return FluentIterable.from(methodModels)
.anyMatch(new Predicate<StoreMethodModel>() {
@Override
public boolean apply(StoreMethodModel input) {
return input.isBindable();
}
});
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/AnnotationUtils.java
================================================
package info.izumin.android.droidux.processor.util;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import java.lang.annotation.Annotation;
import java.util.List;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.AnnotationValueVisitor;
import javax.lang.model.element.Element;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.SimpleAnnotationValueVisitor6;
import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
import static com.google.auto.common.MoreElements.getAnnotationMirror;
/**
* Created by izumin on 11/2/15.
*/
public final class AnnotationUtils {
public static final String TAG = AnnotationUtils.class.getSimpleName();
private AnnotationUtils() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static List<ExecutableElement> findMethodsByAnnotation(Element element, final Class<? extends Annotation> clazz) {
return FluentIterable.from(element.getEnclosedElements())
.filter(new Predicate<Element>() {
@Override
public boolean apply(Element input) {
return input.getAnnotation(clazz) != null;
}
})
.transform(new Function<Element, ExecutableElement>() {
@Override
public ExecutableElement apply(Element input) {
return (ExecutableElement) input;
}
})
.toList();
}
public static TypeMirror getTypeFromAnnotation(Element element, Class<? extends Annotation> annotationType, String argName) {
AnnotationMirror am = getAnnotationMirror(element, annotationType).get();
AnnotationValue av = getAnnotationValue(am, argName);
return TO_TYPE.visit(av);
}
public static List<TypeMirror> getTypesFromAnnotation(Element element, Class<? extends Annotation> annotationType, String argName) {
AnnotationMirror am = getAnnotationMirror(element, annotationType).get();
AnnotationValue av = getAnnotationValue(am, argName);
return TO_LIST_OF_TYPE.visit(av);
}
private static final AnnotationValueVisitor<ImmutableList<TypeMirror>, Void> TO_LIST_OF_TYPE = new SimpleAnnotationValueVisitor6<ImmutableList<TypeMirror>, Void>() {
@Override
public ImmutableList<TypeMirror> visitArray(List<? extends AnnotationValue> vals, Void aVoid) {
return FluentIterable.from(vals).transform(new Function<AnnotationValue, TypeMirror>() {
@Override
public TypeMirror apply(AnnotationValue input) {
return TO_TYPE.visit(input);
}
}).toList();
}
};
private static final AnnotationValueVisitor<TypeMirror, Void> TO_TYPE = new SimpleAnnotationValueVisitor6<TypeMirror, Void>() {
@Override
public TypeMirror visitType(TypeMirror t, Void aVoid) {
return t;
}
};
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/PoetUtils.java
================================================
package info.izumin.android.droidux.processor.util;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeName;
import java.lang.annotation.Annotation;
import javax.lang.model.element.Modifier;
import static info.izumin.android.droidux.processor.util.StringUtils.getLowerCamelFromUpperCamel;
/**
* Created by izumin on 11/2/15.
*/
public final class PoetUtils {
public static final String TAG = PoetUtils.class.getSimpleName();
private PoetUtils() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static ParameterSpec getParameterSpec(ClassName className, Modifier... modifiers) {
return ParameterSpec.builder(
className.box(),
getLowerCamelFromUpperCamel(className.simpleName()),
modifiers
).build();
}
public static ParameterSpec getParameterSpec(Class<?> clazz, Modifier... modifiers) {
return ParameterSpec.builder(
TypeName.get(clazz),
getLowerCamelFromUpperCamel(clazz.getSimpleName()),
modifiers
).build();
}
public static AnnotationSpec getOverrideAnnotation() {
return getAnnotationSpec(Override.class);
}
public static AnnotationSpec getAnnotationSpec(Class<? extends Annotation> clazz) {
return AnnotationSpec.builder(clazz).build();
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/StringUtils.java
================================================
package info.izumin.android.droidux.processor.util;
/**
* Created by izumin on 11/2/15.
*/
public final class StringUtils {
public static final String TAG = StringUtils.class.getSimpleName();
private StringUtils() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static String getPackageName(String qualifiedName) {
return qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
}
public static String getClassName(String qualifiedName) {
return qualifiedName.substring(qualifiedName.lastIndexOf(".") + 1);
}
public static String replaceSuffix(String base, String target, String replacement) {
return base.substring(0, base.lastIndexOf(target)) + replacement;
}
public static String getLowerCamelFromUpperCamel(String upperCamel) {
upperCamel = getClassName(getClassName(upperCamel));
return upperCamel.substring(0, 1).toLowerCase() + upperCamel.substring(1);
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/DispatchableValidator.java
================================================
package info.izumin.android.droidux.processor.validator;
import com.squareup.javapoet.ClassName;
import javax.lang.model.element.VariableElement;
import info.izumin.android.droidux.processor.exception.InvalidDispatchableDeclarationException;
import info.izumin.android.droidux.processor.model.DispatchableModel;
import static com.google.auto.common.MoreTypes.asTypeElement;
/**
* Created by izumin on 11/29/15.
*/
public final class DispatchableValidator {
private DispatchableValidator() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static void validate(DispatchableModel model) {
for (VariableElement element : model.getElement().getParameters()) {
if (!isAction(model, element) && !isState(model, element)) {
throw new InvalidDispatchableDeclarationException(
"@Dispatchable method can have arguments only state or action. "
+ methodName(model) + " has more than one invalid argument."
);
}
}
if (!isValidReturnType(model)) {
throw new InvalidDispatchableDeclarationException(
"@Dispatchable method must return new state. "
+ "But " + methodName(model) + " returns invalid type."
);
}
}
private static boolean isAction(DispatchableModel model, VariableElement element) {
return model.getAction().equals(ClassName.get(asTypeElement(element.asType())));
}
private static boolean isState(DispatchableModel model, VariableElement element) {
return model.getState().equals(ClassName.get(asTypeElement(element.asType())));
}
private static boolean isValidReturnType(DispatchableModel model) {
return ClassName.get(asTypeElement(model.getElement().getReturnType()))
.equals(model.getState());
}
private static String argName(VariableElement element) {
return "[" + element.asType().toString() + " " + element.getSimpleName() + "]";
}
private static String methodName(DispatchableModel model) {
return model.getReducerClassName().simpleName() + "#" + model.getMethodName() + "()";
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/ReducerValidator.java
================================================
package info.izumin.android.droidux.processor.validator;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import info.izumin.android.droidux.UndoableState;
import info.izumin.android.droidux.processor.exception.InvalidReducerDeclarationException;
import info.izumin.android.droidux.processor.model.ReducerModel;
/**
* Created by izumin on 11/29/15.
*/
public final class ReducerValidator {
private ReducerValidator() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static void validate(ReducerModel model) {
if (!isValidClassName(model)) {
throw new InvalidReducerDeclarationException(
"@Reducer class name must end with \"" + ReducerModel.CLASS_NAME_SUFFIX + "\". "
+ "\"" + model.getClassName().simpleName() + "\" has invalid class name."
);
}
if (model.isUndoable() && !hasUndoableState(model.getStateElement())) {
throw new InvalidReducerDeclarationException(
"@Reducer class annotated with @Undoable must have the state implements \"UndoableState<T>\". "
+ model.getState().simpleName() + " state of " + model.getClassName().simpleName() + " does not implement it."
);
}
}
private static boolean isValidClassName(ReducerModel model) {
return model.getClassName().simpleName().endsWith(ReducerModel.CLASS_NAME_SUFFIX);
}
private static boolean hasUndoableState(TypeElement stateElement) {
return FluentIterable.from(stateElement.getInterfaces())
.transform(new Function<TypeMirror, TypeName>() {
@Override
public TypeName apply(TypeMirror input) {
return ClassName.get(MoreTypes.asTypeElement(input));
}
})
.contains(TypeName.get(UndoableState.class));
}
}
================================================
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/StoreValidator.java
================================================
package info.izumin.android.droidux.processor.validator;
import com.google.auto.common.MoreTypes;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.TypeName;
import javax.lang.model.type.TypeMirror;
import info.izumin.android.droidux.BaseStore;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Store;
import info.izumin.android.droidux.processor.exception.InvalidStoreDelcarationException;
import info.izumin.android.droidux.processor.model.StoreModel;
import static info.izumin.android.droidux.processor.util.AnnotationUtils.getTypesFromAnnotation;
/**
* Created by izumin on 11/29/15.
*/
public final class StoreValidator {
private StoreValidator() {
throw new AssertionError("constructor of the utility class should not be called");
}
public static void validate(StoreModel model) {
if (!hasAnnotatedReducers(model)) {
throw new InvalidStoreDelcarationException(
"Values of @Store annotation must have only classes annotated with \"@Reducer\"."
+ "But " + model.getInterfaceName().simpleName() + " has invalid value."
);
}
if (!doesExtendBaseStore(model)) {
throw new InvalidStoreDelcarationException(
"The interface that is annotated @Store must extend \"BaseStore\"."
);
}
}
private static boolean hasAnnotatedReducers(StoreModel model) {
return FluentIterable.from(getTypesFromAnnotation(model.getElement(), Store.class, "value"))
.filter(new Predicate<TypeMirror>() {
@Override
public boolean apply(TypeMirror input) {
return MoreTypes.asTypeElement(input).getAnnotation(Reducer.class) == null;
}
}).size() == 0;
}
private static boolean doesExtendBaseStore(StoreModel model) {
return FluentIterable.from(model.getElement().getInterfaces())
.anyMatch(new Predicate<TypeMirror>() {
@Override
public boolean apply(TypeMirror input) {
return TypeName.get(BaseStore.class).equals(ClassName.get(input));
}
});
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/DroiduxProcessorTest.java
================================================
package info.izumin.android.droidux.processor;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import javax.tools.JavaFileObject;
import info.izumin.android.droidux.processor.fixture.Source;
import io.reactivex.BackpressureStrategy;
import static com.google.common.truth.Truth.assert_;
import static com.google.testing.compile.JavaFileObjects.forSourceLines;
import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
/**
* Created by izumin on 11/2/15.
*/
public class DroiduxProcessorTest {
public static final String TAG = DroiduxProcessorTest.class.getSimpleName();
@Rule
public ExpectedException expectedException = ExpectedException.none();
private static void assertJavaSource(JavaFileObject target, JavaFileObject generated, JavaFileObject... rest) {
assert_().about(javaSource())
.that(target)
.processedWith(new DroiduxProcessor())
.compilesWithoutError()
.and()
.generatesSources(generated, rest);
}
@Test
public void singleReducer() {
assertJavaSource(
forSourceLines("RootStore", Source.Counter.TARGET),
forSourceLines("DroiduxRootStore_CounterStoreImpl", Source.StoreImpl.COUNTER),
forSourceLines("DroiduxRootStore", Source.Counter.GENERATED_STORE)
);
}
@Test
public void singleReducer_with_BackpressureStrategySpecification() {
assertJavaSource(
forSourceLines("RootStore", Source.CounterWithBackpressureStrategy.TARGET),
forSourceLines("DroiduxRootStore_CounterStoreImpl", Source.StoreImpl.COUNTER),
forSourceLines("DroiduxRootStore", Source.CounterWithBackpressureStrategy.GENERATED_STORE)
);
}
@Test
public void singleReducerBindable() {
assertJavaSource(
forSourceLines("RootStore", Source.BindableCounter.TARGET),
forSourceLines("DroiduxRootStore_CounterStoreImpl", Source.StoreImpl.COUNTER),
forSourceLines("DroiduxRootStore", Source.BindableCounter.GENERATED_STORE)
);
}
@Test
public void combinedTwoReducers() {
assertJavaSource(
forSourceLines("RootStore", Source.CombinedTwoReducers.TARGET),
forSourceLines("DroiduxRootStore_CounterStoreImpl", Source.StoreImpl.COUNTER),
forSourceLines("DroiduxRootStore_TodoListStoreImpl", Source.StoreImpl.TODO_LIST),
forSourceLines("DroiduxRootStore", Source.CombinedTwoReducers.GENERATED)
);
}
@Test
public void combinedReducerAndBindableReducer() {
assertJavaSource(
forSourceLines("RootStore", Source.CombinedReducerAndBindableReducer.TARGET),
forSourceLines("DroiduxRootStore_CounterStoreImpl", Source.StoreImpl.COUNTER),
forSourceLines("DroiduxRootStore_TodoListStoreImpl", Source.StoreImpl.TODO_LIST),
forSourceLines("DroiduxRootStore", Source.CombinedReducerAndBindableReducer.GENERATED)
);
}
@Test
public void dispatchableMethodTakesWrongStateType() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Dispatchable method can have arguments only state or action. "
+ "CounterReducer#increment() has more than one invalid argument."
);
assertJavaSource(
forSourceLines("CounterStore", Source.DispatchableTakesWrongStateType.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void dispatchableMethodTakesWrongActionType() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Dispatchable method can have arguments only state or action. "
+ "TodoListReducer#addItem() has more than one invalid argument."
);
assertJavaSource(
forSourceLines("TodoListStore", Source.DispatchableTakesWrongActionType.TARGET),
forSourceLines("DroiduxTodoListStore_TodoListStoreImpl", Source.EMPTY),
forSourceLines("DroiduxTodoListStore", Source.EMPTY)
);
}
@Test
public void dispatchableMethodReturnsWrongType() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Dispatchable method can have arguments only state or action. "
+ "CounterReducer#increment() has more than one invalid argument."
);
assertJavaSource(
forSourceLines("CounterStore", Source.DispatchableTakesExtraArguments.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void dispatchableMethodShouldReturnState() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Dispatchable method must return new state. "
+ "But CounterReducer#increment() returns invalid type."
);
assertJavaSource(
forSourceLines("CounterStore", Source.DispatchableMethosReturnsWrongType.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void reducerWithoutSuffix() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Reducer class name must end with \"Reducer\". \"CounterReduce\" has invalid class name."
);
assertJavaSource(
forSourceLines("CounterStore", Source.ReducerWithoutSuffix.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void undoableReducerWithoutUndoableState() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"@Reducer class annotated with @Undoable must have the state implements \"UndoableState<T>\". "
+ "Counter state of CounterReducer does not implement it."
);
assertJavaSource(
forSourceLines("CounterStore", Source.UndoableReducerWithoutUndoableState.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void storeHasClassThatIsNotAnnotatedWithReducer() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"Values of @Store annotation must have only classes annotated with \"@Reducer\"."
+ "But CounterStore has invalid value."
);
assertJavaSource(
forSourceLines("CounterStore", Source.StoreHasInvalidValue.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
@Test
public void storeNotExtendBaseStore() {
expectedException.expect(RuntimeException.class);
expectedException.expectMessage(
"The interface that is annotated @Store must extend \"BaseStore\"."
);
assertJavaSource(
forSourceLines("CounterStore", Source.StoreNotExtendsBaseStore.TARGET),
forSourceLines("DroiduxCounterStore_CounterStoreImpl", Source.EMPTY),
forSourceLines("DroiduxCounterStore", Source.EMPTY)
);
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Counter.java
================================================
package info.izumin.android.droidux.processor.fixture;
/**
* Created by izumin on 11/2/15.
*/
public class Counter {
public static final String TAG = Counter.class.getSimpleName();
private int count;
public Counter(int count) {
this.count = count;
}
public int getCount() {
return count;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/CounterReducer.java
================================================
package info.izumin.android.droidux.processor.fixture;
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.processor.fixture.action.ClearCountAction;
import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;
import info.izumin.android.droidux.processor.fixture.action.InitializeCountAction;
import info.izumin.android.droidux.processor.fixture.action.SquareCountAction;
/**
* Created by izumin on 11/3/15.
*/
@Reducer(Counter.class)
public class CounterReducer {
@Dispatchable(IncrementCountAction.class)
public Counter increment(Counter state, IncrementCountAction action) {
return new Counter(state.getCount() + action.getValue());
}
@Dispatchable(SquareCountAction.class)
public Counter square(Counter state) {
return new Counter(state.getCount() * state.getCount());
}
@Dispatchable(InitializeCountAction.class)
public Counter initialize(InitializeCountAction action) {
return new Counter(action.getValue());
}
@Dispatchable(ClearCountAction.class)
public Counter clear() {
return new Counter(0);
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Source.java
================================================
package info.izumin.android.droidux.processor.fixture;
/**
* Created by izumin on 11/2/15.
*/
public final class Source {
public static final String TAG = Source.class.getSimpleName();
public static final String[] EMPTY = {};
public static final class StoreImpl {
public static final String[] COUNTER = {
"package info.izumin.android.droidux.sample;",
"",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.StoreImpl;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import info.izumin.android.droidux.processor.fixture.action.ClearCountAction;",
"import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;",
"import info.izumin.android.droidux.processor.fixture.action.InitializeCountAction;",
"import info.izumin.android.droidux.processor.fixture.action.SquareCountAction;",
"",
"final class DroiduxRootStore_CounterStoreImpl extends StoreImpl<Counter, CounterReducer> {",
" protected DroiduxRootStore_CounterStoreImpl(Counter state, CounterReducer reducer) {",
" super(state, reducer);",
" }",
"",
" @Override",
" protected void dispatch(Action action) {",
" Class<? extends Action> actionClass = action.getClass();",
" Counter result = null;",
" if (IncrementCountAction.class.isAssignableFrom(actionClass)) {",
" result = getReducer().increment(getState(), (IncrementCountAction) action);",
" }",
" if (SquareCountAction.class.isAssignableFrom(actionClass)) {",
" result = getReducer().square(getState());",
" }",
" if (InitializeCountAction.class.isAssignableFrom(actionClass)) {",
" result = getReducer().initialize((InitializeCountAction) action);",
" }",
" if (ClearCountAction.class.isAssignableFrom(actionClass)) {",
" result = getReducer().clear();",
" }",
" if (result != null) {",
" setState(result);",
" }",
" }",
"}"
};
public static final String[] TODO_LIST = {
"package info.izumin.android.droidux.sample;",
"",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.UndoableStoreImpl;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"import info.izumin.android.droidux.processor.fixture.TodoListReducer;",
"import info.izumin.android.droidux.processor.fixture.action.AddTodoItemAction;",
"",
"final class DroiduxRootStore_TodoListStoreImpl extends UndoableStoreImpl<TodoList, TodoListReducer> {",
" protected DroiduxCounterStore_CounterStoreImpl(TodoList state, TodoListReducer reducer) {",
" super(state, reducer);",
" }",
"",
" @Override",
" protected void dispatch(Action action) {",
" super.dispatch(action);",
" Class<? extends Action> actionClass = action.getClass();",
" TodoList result = null;",
" if (AddTodoItemAction.class.isAssignableFrom(actionClass)) {",
" result = getReducer().add(getState().clone(), (AddTodoItemAction) action);",
" }",
" if (result != null) {",
" setState(result);",
" }",
" }",
"}"
};
}
public static class Counter {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.Flowable;",
"@Store({CounterReducer.class})",
"public interface RootStore extends BaseStore {",
" Counter counter();",
" Flowable<Counter> observeCounter();",
"}"
};
public static final String[] GENERATED_STORE = {
"package info.izumin.android.droidux.sample;",
"",
"import android.databinding.BaseObservable;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.Dispatcher;",
"import info.izumin.android.droidux.Middleware;",
"import info.izumin.android.droidux.exception.NotInitializedException;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.Flowable;",
"import java.util.ArrayList;",
"import java.util.List;",
"",
"public final class DroiduxRootStore extends BaseObservable implements RootStore {",
" private final DroiduxRootStore_CounterStoreImpl counterStoreImpl;",
" private final Dispatcher dispatcher;",
"",
" protected DroiduxRootStore(final Builder builder) {",
" counterStoreImpl= new DroiduxRootStore_CounterStoreImpl(builder.counter, builder.counterReducer);",
" dispatcher = new Dispatcher(builder.middlewares, counterStoreImpl);",
" for (Middleware middleware : builder.middlewares) {",
" middleware.onAttach(this, dispatcher);",
" }",
" }",
"",
" public static Builder builder() {",
" return new Builder();",
" }",
"",
" @Override",
" public Counter counter() {",
" return counterStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<Counter> observeCounter() {",
" return counterStoreImpl.observe();",
" }",
"",
" @Override",
" public Flowable<Action> dispatch(Action action) {",
" return dispatcher.dispatch(action)",
" }",
"",
" public static final class Builder {",
" private final List<Middleware> middlewares;",
" private CounterReducer counterReducer;",
" private Counter counter;",
"",
" private Builder() {",
" middlewares = new ArrayList<>();",
" }",
"",
" public Builder addMiddleware(Middleware middleware) {",
" middlewares.add(middleware);",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer) {",
" this.counterReducer = counterReducer;",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, Counter counter) {",
" this.counter = counter;",
" return setReducer(counterReducer);",
" }",
"",
" public DroiduxRootStore build() {",
" if (counterReducer == null) {",
" throw new NotInitializedException(\"CounterReducer has not been initialized.\");",
" }",
" return new DroiduxRootStore(this);",
" }",
" }",
"}"
};
}
public static class CounterWithBackpressureStrategy {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.BackpressureStrategy;",
"import io.reactivex.Flowable;",
"@Store({CounterReducer.class})",
"public interface RootStore extends BaseStore {",
" Counter counter();",
" Flowable<Counter> observeCounter();",
" Flowable<Counter> observeCounter(BackpressureStrategy strategy);",
"}"
};
public static final String[] GENERATED_STORE = {
"package info.izumin.android.droidux.sample;",
"",
"import android.databinding.BaseObservable;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.Dispatcher;",
"import info.izumin.android.droidux.Middleware;",
"import info.izumin.android.droidux.exception.NotInitializedException;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.BackpressureStrategy;",
"import io.reactivex.Flowable;",
"import java.util.ArrayList;",
"import java.util.List;",
"",
"public final class DroiduxRootStore extends BaseObservable implements RootStore {",
" private final DroiduxRootStore_CounterStoreImpl counterStoreImpl;",
" private final Dispatcher dispatcher;",
"",
" protected DroiduxRootStore(final Builder builder) {",
" counterStoreImpl= new DroiduxRootStore_CounterStoreImpl(builder.counter, builder.counterReducer);",
" dispatcher = new Dispatcher(builder.middlewares, counterStoreImpl);",
" for (Middleware middleware : builder.middlewares) {",
" middleware.onAttach(this, dispatcher);",
" }",
" }",
"",
" public static Builder builder() {",
" return new Builder();",
" }",
"",
" @Override",
" public Counter counter() {",
" return counterStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<Counter> observeCounter() {",
" return counterStoreImpl.observe();",
" }",
"",
"",
" @Override",
" public Flowable<Counter> observeCounter(BackpressureStrategy strategy) {",
" return counterStoreImpl.observe(strategy);",
" }",
"",
" @Override",
" public Flowable<Action> dispatch(Action action) {",
" return dispatcher.dispatch(action)",
" }",
"",
" public static final class Builder {",
" private final List<Middleware> middlewares;",
" private CounterReducer counterReducer;",
" private Counter counter;",
"",
" private Builder() {",
" middlewares = new ArrayList<>();",
" }",
"",
" public Builder addMiddleware(Middleware middleware) {",
" middlewares.add(middleware);",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer) {",
" this.counterReducer = counterReducer;",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, Counter counter) {",
" this.counter = counter;",
" return setReducer(counterReducer);",
" }",
"",
" public DroiduxRootStore build() {",
" if (counterReducer == null) {",
" throw new NotInitializedException(\"CounterReducer has not been initialized.\");",
" }",
" return new DroiduxRootStore(this);",
" }",
" }",
"}"
};
}
public static class BindableCounter {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import android.databinding.Bindable;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.Flowable;",
"@Store({CounterReducer.class})",
"public interface RootStore extends BaseStore, android.databinding.Observable {",
" @Bindable Counter counter();",
" Flowable<Counter> observeCounter();",
"}"
};
public static final String[] GENERATED_STORE = {
"package info.izumin.android.droidux.sample;",
"",
"import android.databinding.BaseObservable;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.Dispatcher;",
"import info.izumin.android.droidux.Middleware;",
"import info.izumin.android.droidux.OnStateChangedListener;",
"import info.izumin.android.droidux.exception.NotInitializedException;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import io.reactivex.Flowable;",
"import java.util.ArrayList;",
"import java.util.List;",
"",
"public final class DroiduxRootStore extends BaseObservable implements RootStore {",
" private final DroiduxRootStore_CounterStoreImpl counterStoreImpl;",
" private final Dispatcher dispatcher;",
"",
" protected DroiduxRootStore(final Builder builder) {",
" counterStoreImpl = new DroiduxRootStore_CounterStoreImpl(builder.counter, builder.counterReducer);",
" counterStoreImpl.addListener(new OnStateChangedListener<Counter>() {",
" @Override",
" public void onStateChanged(Counter counter) {",
" notifyPropertyChanged(builder.counterFieldId);",
" }",
" });",
" dispatcher = new Dispatcher(builder.middlewares, counterStoreImpl);",
" for (Middleware middleware : builder.middlewares) {",
" middleware.onAttach(this, dispatcher);",
" }",
" }",
"",
" public static Builder builder() {",
" return new Builder();",
" }",
"",
" @Override",
" public Counter counter() {",
" return counterStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<Counter> observeCounter() {",
" return counterStoreImpl.observe();",
" }",
"",
" @Override",
" public Flowable<Action> dispatch(Action action) {",
" return dispatcher.dispatch(action)",
" }",
"",
" public static final class Builder {",
" private final List<Middleware> middlewares;",
" private CounterReducer counterReducer;",
" private Counter counter;",
" private int counterFieldId;",
"",
" private Builder() {",
" middlewares = new ArrayList<>();",
" }",
"",
" public Builder addMiddleware(Middleware middleware) {",
" middlewares.add(middleware);",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, int counterFieldId) {",
" this.counterFieldId = counterFieldId;",
" this.counterReducer = counterReducer;",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, Counter counter, int counterFieldId) {",
" this.counter = counter;",
" return setReducer(counterReducer, counterFieldId);",
" }",
"",
" public DroiduxRootStore build() {",
" if (counterReducer == null) {",
" throw new NotInitializedException(\"CounterReducer has not been initialized.\");",
" }",
" return new DroiduxRootStore(this);",
" }",
" }",
"}"
};
}
public static class CombinedTwoReducers {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import info.izumin.android.droidux.processor.fixture.TodoListReducer;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"import io.reactivex.Flowable;",
"@Store({CounterReducer.class, TodoListReducer.class})",
"public interface RootStore extends BaseStore {",
" Counter counter();",
" Flowable<Counter> observeCounter();",
" TodoList todoList();",
" Flowable<TodoList> observeTodoList();",
"}"
};
public static final String[] GENERATED = {
"package info.izumin.android.droidux.sample;",
"",
"import android.databinding.BaseObservable;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.Dispatcher;",
"import info.izumin.android.droidux.Middleware;",
"import info.izumin.android.droidux.exception.NotInitializedException;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"import info.izumin.android.droidux.processor.fixture.TodoListReducer;",
"import io.reactivex.Flowable;",
"import java.util.ArrayList;",
"import java.util.List;",
"",
"public final class DroiduxRootStore extends BaseObservable implements RootStore {",
" private final DroiduxRootStore_CounterStoreImpl counterStoreImpl;",
" private final DroiduxRootStore_TodoListStoreImpl todoListStoreImpl;",
" private final Dispatcher dispatcher;",
"",
" protected DroiduxRootStore(final Builder builder) {",
" counterStoreImpl= new DroiduxRootStore_CounterStoreImpl(builder.counter, builder.counterReducer);",
" todoListStoreImpl= new DroiduxRootStore_TodoListStoreImpl(builder.todoList, builder.todoListReducer);",
" dispatcher = new Dispatcher(builder.middlewares, counterStoreImpl, todoListStoreImpl);",
" for (Middleware middleware : builder.middlewares) {",
" middleware.onAttach(this, dispatcher);",
" }",
" }",
"",
" public static Builder builder() {",
" return new Builder();",
" }",
"",
" @Override",
" public Counter counter() {",
" return counterStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<Counter> observeCounter() {",
" return counterStoreImpl.observe();",
" }",
"",
" @Override",
" public TodoList todoList() {",
" return todoListStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<TodoList> observeTodoList() {",
" return todoListStoreImpl.observe();",
" }",
"",
" @Override",
" public Flowable<Action> dispatch(Action action) {",
" return dispatcher.dispatch(action)",
" }",
"",
" public static final class Builder {",
" private final List<Middleware> middlewares;",
" private CounterReducer counterReducer;",
" private TodoListReducer todoListReducer;",
" private Counter counter;",
" private TodoList todoList;",
" ",
" private Builder() {",
" middlewares = new ArrayList<>();",
" }",
"",
" public Builder addMiddleware(Middleware middleware) {",
" middlewares.add(middleware);",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer) {",
" this.counterReducer = counterReducer;",
" return this;",
" }",
"",
" public Builder setReducer(TodoListReducer todoListReducer) {",
" this.todoListReducer = todoListReducer;",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, Counter counter) {",
" this.counter = counter;",
" return setReducer(counterReducer);",
" }",
"",
" public Builder setReducer(TodoListReducer todoListReducer, TodoList todoList) {",
" this.todoList = todoList;",
" return setReducer(todoListReducer);",
" }",
"",
" public DroiduxRootStore build() {",
" if (counterReducer == null) {",
" throw new NotInitializedException(\"CounterReducer has not been initialized.\");",
" }",
" if (todoListReducer == null) {",
" throw new NotInitializedException(\"TodoListReducer has not been initialized.\");",
" }",
" return new DroiduxRootStore(this);",
" }",
" }",
"}"
};
}
public static class CombinedReducerAndBindableReducer {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import android.databinding.Bindable;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import info.izumin.android.droidux.processor.fixture.TodoListReducer;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"import io.reactivex.Flowable;",
"@Store({CounterReducer.class, TodoListReducer.class})",
"public interface RootStore extends BaseStore, android.databinding.Observable {",
" Counter counter();",
" Flowable<Counter> observeCounter();",
" @Bindable TodoList todoList();",
" Flowable<TodoList> observeTodoList();",
"}"
};
public static final String[] GENERATED = {
"package info.izumin.android.droidux.sample;",
"",
"import android.databinding.BaseObservable;",
"import info.izumin.android.droidux.Action;",
"import info.izumin.android.droidux.Dispatcher;",
"import info.izumin.android.droidux.Middleware;",
"import info.izumin.android.droidux.OnStateChangedListener;",
"import info.izumin.android.droidux.exception.NotInitializedException;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"import info.izumin.android.droidux.processor.fixture.CounterReducer;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"import info.izumin.android.droidux.processor.fixture.TodoListReducer;",
"import io.reactivex.Flowable;",
"import java.util.ArrayList;",
"import java.util.List;",
"",
"public final class DroiduxRootStore extends BaseObservable implements RootStore {",
" private final DroiduxRootStore_CounterStoreImpl counterStoreImpl;",
" private final DroiduxRootStore_TodoListStoreImpl todoListStoreImpl;",
" private final Dispatcher dispatcher;",
"",
" protected DroiduxRootStore(final Builder builder) {",
" counterStoreImpl= new DroiduxRootStore_CounterStoreImpl(builder.counter, builder.counterReducer);",
" todoListStoreImpl= new DroiduxRootStore_TodoListStoreImpl(builder.todoList, builder.todoListReducer);",
" todoListStoreImpl.addListener(new OnStateChangedListener<TodoList>() {",
" @Override",
" public void onStateChanged(TodoList todoList) {",
" notifyPropertyChanged(builder.todoListFieldId);",
" }",
" });",
" dispatcher = new Dispatcher(builder.middlewares, counterStoreImpl, todoListStoreImpl);",
" for (Middleware middleware : builder.middlewares) {",
" middleware.onAttach(this, dispatcher);",
" }",
" }",
"",
" public static Builder builder() {",
" return new Builder();",
" }",
"",
" @Override",
" public Counter counter() {",
" return counterStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<Counter> observeCounter() {",
" return counterStoreImpl.observe();",
" }",
"",
" @Override",
" public TodoList todoList() {",
" return todoListStoreImpl.getState();",
" }",
"",
" @Override",
" public Flowable<TodoList> observeTodoList() {",
" return todoListStoreImpl.observe();",
" }",
"",
" @Override",
" public Flowable<Action> dispatch(Action action) {",
" return dispatcher.dispatch(action)",
" }",
"",
" public static final class Builder {",
" private final List<Middleware> middlewares;",
" private CounterReducer counterReducer;",
" private TodoListReducer todoListReducer;",
" private Counter counter;",
" private TodoList todoList;",
" private int todoListFieldId;",
" ",
" private Builder() {",
" middlewares = new ArrayList<>();",
" }",
"",
" public Builder addMiddleware(Middleware middleware) {",
" middlewares.add(middleware);",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer) {",
" this.counterReducer = counterReducer;",
" return this;",
" }",
"",
" public Builder setReducer(TodoListReducer todoListReducer, int todoListFieldId) {",
" this.todoListFieldId = todoListFieldId;",
" this.todoListReducer = todoListReducer;",
" return this;",
" }",
"",
" public Builder setReducer(CounterReducer counterReducer, Counter counter) {",
" this.counter = counter;",
" return setReducer(counterReducer);",
" }",
"",
" public Builder setReducer(TodoListReducer todoListReducer, TodoList todoList, int todoListFieldId) {",
" this.todoList = todoList;",
" return setReducer(todoListReducer, todoListFieldId);",
" }",
"",
" public DroiduxRootStore build() {",
" if (counterReducer == null) {",
" throw new NotInitializedException(\"CounterReducer has not been initialized.\");",
" }",
" if (todoListReducer == null) {",
" throw new NotInitializedException(\"TodoListReducer has not been initialized.\");",
" }",
" return new DroiduxRootStore(this);",
" }",
" }",
"}"
};
}
public static class DispatchableTakesWrongStateType {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Dispatchable;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore extends BaseStore {",
" @Reducer(Counter.class)",
" public static class CounterReducer {",
" @Dispatchable(IncrementCountAction.class)",
" public Counter increment(Object state, IncrementCountAction action) {",
" return null;",
" }",
" }",
"}"
};
}
public static class DispatchableTakesWrongActionType {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Dispatchable;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.action.AddTodoItemAction;",
"import info.izumin.android.droidux.processor.fixture.action.CompleteTodoItemAction;",
"import info.izumin.android.droidux.processor.fixture.TodoList;",
"@Store(TodoListStore.TodoListReducer.class)",
"public interface TodoListStore extends BaseStore {",
" @Reducer(TodoList.class)",
" public static class TodoListReducer {",
" @Dispatchable(CompleteTodoItemAction.class)",
" public TodoList addItem(TodoList state, AddTodoItemAction action) {",
" return null;",
" }",
" }",
"}"
};
}
public static class DispatchableTakesExtraArguments {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Dispatchable;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore extends BaseStore {",
" @Reducer(Counter.class)",
" public static class CounterReducer {",
" @Dispatchable(IncrementCountAction.class)",
" public Counter increment(Counter state, IncrementCountAction action, String extra) {",
" return null;",
" }",
" }",
"}"
};
}
public static class DispatchableMethosReturnsWrongType{
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Dispatchable;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore extends BaseStore {",
" @Reducer(Counter.class)",
" public static class CounterReducer {",
" @Dispatchable(IncrementCountAction.class)",
" public Object increment(Counter state, IncrementCountAction action) {",
" return null;",
" }",
" }",
"}"
};
}
public static class ReducerWithoutSuffix {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Dispatchable;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.action.IncrementCountAction;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReduce.class)",
"public interface CounterStore extends BaseStore {",
" @Reducer(Counter.class)",
" public static class CounterReduce {",
" @Dispatchable(IncrementCountAction.class)",
" public Counter increment(Counter state, IncrementCountAction action) {",
" return null;",
" }",
" }",
"}"
};
}
public static class UndoableReducerWithoutUndoableState {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.annotation.Undoable;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore extends BaseStore {",
" @Undoable",
" @Reducer(Counter.class)",
" public static class CounterReducer {",
" }",
"}"
};
}
public static class StoreHasInvalidValue {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Store;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore extends BaseStore {",
" public static class CounterReducer {",
" }",
"}"
};
}
public static class StoreNotExtendsBaseStore {
public static final String[] TARGET = {
"package info.izumin.android.droidux.sample;",
"import info.izumin.android.droidux.BaseStore;",
"import info.izumin.android.droidux.annotation.Reducer;",
"import info.izumin.android.droidux.annotation.Store;",
"import info.izumin.android.droidux.processor.fixture.Counter;",
"@Store(CounterStore.CounterReducer.class)",
"public interface CounterStore {",
" @Reducer(Counter.class)",
" public static class CounterReducer {",
" }",
"}"
};
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoList.java
================================================
package info.izumin.android.droidux.processor.fixture;
import java.util.ArrayList;
import info.izumin.android.droidux.UndoableState;
/**
* Created by izumin on 11/2/15.
*/
public class TodoList extends ArrayList<TodoList.Item> implements UndoableState<TodoList> {
@Override
public TodoList clone() {
return (TodoList) super.clone();
}
public static class Item {
private String body;
private boolean isCompleted;
public Item(String body) {
this.body = body;
this.isCompleted = false;
}
public String getBody() {
return body;
}
public boolean isCompleted() {
return isCompleted;
}
public void setCompleted(boolean isCompleted) {
this.isCompleted = isCompleted;
}
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoListReducer.java
================================================
package info.izumin.android.droidux.processor.fixture;
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.annotation.Undoable;
import info.izumin.android.droidux.processor.fixture.action.AddTodoItemAction;
/**
* Created by izumin on 11/3/15.
*/
@Undoable
@Reducer(TodoList.class)
public class TodoListReducer {
@Dispatchable(AddTodoItemAction.class)
public TodoList add(TodoList state, AddTodoItemAction action) {
TodoList newState = new TodoList();
newState.addAll(state);
newState.add(new TodoList.Item(action.getValue()));
return newState;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/AddTodoItemAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class AddTodoItemAction implements Action {
public static final String TAG = AddTodoItemAction.class.getSimpleName();
private final String value;
public AddTodoItemAction(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/ClearCountAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class ClearCountAction implements Action {
public static final String TAG = ClearCountAction.class.getSimpleName();
public ClearCountAction() {
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/CompleteTodoItemAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class CompleteTodoItemAction implements Action {
public static final String TAG = CompleteTodoItemAction.class.getSimpleName();
private final int id;
public CompleteTodoItemAction(int id) {
this.id = id;
}
public int getId() {
return id;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/IncrementCountAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class IncrementCountAction implements Action {
public static final String TAG = IncrementCountAction.class.getSimpleName();
private final int value;
public IncrementCountAction(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/InitializeCountAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class InitializeCountAction implements Action {
public static final String TAG = InitializeCountAction.class.getSimpleName();
private final int value;
public InitializeCountAction(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
================================================
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/SquareCountAction.java
================================================
package info.izumin.android.droidux.processor.fixture.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 11/2/15.
*/
public class SquareCountAction implements Action {
public static final String TAG = SquareCountAction.class.getSimpleName();
public SquareCountAction() {
}
}
================================================
FILE: examples/counter/.gitignore
================================================
/build
================================================
FILE: examples/counter/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion project.compileSdkVersion
buildToolsVersion project.buildToolsVersion
defaultConfig {
applicationId "info.izumin.android.droidux.example.counter"
minSdkVersion project.minSdkVersion
targetSdkVersion project.targetSdkVersion
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
compile "io.reactivex.rxjava2:rxjava:${project.rxJava2Version}"
compile "io.reactivex.rxjava2:rxandroid:${project.rxAndroid2Version}"
compile project(':droidux')
annotationProcessor project(':droidux-processor')
compile project(':middlewares:droidux-thunk')
compile "com.android.support:appcompat-v7:${project.supportLibrariesVersion}"
compile "com.android.support:design:${project.supportLibrariesVersion}"
}
================================================
FILE: examples/counter/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: examples/counter/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.izumin.android.droidux.example.counter">
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/Counter.java
================================================
package info.izumin.android.droidux.example.counter;
/**
* Created by izumin on 12/6/15.
*/
public class Counter {
public static final String TAG = Counter.class.getSimpleName();
private final int count;
public Counter(int count) {
this.count = count;
}
public int getCount() {
return count;
}
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/CounterReducer.java
================================================
package info.izumin.android.droidux.example.counter;
import info.izumin.android.droidux.annotation.Dispatchable;
import info.izumin.android.droidux.annotation.Reducer;
import info.izumin.android.droidux.example.counter.action.DecrementCountAction;
import info.izumin.android.droidux.example.counter.action.IncrementCountAction;
/**
* Created by izumin on 12/6/15.
*/
@Reducer(Counter.class)
public class CounterReducer {
public static final String TAG = CounterReducer.class.getSimpleName();
@Dispatchable(IncrementCountAction.class)
public Counter increment(Counter state) {
return new Counter(state.getCount() + 1);
}
@Dispatchable(DecrementCountAction.class)
public Counter decrement(Counter state) {
return new Counter(state.getCount() - 1);
}
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainActivity.java
================================================
package info.izumin.android.droidux.example.counter;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import info.izumin.android.droidux.example.counter.action.DecrementCountAction;
import info.izumin.android.droidux.example.counter.action.IncrementCountAction;
import info.izumin.android.droidux.example.counter.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity implements MainEventHandlers {
private RootStore store;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
store = DroiduxRootStore.builder()
.setReducer(new CounterReducer(), new Counter(0), BR.counter)
.build();
binding.setHandlers(this);
binding.setStore(store);
}
@Override
public void onClickBtnIncrement(View v) {
store.dispatch(new IncrementCountAction()).subscribe();
}
@Override
public void onClickBtnDecrement(View v) {
store.dispatch(new DecrementCountAction()).subscribe();
}
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainEventHandlers.java
================================================
package info.izumin.android.droidux.example.counter;
import android.view.View;
/**
* Created by izumin on 12/6/15.
*/
public interface MainEventHandlers {
void onClickBtnIncrement(View v);
void onClickBtnDecrement(View v);
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/RootStore.java
================================================
package info.izumin.android.droidux.example.counter;
import android.databinding.Bindable;
import info.izumin.android.droidux.BaseStore;
import info.izumin.android.droidux.annotation.Store;
/**
* Created by izumin on 12/6/15.
*/
@Store(CounterReducer.class)
public interface RootStore extends BaseStore, android.databinding.Observable {
@Bindable Counter getCounter();
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/DecrementCountAction.java
================================================
package info.izumin.android.droidux.example.counter.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 12/6/15.
*/
public class DecrementCountAction implements Action {
public static final String TAG = DecrementCountAction.class.getSimpleName();
}
================================================
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/IncrementCountAction.java
================================================
package info.izumin.android.droidux.example.counter.action;
import info.izumin.android.droidux.Action;
/**
* Created by izumin on 12/6/15.
*/
public class IncrementCountAction implements Action {
public static final String TAG = IncrementCountAction.class.getSimpleName();
}
================================================
FILE: examples/counter/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" >
<data>
<variable name="handlers" type="info.izumin.android.droidux.example.counter.MainEventHandlers" />
<variable name="store" type="info.izumin.android.droidux.example.counter.RootStore" />
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="info.izumin.android.droidux.example.counter.MainActivity">
<TextView
android:id="@+id/text_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/counter_vertical_margin"
android:layout_marginBottom="@dimen/counter_vertical_margin"
android:layout_centerInParent="true"
android:textSize="@dimen/text_size_display3"
android:text="@{String.valueOf(store.counter.getCount())}"
tools:text="16" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/text_counter"
android:orientation="horizontal"
android:gravity="center_horizontal" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_increment"
android:onClick="@{handlers.onClickBtnIncrement}"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/btn_decrement"
android:onClick="@{handlers.onClickBtnDecrement}"/>
</LinearLayout>
</RelativeLayout>
</layout>
================================================
FILE: examples/counter/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
================================================
FILE: examples/counter/src/main/res/values/dimens.xml
================================================
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="counter_vertical_margin">32dp</dimen>
<dimen name="text_size_display3">56sp</dimen>
</resources>
================================================
FILE: examples/counter/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">Counter</string>
<string name="btn_increment">+</string>
<string name="btn_decrement">-</string>
</resources>
================================================
FILE: examples/counter/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: examples/counter/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
================================================
FILE: examples/todomvc/.gitignore
================================================
/build
================================================
FILE: examples/todomvc/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion project.compileSdkVersion
buildToolsVersion project.buildToolsVersion
defaultConfig {
applicationId "info.izumin.android.droidux.example.todomvc"
minSdkVersion project.minSdkVersion
targetSdkVersion project.targetSdkVersion
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
dataBinding {
enabled = true
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile "io.reactivex.rxjava2:rxjava:${project.rxJava2Version}"
compile "io.reactivex.rxjava2:rxandroid:${project.rxAndroid2Version}"
compile project(':droidux')
annotationProcessor project(':droidux-processor')
compile "com.android.support:appcompat-v7:${project.supportLibrariesVersion}"
compile "com.android.support:design:${project.supportLibrariesVersion}"
compile 'com.google.code.gson:gson:2.4'
}
================================================
FILE: examples/todomvc/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/opt/android-sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
================================================
FILE: examples/todomvc/src/androidTest/java/info/izumin/android/droidux/ApplicationTest.java
================================================
package info.izumin.android.droidux;
import android.app.Application;
import android.test.ApplicationTestCase;
/**
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
*/
public class ApplicationTest extends ApplicationTestCase<Application> {
public ApplicationTest() {
super(Application.class);
}
}
================================================
FILE: examples/todomvc/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.izumin.android.droidux.example.todomvc" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".App" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/App.java
================================================
package info.izumin.android.droidux.example.todomvc;
import android.app.Application;
import java.util.ArrayList;
import info.izumin.android.droidux.example.todomvc.entity.TodoList;
import info.izumin.android.droidux.example.todomvc.middleware.Logger;
import info.izumin.android.droidux.example.todomvc.reducer.TodoListReducer;
/**
* Created by izumin on 11/4/15.
*/
public class App extends Application {
public static final String TAG = App.class.getSimpleName();
private RootStore store;
@Override
public void onCreate() {
super.onCreate();
store = DroiduxRootStore.builder()
.addMiddleware(new Logger())
.setReducer(new TodoListReducer(), new TodoList(new ArrayList<>()))
.build();
}
public RootStore getStore() {
return store;
}
}
================================================
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivity.java
================================================
package info.izumin.android.droidux.example.todomvc;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private RootStore store;
private MainActivityHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DataBindingUtil.setContentView(this, R.layout.activity_main);
store = ((App) getApplication()).getStore();
helper = new MainActivityHelper(this);
helper.onCreate();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_manu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return helper.onOptionItemSelected(item) || super.onOptionsItemSelected(item);
}
}
================================================
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivityHelper.java
================================================
package info.izumin.android.droidux.example.todomvc;
import android.support.v7.app.AlertDialog;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import info.izumin.android.droidux.example.todomvc.action.AddTodoAction;
import info.izumin.android.droidux.example.todomvc.action.ClearCompletedTodoAction;
import info.izumin.android.droidux.example.todomvc.action.DeleteTodoAction;
import info.izumin.android.droidux.example.todomvc.action.ToggleCompletedTodoAction;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.SingleSubject;
/**
* Created by izumin on 11/5/15.
*/
public class MainActivityHelper {
public static final String TAG = MainActivityHelper.class.getSimpleName();
private MainActivity activity;
private RootStore store;
private EditText editNewTodo;
private Button btnAddTodo;
private ListView listTodo;
public MainActivityHelper(MainActivity activity) {
this.activity = activity;
}
public void onCreate() {
store = ((App) activity.getApplication()).getStore();
editNewTodo = (EditText) activity.findViewById(R.id.edit_new_todo);
btnAddTodo = (Button) activity.findViewById(R.id.btn_add_todo);
listTodo = (ListView) activity.findViewById(R.id.list_todo);
observeOnClickBtnAddTodo()
.filter(s -> !s.isEmpty())
.flatMap(s -> store.dispatch(new AddTodoAction(s)))
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(action -> {
editNewTodo.setText("");
Toast.makeText(activity, R.string.toast_add_todo, Toast.LENGTH_SHORT).show();
});
observeOnClickListItem()
.flatMap(id -> store.dispatch(new ToggleCompletedTodoAction(id.intValue())))
.subscribe();
observeOnLongClickListItem()
.flatMap(id -> store.dispatch(new DeleteTodoAction(id)))
.subscribeOn(AndroidSchedulers.mainThread())
.subscribe(action
gitextract_k8nenrgu/ ├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── build.gradle ├── droidux/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── info/ │ │ └── izumin/ │ │ └── android/ │ │ └── droidux/ │ │ ├── Action.java │ │ ├── BaseStore.java │ │ ├── Dispatcher.java │ │ ├── History.java │ │ ├── Middleware.java │ │ ├── OnStateChangedListener.java │ │ ├── StoreImpl.java │ │ ├── UndoableState.java │ │ ├── UndoableStoreImpl.java │ │ ├── action/ │ │ │ ├── HistoryAction.java │ │ │ ├── RedoAction.java │ │ │ └── UndoAction.java │ │ ├── annotation/ │ │ │ ├── Dispatchable.java │ │ │ ├── Reducer.java │ │ │ ├── Store.java │ │ │ └── Undoable.java │ │ └── exception/ │ │ └── NotInitializedException.java │ └── test/ │ └── groovy/ │ └── info/ │ └── izumin/ │ └── android/ │ └── droidux/ │ ├── DispatcherTest.groovy │ ├── HistoryTest.groovy │ └── action/ │ └── HistoryActionTest.groovy ├── droidux-processor/ │ ├── .gitignore │ ├── build.gradle │ ├── libs/ │ │ └── databinding-library.jar │ └── src/ │ ├── main/ │ │ └── java/ │ │ └── info/ │ │ └── izumin/ │ │ └── android/ │ │ └── droidux/ │ │ └── processor/ │ │ ├── AbstractProcessingStep.java │ │ ├── DroiduxProcessor.java │ │ ├── ReducerProcessingStep.java │ │ ├── StoreProcessingStep.java │ │ ├── exception/ │ │ │ ├── InvalidDispatchableDeclarationException.java │ │ │ ├── InvalidReducerDeclarationException.java │ │ │ └── InvalidStoreDelcarationException.java │ │ ├── generator/ │ │ │ ├── StoreBuilderClassGenerator.java │ │ │ ├── StoreClassGenerator.java │ │ │ └── StoreImplClassGenerator.java │ │ ├── model/ │ │ │ ├── BuilderModel.java │ │ │ ├── DispatchableModel.java │ │ │ ├── DispatcherModel.java │ │ │ ├── ReducerModel.java │ │ │ ├── StoreImplModel.java │ │ │ ├── StoreMethodModel.java │ │ │ └── StoreModel.java │ │ ├── util/ │ │ │ ├── AnnotationUtils.java │ │ │ ├── PoetUtils.java │ │ │ └── StringUtils.java │ │ └── validator/ │ │ ├── DispatchableValidator.java │ │ ├── ReducerValidator.java │ │ └── StoreValidator.java │ └── test/ │ └── java/ │ └── info/ │ └── izumin/ │ └── android/ │ └── droidux/ │ └── processor/ │ ├── DroiduxProcessorTest.java │ └── fixture/ │ ├── Counter.java │ ├── CounterReducer.java │ ├── Source.java │ ├── TodoList.java │ ├── TodoListReducer.java │ └── action/ │ ├── AddTodoItemAction.java │ ├── ClearCountAction.java │ ├── CompleteTodoItemAction.java │ ├── IncrementCountAction.java │ ├── InitializeCountAction.java │ └── SquareCountAction.java ├── examples/ │ ├── counter/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── example/ │ │ │ └── counter/ │ │ │ ├── Counter.java │ │ │ ├── CounterReducer.java │ │ │ ├── MainActivity.java │ │ │ ├── MainEventHandlers.java │ │ │ ├── RootStore.java │ │ │ └── action/ │ │ │ ├── DecrementCountAction.java │ │ │ └── IncrementCountAction.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ ├── todomvc/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── ApplicationTest.java │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── example/ │ │ │ └── todomvc/ │ │ │ ├── App.java │ │ │ ├── MainActivity.java │ │ │ ├── MainActivityHelper.java │ │ │ ├── RootStore.java │ │ │ ├── TodoListAdapter.java │ │ │ ├── action/ │ │ │ │ ├── AddTodoAction.java │ │ │ │ ├── ClearCompletedTodoAction.java │ │ │ │ ├── DeleteTodoAction.java │ │ │ │ └── ToggleCompletedTodoAction.java │ │ │ ├── entity/ │ │ │ │ └── TodoList.java │ │ │ ├── middleware/ │ │ │ │ └── Logger.java │ │ │ └── reducer/ │ │ │ └── TodoListReducer.java │ │ └── res/ │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ └── list_item_todo.xml │ │ ├── menu/ │ │ │ └── main_manu.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ ├── values-v21/ │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ ├── todos-with-dagger/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── androidTest/ │ │ │ └── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── example/ │ │ │ └── todoswithdagger/ │ │ │ └── ApplicationTest.java │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── info/ │ │ │ │ └── izumin/ │ │ │ │ └── android/ │ │ │ │ └── droidux/ │ │ │ │ └── example/ │ │ │ │ └── todoswithdagger/ │ │ │ │ ├── App.java │ │ │ │ ├── AppComponent.java │ │ │ │ ├── AppModule.java │ │ │ │ ├── RootStore.java │ │ │ │ ├── action/ │ │ │ │ │ ├── AddTodoAction.java │ │ │ │ │ ├── ClearCompletedTodoAction.java │ │ │ │ │ ├── ClearNewTodoTextAction.java │ │ │ │ │ ├── DeleteTodoAction.java │ │ │ │ │ ├── ToggleCompletedTodoAction.java │ │ │ │ │ └── UpdateNewTodoTextAction.java │ │ │ │ ├── adapter/ │ │ │ │ │ └── TodoListAdapter.java │ │ │ │ ├── entity/ │ │ │ │ │ └── TodoList.java │ │ │ │ ├── module/ │ │ │ │ │ └── main/ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ ├── MainComponent.java │ │ │ │ │ ├── MainEventHandlers.java │ │ │ │ │ ├── MainModule.java │ │ │ │ │ ├── MainPresenter.java │ │ │ │ │ └── MainView.java │ │ │ │ ├── reducer/ │ │ │ │ │ └── TodoListReducer.java │ │ │ │ └── util/ │ │ │ │ └── ViewBindingUtils.java │ │ │ └── res/ │ │ │ ├── layout/ │ │ │ │ ├── activity_main.xml │ │ │ │ └── list_item_todo.xml │ │ │ ├── menu/ │ │ │ │ └── main_manu.xml │ │ │ ├── values/ │ │ │ │ ├── colors.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── strings.xml │ │ │ │ └── styles.xml │ │ │ └── values-w820dp/ │ │ │ └── dimens.xml │ │ └── test/ │ │ └── java/ │ │ └── info/ │ │ └── izumin/ │ │ └── android/ │ │ └── droidux/ │ │ └── example/ │ │ └── todoswithdagger/ │ │ └── ExampleUnitTest.java │ └── todos-with-undo/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── info/ │ │ └── izumin/ │ │ └── android/ │ │ └── droidux/ │ │ └── example/ │ │ └── todoswithundo/ │ │ └── ApplicationTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── example/ │ │ │ └── todoswithundo/ │ │ │ ├── App.java │ │ │ ├── MainActivity.java │ │ │ ├── MainActivityHelper.java │ │ │ ├── RootStore.java │ │ │ ├── TodoListAdapter.java │ │ │ ├── action/ │ │ │ │ ├── AddTodoAction.java │ │ │ │ ├── ClearCompletedTodoAction.java │ │ │ │ ├── DeleteTodoAction.java │ │ │ │ └── ToggleCompletedTodoAction.java │ │ │ ├── entity/ │ │ │ │ └── TodoList.java │ │ │ ├── middleware/ │ │ │ │ └── Logger.java │ │ │ └── reducer/ │ │ │ └── TodoListReducer.java │ │ └── res/ │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ └── list_item_todo.xml │ │ ├── menu/ │ │ │ └── main_manu.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values-w820dp/ │ │ └── dimens.xml │ └── test/ │ └── java/ │ └── info/ │ └── izumin/ │ └── android/ │ └── droidux/ │ └── example/ │ └── todoswithundo/ │ └── ExampleUnitTest.java ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── middlewares/ │ └── droidux-thunk/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── info/ │ │ │ └── izumin/ │ │ │ └── android/ │ │ │ └── droidux/ │ │ │ └── thunk/ │ │ │ ├── AsyncAction.java │ │ │ └── ThunkMiddleware.java │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── test/ │ └── groovy/ │ └── info/ │ └── izumin/ │ └── android/ │ └── droidux/ │ └── thunk/ │ └── ThunkMiddlewareTest.groovy └── settings.gradle
SYMBOL INDEX (508 symbols across 106 files)
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/AbstractProcessingStep.java
class AbstractProcessingStep (line 13) | public abstract class AbstractProcessingStep implements BasicAnnotationP...
method AbstractProcessingStep (line 18) | public AbstractProcessingStep(Filer filer) {
method write (line 22) | protected void write(JavaFile file) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/DroiduxProcessor.java
class DroiduxProcessor (line 11) | @AutoService(Processor.class)
method getSupportedSourceVersion (line 14) | @Override
method initSteps (line 19) | @Override
method getFiler (line 27) | private Filer getFiler() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/ReducerProcessingStep.java
class ReducerProcessingStep (line 18) | public class ReducerProcessingStep extends AbstractProcessingStep {
method ReducerProcessingStep (line 21) | public ReducerProcessingStep(Filer filer) {
method annotations (line 25) | @Override
method process (line 30) | @Override
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/StoreProcessingStep.java
class StoreProcessingStep (line 23) | public class StoreProcessingStep extends AbstractProcessingStep {
method StoreProcessingStep (line 26) | public StoreProcessingStep(Filer filer) {
method annotations (line 30) | @Override
method process (line 35) | @Override
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidDispatchableDeclarationException.java
class InvalidDispatchableDeclarationException (line 6) | public class InvalidDispatchableDeclarationException extends RuntimeExce...
method InvalidDispatchableDeclarationException (line 7) | public InvalidDispatchableDeclarationException(String message) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidReducerDeclarationException.java
class InvalidReducerDeclarationException (line 6) | public class InvalidReducerDeclarationException extends RuntimeException {
method InvalidReducerDeclarationException (line 7) | public InvalidReducerDeclarationException(String message) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidStoreDelcarationException.java
class InvalidStoreDelcarationException (line 6) | public class InvalidStoreDelcarationException extends RuntimeException {
method InvalidStoreDelcarationException (line 7) | public InvalidStoreDelcarationException(String message) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreBuilderClassGenerator.java
class StoreBuilderClassGenerator (line 29) | public class StoreBuilderClassGenerator {
method StoreBuilderClassGenerator (line 36) | public StoreBuilderClassGenerator(StoreModel storeModel) {
method createBuilderTypeSpec (line 40) | public TypeSpec createBuilderTypeSpec() {
method createFieldSpecs (line 52) | private List<FieldSpec> createFieldSpecs() {
method createBuilderConstructor (line 92) | private MethodSpec createBuilderConstructor() {
method createAddMiddlewareMethodSpec (line 99) | private MethodSpec createAddMiddlewareMethodSpec() {
method createReducerSetterMethodSpecs (line 110) | private List<MethodSpec> createReducerSetterMethodSpecs() {
method createReducerAndStateSetterMethodSpecs (line 131) | private List<MethodSpec> createReducerAndStateSetterMethodSpecs() {
method createBuildMethodSpec (line 156) | private MethodSpec createBuildMethodSpec() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreClassGenerator.java
class StoreClassGenerator (line 39) | public class StoreClassGenerator {
method StoreClassGenerator (line 44) | public StoreClassGenerator(StoreModel storeModel) {
method createJavaFile (line 48) | public JavaFile createJavaFile() {
method createTypeSpec (line 53) | private TypeSpec createTypeSpec() {
method createFieldSpecs (line 67) | private List<FieldSpec> createFieldSpecs() {
method createConstructor (line 81) | private MethodSpec createConstructor() {
method createBuilderMethodSpec (line 132) | private MethodSpec createBuilderMethodSpec() {
method createGetterMethodSpecs (line 140) | private List<MethodSpec> createGetterMethodSpecs() {
method createDispatchMethodSpec (line 157) | private MethodSpec createDispatchMethodSpec() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreImplClassGenerator.java
class StoreImplClassGenerator (line 31) | public class StoreImplClassGenerator {
method StoreImplClassGenerator (line 36) | public StoreImplClassGenerator(StoreImplModel storeImplModel) {
method createJavaFile (line 40) | public JavaFile createJavaFile() {
method createTypeSpec (line 45) | private TypeSpec createTypeSpec() {
method createConstructor (line 55) | private MethodSpec createConstructor() {
method createMethodSpec (line 64) | private MethodSpec createMethodSpec() {
method createCodeBlock (line 74) | private CodeBlock createCodeBlock() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/BuilderModel.java
class BuilderModel (line 15) | public class BuilderModel {
method BuilderModel (line 35) | public BuilderModel(StoreModel storeModel) {
method getStoreModel (line 41) | public StoreModel getStoreModel() {
method getClassName (line 45) | public ClassName getClassName() {
method getReducerModels (line 49) | public List<ReducerModel> getReducerModels() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatchableModel.java
class DispatchableModel (line 22) | public class DispatchableModel {
method DispatchableModel (line 32) | public DispatchableModel(ExecutableElement element, ReducerModel reduc...
method getAction (line 48) | public ClassName getAction() {
method getMethodName (line 52) | public String getMethodName() {
method argumentCount (line 56) | public int argumentCount() {
method getElement (line 60) | public ExecutableElement getElement() {
method getArguments (line 64) | public List<ClassName> getArguments() {
method getReducerClassName (line 68) | public ClassName getReducerClassName() {
method getState (line 71) | public ClassName getState() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatcherModel.java
class DispatcherModel (line 14) | public class DispatcherModel {
method fieldSpec (line 23) | public static FieldSpec fieldSpec() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/ReducerModel.java
class ReducerModel (line 24) | public class ReducerModel {
method ReducerModel (line 44) | public ReducerModel(TypeElement element) {
method getElement (line 67) | public TypeElement getElement() {
method getStateElement (line 71) | public TypeElement getStateElement() {
method getState (line 75) | public ClassName getState() {
method getClassName (line 79) | public ClassName getClassName() {
method getQualifiedName (line 83) | public String getQualifiedName() {
method getPackageName (line 87) | public String getPackageName() {
method getVariableName (line 91) | public String getVariableName() {
method getStateName (line 95) | public String getStateName() {
method getStateVariableName (line 99) | public String getStateVariableName() {
method getDispatchableModels (line 103) | public List<DispatchableModel> getDispatchableModels() {
method isUndoable (line 107) | public boolean isUndoable() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreImplModel.java
class StoreImplModel (line 11) | public class StoreImplModel {
method StoreImplModel (line 38) | public StoreImplModel(StoreModel storeModel, ReducerModel reducerModel) {
method getState (line 49) | public ClassName getState() {
method getPackageName (line 53) | public String getPackageName() {
method getStateName (line 57) | public String getStateName() {
method getStateVariableName (line 61) | public String getStateVariableName() {
method isUndoable (line 65) | public boolean isUndoable() {
method getStoreImplName (line 69) | public String getStoreImplName() {
method getClassName (line 73) | public ClassName getClassName() {
method getVariableName (line 77) | public String getVariableName() {
method getReducerModel (line 81) | public ReducerModel getReducerModel() {
method getFieldIdName (line 85) | public String getFieldIdName() {
method isBindable (line 89) | public boolean isBindable() {
method setIsBindable (line 93) | public void setIsBindable(boolean isBindable) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreMethodModel.java
class StoreMethodModel (line 26) | public class StoreMethodModel {
type Kind (line 29) | enum Kind {
method StoreMethodModel (line 47) | public StoreMethodModel(ExecutableElement element, StoreModel storeMod...
method getName (line 81) | public String getName() {
method getReturnType (line 85) | public DeclaredType getReturnType() {
method getCodeBlock (line 89) | public CodeBlock getCodeBlock() {
method getParameters (line 133) | public List<ParameterSpec> getParameters() {
method isBindable (line 144) | public boolean isBindable() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreModel.java
class StoreModel (line 23) | public class StoreModel {
method StoreModel (line 43) | public StoreModel(TypeElement element) {
method getElement (line 95) | public TypeElement getElement() {
method getInterfaceName (line 99) | public ClassName getInterfaceName() {
method getClassName (line 103) | public ClassName getClassName() {
method getReducerModels (line 107) | public List<ReducerModel> getReducerModels() {
method getStoreImplModels (line 111) | public List<StoreImplModel> getStoreImplModels() {
method getMethodModels (line 115) | public List<StoreMethodModel> getMethodModels() {
method getBuilderModel (line 119) | public BuilderModel getBuilderModel() {
method isBindable (line 123) | public boolean isBindable() {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/AnnotationUtils.java
class AnnotationUtils (line 25) | public final class AnnotationUtils {
method AnnotationUtils (line 28) | private AnnotationUtils() {
method findMethodsByAnnotation (line 32) | public static List<ExecutableElement> findMethodsByAnnotation(Element ...
method getTypeFromAnnotation (line 49) | public static TypeMirror getTypeFromAnnotation(Element element, Class<...
method getTypesFromAnnotation (line 55) | public static List<TypeMirror> getTypesFromAnnotation(Element element,...
method visitArray (line 62) | @Override
method visitType (line 74) | @Override
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/PoetUtils.java
class PoetUtils (line 17) | public final class PoetUtils {
method PoetUtils (line 20) | private PoetUtils() {
method getParameterSpec (line 24) | public static ParameterSpec getParameterSpec(ClassName className, Modi...
method getParameterSpec (line 32) | public static ParameterSpec getParameterSpec(Class<?> clazz, Modifier....
method getOverrideAnnotation (line 40) | public static AnnotationSpec getOverrideAnnotation() {
method getAnnotationSpec (line 44) | public static AnnotationSpec getAnnotationSpec(Class<? extends Annotat...
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/StringUtils.java
class StringUtils (line 6) | public final class StringUtils {
method StringUtils (line 9) | private StringUtils() {
method getPackageName (line 13) | public static String getPackageName(String qualifiedName) {
method getClassName (line 17) | public static String getClassName(String qualifiedName) {
method replaceSuffix (line 21) | public static String replaceSuffix(String base, String target, String ...
method getLowerCamelFromUpperCamel (line 25) | public static String getLowerCamelFromUpperCamel(String upperCamel) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/DispatchableValidator.java
class DispatchableValidator (line 15) | public final class DispatchableValidator {
method DispatchableValidator (line 16) | private DispatchableValidator() {
method validate (line 20) | public static void validate(DispatchableModel model) {
method isAction (line 38) | private static boolean isAction(DispatchableModel model, VariableEleme...
method isState (line 42) | private static boolean isState(DispatchableModel model, VariableElemen...
method isValidReturnType (line 46) | private static boolean isValidReturnType(DispatchableModel model) {
method argName (line 51) | private static String argName(VariableElement element) {
method methodName (line 55) | private static String methodName(DispatchableModel model) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/ReducerValidator.java
class ReducerValidator (line 19) | public final class ReducerValidator {
method ReducerValidator (line 20) | private ReducerValidator() {
method validate (line 24) | public static void validate(ReducerModel model) {
method isValidClassName (line 40) | private static boolean isValidClassName(ReducerModel model) {
method hasUndoableState (line 44) | private static boolean hasUndoableState(TypeElement stateElement) {
FILE: droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/StoreValidator.java
class StoreValidator (line 22) | public final class StoreValidator {
method StoreValidator (line 23) | private StoreValidator() {
method validate (line 27) | public static void validate(StoreModel model) {
method hasAnnotatedReducers (line 42) | private static boolean hasAnnotatedReducers(StoreModel model) {
method doesExtendBaseStore (line 52) | private static boolean doesExtendBaseStore(StoreModel model) {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/DroiduxProcessorTest.java
class DroiduxProcessorTest (line 19) | public class DroiduxProcessorTest {
method assertJavaSource (line 25) | private static void assertJavaSource(JavaFileObject target, JavaFileOb...
method singleReducer (line 34) | @Test
method singleReducer_with_BackpressureStrategySpecification (line 43) | @Test
method singleReducerBindable (line 52) | @Test
method combinedTwoReducers (line 61) | @Test
method combinedReducerAndBindableReducer (line 71) | @Test
method dispatchableMethodTakesWrongStateType (line 81) | @Test
method dispatchableMethodTakesWrongActionType (line 95) | @Test
method dispatchableMethodReturnsWrongType (line 110) | @Test
method dispatchableMethodShouldReturnState (line 124) | @Test
method reducerWithoutSuffix (line 138) | @Test
method undoableReducerWithoutUndoableState (line 151) | @Test
method storeHasClassThatIsNotAnnotatedWithReducer (line 165) | @Test
method storeNotExtendBaseStore (line 179) | @Test
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Counter.java
class Counter (line 6) | public class Counter {
method Counter (line 11) | public Counter(int count) {
method getCount (line 15) | public int getCount() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/CounterReducer.java
class CounterReducer (line 13) | @Reducer(Counter.class)
method increment (line 15) | @Dispatchable(IncrementCountAction.class)
method square (line 20) | @Dispatchable(SquareCountAction.class)
method initialize (line 25) | @Dispatchable(InitializeCountAction.class)
method clear (line 30) | @Dispatchable(ClearCountAction.class)
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Source.java
class Source (line 6) | public final class Source {
class StoreImpl (line 11) | public static final class StoreImpl {
class Counter (line 82) | public static class Counter {
class CounterWithBackpressureStrategy (line 178) | public static class CounterWithBackpressureStrategy {
class BindableCounter (line 283) | public static class BindableCounter {
class CombinedTwoReducers (line 389) | public static class CombinedTwoReducers {
class CombinedReducerAndBindableReducer (line 518) | public static class CombinedReducerAndBindableReducer {
class DispatchableTakesWrongStateType (line 657) | public static class DispatchableTakesWrongStateType {
class DispatchableTakesWrongActionType (line 679) | public static class DispatchableTakesWrongActionType {
class DispatchableTakesExtraArguments (line 702) | public static class DispatchableTakesExtraArguments {
class DispatchableMethosReturnsWrongType (line 724) | public static class DispatchableMethosReturnsWrongType{
class ReducerWithoutSuffix (line 746) | public static class ReducerWithoutSuffix {
class UndoableReducerWithoutUndoableState (line 768) | public static class UndoableReducerWithoutUndoableState {
class StoreHasInvalidValue (line 786) | public static class StoreHasInvalidValue {
class StoreNotExtendsBaseStore (line 799) | public static class StoreNotExtendsBaseStore {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoList.java
class TodoList (line 10) | public class TodoList extends ArrayList<TodoList.Item> implements Undoab...
method clone (line 12) | @Override
class Item (line 17) | public static class Item {
method Item (line 21) | public Item(String body) {
method getBody (line 26) | public String getBody() {
method isCompleted (line 30) | public boolean isCompleted() {
method setCompleted (line 34) | public void setCompleted(boolean isCompleted) {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoListReducer.java
class TodoListReducer (line 11) | @Undoable
method add (line 14) | @Dispatchable(AddTodoItemAction.class)
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/AddTodoItemAction.java
class AddTodoItemAction (line 8) | public class AddTodoItemAction implements Action {
method AddTodoItemAction (line 13) | public AddTodoItemAction(String value) {
method getValue (line 17) | public String getValue() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/ClearCountAction.java
class ClearCountAction (line 8) | public class ClearCountAction implements Action {
method ClearCountAction (line 11) | public ClearCountAction() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/CompleteTodoItemAction.java
class CompleteTodoItemAction (line 8) | public class CompleteTodoItemAction implements Action {
method CompleteTodoItemAction (line 13) | public CompleteTodoItemAction(int id) {
method getId (line 17) | public int getId() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/IncrementCountAction.java
class IncrementCountAction (line 8) | public class IncrementCountAction implements Action {
method IncrementCountAction (line 13) | public IncrementCountAction(int value) {
method getValue (line 17) | public int getValue() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/InitializeCountAction.java
class InitializeCountAction (line 8) | public class InitializeCountAction implements Action {
method InitializeCountAction (line 13) | public InitializeCountAction(int value) {
method getValue (line 17) | public int getValue() {
FILE: droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/SquareCountAction.java
class SquareCountAction (line 8) | public class SquareCountAction implements Action {
method SquareCountAction (line 11) | public SquareCountAction() {
FILE: droidux/src/main/java/info/izumin/android/droidux/Action.java
type Action (line 6) | public interface Action {
FILE: droidux/src/main/java/info/izumin/android/droidux/BaseStore.java
type BaseStore (line 9) | public interface BaseStore {
method dispatch (line 10) | Flowable<Action> dispatch(Action action);
FILE: droidux/src/main/java/info/izumin/android/droidux/Dispatcher.java
class Dispatcher (line 14) | public class Dispatcher {
method Dispatcher (line 20) | public Dispatcher(List<Middleware> middlewares, StoreImpl... storeImpl...
method dispatch (line 25) | public Flowable<Action> dispatch(Action action) {
method applyMiddlewaresBeforeDispatch (line 48) | private Flowable<Action> applyMiddlewaresBeforeDispatch(Action action) {
method applyMiddlewaresAfterDispatch (line 62) | private Flowable<Action> applyMiddlewaresAfterDispatch(Action action) {
FILE: droidux/src/main/java/info/izumin/android/droidux/History.java
class History (line 9) | public class History<T extends UndoableState<T>> {
method History (line 20) | public History(T initialState) {
method getPresent (line 26) | public T getPresent() {
method insert (line 30) | public void insert(T state) {
method undo (line 39) | public T undo() {
method redo (line 47) | public T redo() {
method isUndoable (line 55) | public boolean isUndoable() {
method isRedoable (line 59) | public boolean isRedoable() {
method setLimit (line 63) | public void setLimit(int limit) {
FILE: droidux/src/main/java/info/izumin/android/droidux/Middleware.java
class Middleware (line 8) | public abstract class Middleware<S extends BaseStore> {
method onAttach (line 14) | public void onAttach(S store, Dispatcher dispatcher) {
method getStore (line 19) | protected S getStore() {
method getDispatcher (line 23) | protected Dispatcher getDispatcher() {
method beforeDispatch (line 27) | public abstract Flowable<Action> beforeDispatch(Action action);
method afterDispatch (line 28) | public abstract Flowable<Action> afterDispatch(Action action);
FILE: droidux/src/main/java/info/izumin/android/droidux/OnStateChangedListener.java
type OnStateChangedListener (line 6) | public interface OnStateChangedListener<T> {
method onStateChanged (line 7) | void onStateChanged(T state);
FILE: droidux/src/main/java/info/izumin/android/droidux/StoreImpl.java
class StoreImpl (line 13) | public abstract class StoreImpl<T, R> {
method StoreImpl (line 21) | protected StoreImpl(T state, R reducer) {
method observe (line 28) | public Flowable<T> observe() {
method observe (line 32) | public Flowable<T> observe(BackpressureStrategy strategy) {
method getState (line 36) | public T getState() {
method setState (line 40) | protected void setState(T state) {
method getReducer (line 48) | protected R getReducer() {
method addListener (line 52) | public void addListener(OnStateChangedListener<T> listener) {
method dispatch (line 56) | protected abstract void dispatch(Action action);
FILE: droidux/src/main/java/info/izumin/android/droidux/UndoableState.java
type UndoableState (line 6) | public interface UndoableState<T> extends Cloneable {
method clone (line 7) | T clone();
FILE: droidux/src/main/java/info/izumin/android/droidux/UndoableStoreImpl.java
class UndoableStoreImpl (line 8) | public abstract class UndoableStoreImpl<T extends UndoableState<T>, R> e...
method UndoableStoreImpl (line 13) | protected UndoableStoreImpl(T state, R reducer) {
method dispatch (line 18) | @Override
method setStateWithoutKeepingHistory (line 28) | protected void setStateWithoutKeepingHistory(T state) {
method setState (line 32) | @Override
method getState (line 38) | @Override
method getHistory (line 43) | public History<T> getHistory() {
method isUndoable (line 47) | public boolean isUndoable() {
method isRedoable (line 51) | public boolean isRedoable() {
method setLimit (line 55) | public void setLimit(int limit) {
FILE: droidux/src/main/java/info/izumin/android/droidux/action/HistoryAction.java
class HistoryAction (line 16) | public class HistoryAction implements Action {
type Kind (line 19) | enum Kind {
method handle (line 21) | @Override
method handle (line 27) | @Override
method handle (line 33) | abstract <T extends UndoableState<T>> T handle(History<T> history);
method HistoryAction (line 39) | public HistoryAction(Kind kind, Class targetReducerType) {
method isAssignableTo (line 49) | public <R> boolean isAssignableTo(R reducer) {
method handle (line 53) | public <T extends UndoableState<T>> T handle(History<T> history) {
method getNecessaryAnnotationTypes (line 57) | protected Set<Class<? extends Annotation>> getNecessaryAnnotationTypes...
FILE: droidux/src/main/java/info/izumin/android/droidux/action/RedoAction.java
class RedoAction (line 6) | public class RedoAction extends HistoryAction {
method RedoAction (line 9) | public RedoAction(Class targetReducerType) {
FILE: droidux/src/main/java/info/izumin/android/droidux/action/UndoAction.java
class UndoAction (line 6) | public class UndoAction extends HistoryAction {
method UndoAction (line 9) | public UndoAction(Class targetReducerType) {
FILE: droidux/src/main/java/info/izumin/android/droidux/exception/NotInitializedException.java
class NotInitializedException (line 6) | public class NotInitializedException extends RuntimeException {
method NotInitializedException (line 7) | public NotInitializedException(String message) {
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/Counter.java
class Counter (line 6) | public class Counter {
method Counter (line 11) | public Counter(int count) {
method getCount (line 15) | public int getCount() {
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/CounterReducer.java
class CounterReducer (line 11) | @Reducer(Counter.class)
method increment (line 15) | @Dispatchable(IncrementCountAction.class)
method decrement (line 20) | @Dispatchable(DecrementCountAction.class)
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainActivity.java
class MainActivity (line 12) | public class MainActivity extends AppCompatActivity implements MainEvent...
method onCreate (line 16) | @Override
method onClickBtnIncrement (line 29) | @Override
method onClickBtnDecrement (line 34) | @Override
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainEventHandlers.java
type MainEventHandlers (line 8) | public interface MainEventHandlers {
method onClickBtnIncrement (line 9) | void onClickBtnIncrement(View v);
method onClickBtnDecrement (line 10) | void onClickBtnDecrement(View v);
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/RootStore.java
type RootStore (line 11) | @Store(CounterReducer.class)
method getCounter (line 13) | @Bindable Counter getCounter();
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/DecrementCountAction.java
class DecrementCountAction (line 8) | public class DecrementCountAction implements Action {
FILE: examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/IncrementCountAction.java
class IncrementCountAction (line 8) | public class IncrementCountAction implements Action {
FILE: examples/todomvc/src/androidTest/java/info/izumin/android/droidux/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/App.java
class App (line 14) | public class App extends Application {
method onCreate (line 19) | @Override
method getStore (line 28) | public RootStore getStore() {
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivity.java
class MainActivity (line 9) | public class MainActivity extends AppCompatActivity {
method onCreate (line 15) | @Override
method onCreateOptionsMenu (line 24) | @Override
method onOptionsItemSelected (line 30) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivityHelper.java
class MainActivityHelper (line 24) | public class MainActivityHelper {
method MainActivityHelper (line 34) | public MainActivityHelper(MainActivity activity) {
method onCreate (line 38) | public void onCreate() {
method onOptionItemSelected (line 68) | public boolean onOptionItemSelected(MenuItem item) {
method observeOnClickBtnAddTodo (line 78) | private Flowable<String> observeOnClickBtnAddTodo() {
method observeOnClickListItem (line 84) | private Flowable<Long> observeOnClickListItem() {
method observeOnLongClickListItem (line 90) | private Flowable<Long> observeOnLongClickListItem() {
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/RootStore.java
type RootStore (line 13) | @Store(TodoListReducer.class)
method todoList (line 15) | TodoList todoList();
method observeTodoList (line 16) | Flowable<TodoList> observeTodoList();
method observeTodoList (line 17) | Flowable<TodoList> observeTodoList(BackpressureStrategy strategy);
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/TodoListAdapter.java
class TodoListAdapter (line 16) | public class TodoListAdapter extends BaseAdapter {
method TodoListAdapter (line 24) | public TodoListAdapter(Context context) {
method getCount (line 31) | @Override
method getItem (line 36) | @Override
method getItemId (line 41) | @Override
method getView (line 46) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/AddTodoAction.java
class AddTodoAction (line 10) | public class AddTodoAction implements Action {
method AddTodoAction (line 15) | public AddTodoAction(String text) {
method getText (line 19) | public String getText() {
method toString (line 23) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/ClearCompletedTodoAction.java
class ClearCompletedTodoAction (line 8) | public class ClearCompletedTodoAction implements Action {
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/DeleteTodoAction.java
class DeleteTodoAction (line 10) | public class DeleteTodoAction implements Action {
method DeleteTodoAction (line 15) | public DeleteTodoAction(long id) {
method getId (line 19) | public long getId() {
method toString (line 23) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/ToggleCompletedTodoAction.java
class ToggleCompletedTodoAction (line 10) | public class ToggleCompletedTodoAction implements Action {
method ToggleCompletedTodoAction (line 15) | public ToggleCompletedTodoAction(int id) {
method getId (line 19) | public int getId() {
method toString (line 23) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/entity/TodoList.java
class TodoList (line 13) | public class TodoList {
method TodoList (line 18) | public TodoList(List<Todo> todoList) {
method getTodoList (line 22) | public List<Todo> getTodoList() {
method getTodoById (line 26) | public Todo getTodoById(int id) {
method toString (line 31) | @Override
class Todo (line 36) | public static class Todo {
method Todo (line 41) | public Todo(int id, String text) {
method Todo (line 47) | public Todo(int id, String text, boolean isCompleted) {
method getId (line 53) | public int getId() {
method isCompleted (line 57) | public boolean isCompleted() {
method getText (line 61) | public String getText() {
method toString (line 65) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/middleware/Logger.java
class Logger (line 13) | public class Logger extends Middleware<RootStore> {
method beforeDispatch (line 16) | @Override
method afterDispatch (line 23) | @Override
FILE: examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/reducer/TodoListReducer.java
class TodoListReducer (line 18) | @Reducer(TodoList.class)
method onAddedTodo (line 22) | @Dispatchable(AddTodoAction.class)
method onCompletedTodo (line 37) | @Dispatchable(ToggleCompletedTodoAction.class)
method onClearCompletedTodo (line 50) | @Dispatchable(ClearCompletedTodoAction.class)
method onDeletedTodo (line 57) | @Dispatchable(DeleteTodoAction.class)
FILE: examples/todos-with-dagger/src/androidTest/java/info/izumin/android/droidux/example/todoswithdagger/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/App.java
class App (line 11) | public class App extends Application {
method onCreate (line 17) | @Override
method getStore (line 24) | public RootStore getStore() {
method getComponent (line 28) | public AppComponent getComponent() {
method setupStore (line 32) | private void setupStore() {
method setupGraph (line 38) | private void setupGraph() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/AppComponent.java
type AppComponent (line 12) | @Singleton
method createMainActivityComponent (line 17) | MainComponent createMainActivityComponent(MainModule module);
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/AppModule.java
class AppModule (line 11) | @Module
method AppModule (line 16) | public AppModule(App app) {
method provideRootStore (line 20) | @Provides
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/RootStore.java
type RootStore (line 12) | @Store(TodoListReducer.class)
method todoList (line 14) | TodoList todoList();
method observeTodoList (line 15) | Flowable<TodoList> observeTodoList();
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/AddTodoAction.java
class AddTodoAction (line 10) | public class AddTodoAction implements Action {
method AddTodoAction (line 15) | public AddTodoAction(String text) {
method getText (line 19) | public String getText() {
method toString (line 23) | @Override
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ClearCompletedTodoAction.java
class ClearCompletedTodoAction (line 8) | public class ClearCompletedTodoAction implements Action {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ClearNewTodoTextAction.java
class ClearNewTodoTextAction (line 8) | public class ClearNewTodoTextAction implements Action {
method ClearNewTodoTextAction (line 11) | public ClearNewTodoTextAction() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/DeleteTodoAction.java
class DeleteTodoAction (line 10) | public class DeleteTodoAction implements Action {
method DeleteTodoAction (line 15) | public DeleteTodoAction(long id) {
method getId (line 19) | public long getId() {
method toString (line 23) | @Override
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ToggleCompletedTodoAction.java
class ToggleCompletedTodoAction (line 10) | public class ToggleCompletedTodoAction implements Action {
method ToggleCompletedTodoAction (line 15) | public ToggleCompletedTodoAction(int id) {
method getId (line 19) | public int getId() {
method toString (line 23) | @Override
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/UpdateNewTodoTextAction.java
class UpdateNewTodoTextAction (line 8) | public class UpdateNewTodoTextAction implements Action {
method UpdateNewTodoTextAction (line 13) | public UpdateNewTodoTextAction(String text) {
method getText (line 17) | public String getText() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/adapter/TodoListAdapter.java
class TodoListAdapter (line 19) | public class TodoListAdapter extends BaseAdapter {
method TodoListAdapter (line 27) | public TodoListAdapter(Context context) {
method getCount (line 34) | @Override
method getItem (line 39) | @Override
method getItemId (line 44) | @Override
method getView (line 49) | @Override
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/entity/TodoList.java
class TodoList (line 14) | public class TodoList extends ArrayList<TodoList.Todo> implements Undoab...
method TodoList (line 17) | public TodoList() {
method TodoList (line 20) | public TodoList(List<Todo> list) {
method getTodoById (line 24) | public Todo getTodoById(int id) {
method clone (line 29) | @Override
method toString (line 34) | @Override
class Todo (line 39) | public static class Todo {
method Todo (line 44) | public Todo(int id, String text) {
method Todo (line 50) | public Todo(int id, String text, boolean isCompleted) {
method getId (line 56) | public int getId() {
method isCompleted (line 60) | public boolean isCompleted() {
method getText (line 64) | public String getText() {
method toString (line 68) | @Override
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainActivity.java
class MainActivity (line 22) | public class MainActivity extends AppCompatActivity implements MainView,...
method onCreate (line 29) | @Override
method onStart (line 39) | @Override
method onStop (line 45) | @Override
method onCreateOptionsMenu (line 51) | @Override
method onOptionsItemSelected (line 57) | @Override
method showToast (line 68) | @Override
method showConfirmDeleteDialog (line 73) | @Override
method clearNewTodoText (line 88) | @Override
method onClickAddTodo (line 93) | @Override
method onItemClick (line 98) | @Override
method onItemLongClick (line 103) | @Override
method getModule (line 109) | protected MainModule getModule() {
method setupComponent (line 113) | private void setupComponent() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainComponent.java
type MainComponent (line 8) | @Subcomponent(
method inject (line 12) | void inject(MainActivity activity);
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainEventHandlers.java
type MainEventHandlers (line 9) | public interface MainEventHandlers {
method onClickAddTodo (line 10) | void onClickAddTodo(View view);
method onItemClick (line 11) | void onItemClick(AdapterView<?> parent, View view, int position, long ...
method onItemLongClick (line 12) | boolean onItemLongClick(AdapterView<?> parent, View view, int position...
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainModule.java
class MainModule (line 10) | @Module
method MainModule (line 16) | public MainModule(MainActivity activity) {
method provideMainPresenter (line 20) | @Provides
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainPresenter.java
class MainPresenter (line 17) | public class MainPresenter {
method MainPresenter (line 29) | public MainPresenter(MainView view, RootStore store) {
method onStart (line 34) | void onStart() {
method onStop (line 57) | void onStop() {
method onClickBtnAddTodo (line 61) | void onClickBtnAddTodo(String text) {
method onClickListItem (line 65) | void onClickListItem(long id) {
method onLongClickListItem (line 69) | void onLongClickListItem(long id) {
method clearCompletedTodo (line 73) | void clearCompletedTodo() {
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainView.java
type MainView (line 8) | public interface MainView {
method showToast (line 9) | void showToast(@StringRes int resId, Object... args);
method showConfirmDeleteDialog (line 10) | void showConfirmDeleteDialog(long id);
method clearNewTodoText (line 11) | void clearNewTodoText();
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/reducer/TodoListReducer.java
class TodoListReducer (line 15) | @Reducer(TodoList.class)
method add (line 19) | @Dispatchable(AddTodoAction.class)
method complete (line 36) | @Dispatchable(ToggleCompletedTodoAction.class)
method clear (line 49) | @Dispatchable(ClearCompletedTodoAction.class)
method delete (line 56) | @Dispatchable(DeleteTodoAction.class)
FILE: examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/util/ViewBindingUtils.java
class ViewBindingUtils (line 11) | public final class ViewBindingUtils {
method ViewBindingUtils (line 12) | private ViewBindingUtils() {
method setTodoAdapter (line 16) | @BindingAdapter("todoAdapter")
FILE: examples/todos-with-dagger/src/test/java/info/izumin/android/droidux/example/todoswithdagger/ExampleUnitTest.java
class ExampleUnitTest (line 10) | public class ExampleUnitTest {
method addition_isCorrect (line 11) | @Test
FILE: examples/todos-with-undo/src/androidTest/java/info/izumin/android/droidux/example/todoswithundo/ApplicationTest.java
class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
method ApplicationTest (line 10) | public ApplicationTest() {
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/App.java
class App (line 12) | public class App extends Application {
method onCreate (line 17) | @Override
method getStore (line 26) | public RootStore getStore() {
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/MainActivity.java
class MainActivity (line 9) | public class MainActivity extends AppCompatActivity {
method onCreate (line 15) | @Override
method onCreateOptionsMenu (line 24) | @Override
method onOptionsItemSelected (line 30) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/MainActivityHelper.java
class MainActivityHelper (line 28) | public class MainActivityHelper {
method MainActivityHelper (line 38) | public MainActivityHelper(MainActivity activity) {
method onCreate (line 42) | public void onCreate() {
method onOptionItemSelected (line 72) | public boolean onOptionItemSelected(MenuItem item) {
method observeOnClickBtnAddTodo (line 88) | private Flowable<String> observeOnClickBtnAddTodo() {
method observeOnClickListItem (line 94) | private Flowable<Long> observeOnClickListItem() {
method observeOnLongClickListItem (line 100) | private Flowable<Long> observeOnLongClickListItem() {
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/RootStore.java
type RootStore (line 12) | @Store(TodoListReducer.class)
method todoList (line 14) | TodoList todoList();
method observeTodoList (line 15) | Flowable<TodoList> observeTodoList();
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/TodoListAdapter.java
class TodoListAdapter (line 16) | public class TodoListAdapter extends BaseAdapter {
method TodoListAdapter (line 24) | public TodoListAdapter(Context context) {
method getCount (line 31) | @Override
method getItem (line 36) | @Override
method getItemId (line 41) | @Override
method getView (line 46) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/AddTodoAction.java
class AddTodoAction (line 10) | public class AddTodoAction implements Action {
method AddTodoAction (line 15) | public AddTodoAction(String text) {
method getText (line 19) | public String getText() {
method toString (line 23) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ClearCompletedTodoAction.java
class ClearCompletedTodoAction (line 8) | public class ClearCompletedTodoAction implements Action {
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/DeleteTodoAction.java
class DeleteTodoAction (line 10) | public class DeleteTodoAction implements Action {
method DeleteTodoAction (line 15) | public DeleteTodoAction(long id) {
method getId (line 19) | public long getId() {
method toString (line 23) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ToggleCompletedTodoAction.java
class ToggleCompletedTodoAction (line 10) | public class ToggleCompletedTodoAction implements Action {
method ToggleCompletedTodoAction (line 15) | public ToggleCompletedTodoAction(int id) {
method getId (line 19) | public int getId() {
method toString (line 23) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/entity/TodoList.java
class TodoList (line 14) | public class TodoList extends ArrayList<TodoList.Todo> implements Undoab...
method TodoList (line 17) | public TodoList() {
method TodoList (line 20) | public TodoList(List<Todo> list) {
method getTodoById (line 24) | public Todo getTodoById(int id) {
method clone (line 29) | @Override
method toString (line 34) | @Override
class Todo (line 39) | public static class Todo {
method Todo (line 44) | public Todo(int id, String text) {
method Todo (line 50) | public Todo(int id, String text, boolean isCompleted) {
method getId (line 56) | public int getId() {
method isCompleted (line 60) | public boolean isCompleted() {
method getText (line 64) | public String getText() {
method toString (line 68) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/middleware/Logger.java
class Logger (line 14) | public class Logger extends Middleware<RootStore> {
method beforeDispatch (line 18) | @Override
method afterDispatch (line 25) | @Override
FILE: examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/reducer/TodoListReducer.java
class TodoListReducer (line 16) | @Undoable
method onAddedTodo (line 21) | @Dispatchable(AddTodoAction.class)
method onCompletedTodo (line 39) | @Dispatchable(ToggleCompletedTodoAction.class)
method onClearCompletedTodo (line 52) | @Dispatchable(ClearCompletedTodoAction.class)
method onDeletedTodo (line 59) | @Dispatchable(DeleteTodoAction.class)
FILE: examples/todos-with-undo/src/test/java/info/izumin/android/droidux/example/todoswithundo/ExampleUnitTest.java
class ExampleUnitTest (line 10) | public class ExampleUnitTest {
method addition_isCorrect (line 11) | @Test
FILE: middlewares/droidux-thunk/src/main/java/info/izumin/android/droidux/thunk/AsyncAction.java
type AsyncAction (line 10) | public interface AsyncAction extends Action {
method call (line 11) | Flowable<Action> call(Dispatcher dispatcher);
FILE: middlewares/droidux-thunk/src/main/java/info/izumin/android/droidux/thunk/ThunkMiddleware.java
class ThunkMiddleware (line 11) | public class ThunkMiddleware extends Middleware {
method beforeDispatch (line 14) | @Override
method afterDispatch (line 34) | @Override
Condensed preview — 183 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (302K chars).
[
{
"path": ".gitignore",
"chars": 1530,
"preview": "# Created by https://www.gitignore.io/api/android,intellij,gradle\n\n### Android ###\n# Built application files\n*.apk\n*.ap_"
},
{
"path": ".travis.yml",
"chars": 548,
"preview": "language: android\njdk: oraclejdk8\nandroid:\n components:\n - tools\n - build-tools-27.0.3\n - android-27\n - ext"
},
{
"path": "LICENSE.md",
"chars": 10228,
"preview": "Apache License\n\nVersion 2.0, January 2004\n\nhttp://www.apache.org/licenses/\n\nTERMS AND CONDITIONS FOR USE, REPRODUCTION, "
},
{
"path": "README.md",
"chars": 12304,
"preview": "# Droidux\n[](https://travis-ci.org/izumin5210/Droidux)\n[![D"
},
{
"path": "build.gradle",
"chars": 1312,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "droidux/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "droidux/build.gradle",
"chars": 657,
"preview": "apply plugin: 'java'\napply plugin: 'groovy'\napply plugin: 'com.novoda.bintray-release'\n\ntargetCompatibility = JavaVersio"
},
{
"path": "droidux/proguard-rules.pro",
"chars": 719,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/Action.java",
"chars": 107,
"preview": "package info.izumin.android.droidux;\n\n/**\n * Created by izumin on 11/2/15.\n */\npublic interface Action {\n}\n"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/BaseStore.java",
"chars": 215,
"preview": "package info.izumin.android.droidux;\n\nimport io.reactivex.Flowable;\nimport io.reactivex.Single;\n\n/**\n * Created by izumi"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/Dispatcher.java",
"chars": 2781,
"preview": "package info.izumin.android.droidux;\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.ListIterator;\n\nim"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/History.java",
"chars": 1528,
"preview": "package info.izumin.android.droidux;\n\nimport java.util.ArrayDeque;\nimport java.util.Deque;\n\n/**\n * Created by izumin on "
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/Middleware.java",
"chars": 699,
"preview": "package info.izumin.android.droidux;\n\nimport io.reactivex.Flowable;\n\n/**\n * Created by izumin on 11/2/15.\n */\npublic abs"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/OnStateChangedListener.java",
"chars": 160,
"preview": "package info.izumin.android.droidux;\n\n/**\n * Created by izumin on 12/6/15.\n */\npublic interface OnStateChangedListener<T"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/StoreImpl.java",
"chars": 1418,
"preview": "package info.izumin.android.droidux;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\nimport io.reactivex.BackpressureS"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/UndoableState.java",
"chars": 151,
"preview": "package info.izumin.android.droidux;\n\n/**\n * Created by izumin on 11/24/15.\n */\npublic interface UndoableState<T> extend"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/UndoableStoreImpl.java",
"chars": 1470,
"preview": "package info.izumin.android.droidux;\n\nimport info.izumin.android.droidux.action.HistoryAction;\n\n/**\n * Created by izumin"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/action/HistoryAction.java",
"chars": 1917,
"preview": "package info.izumin.android.droidux.action;\n\nimport java.lang.annotation.Annotation;\nimport java.util.HashSet;\nimport ja"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/action/RedoAction.java",
"chars": 309,
"preview": "package info.izumin.android.droidux.action;\n\n/**\n * Created by izumin on 11/24/15.\n */\npublic class RedoAction extends H"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/action/UndoAction.java",
"chars": 309,
"preview": "package info.izumin.android.droidux.action;\n\n/**\n * Created by izumin on 11/24/15.\n */\npublic class UndoAction extends H"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/annotation/Dispatchable.java",
"chars": 371,
"preview": "package info.izumin.android.droidux.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Re"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/annotation/Reducer.java",
"chars": 366,
"preview": "package info.izumin.android.droidux.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Re"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/annotation/Store.java",
"chars": 375,
"preview": "package info.izumin.android.droidux.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Re"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/annotation/Undoable.java",
"chars": 346,
"preview": "package info.izumin.android.droidux.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Re"
},
{
"path": "droidux/src/main/java/info/izumin/android/droidux/exception/NotInitializedException.java",
"chars": 238,
"preview": "package info.izumin.android.droidux.exception;\n\n/**\n * Created by izumin on 11/8/15.\n */\npublic class NotInitializedExce"
},
{
"path": "droidux/src/test/groovy/info/izumin/android/droidux/DispatcherTest.groovy",
"chars": 1322,
"preview": "package info.izumin.android.droidux\n\nimport io.reactivex.Flowable\nimport spock.lang.Specification\n\n/**\n * Created by izu"
},
{
"path": "droidux/src/test/groovy/info/izumin/android/droidux/HistoryTest.groovy",
"chars": 3589,
"preview": "package info.izumin.android.droidux\n\nimport spock.lang.Specification;\n\n/**\n * Created by izumin on new Counter(1)new Cou"
},
{
"path": "droidux/src/test/groovy/info/izumin/android/droidux/action/HistoryActionTest.groovy",
"chars": 1853,
"preview": "package info.izumin.android.droidux.action\n\nimport info.izumin.android.droidux.UndoableState\nimport info.izumin.android."
},
{
"path": "droidux-processor/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "droidux-processor/build.gradle",
"chars": 1246,
"preview": "import org.gradle.internal.jvm.Jvm\n\napply plugin: 'java'\napply plugin: 'com.novoda.bintray-release'\n\ntargetCompatibility"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/AbstractProcessingStep.java",
"chars": 730,
"preview": "package info.izumin.android.droidux.processor;\n\nimport com.google.auto.common.BasicAnnotationProcessor;\nimport com.squar"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/DroiduxProcessor.java",
"chars": 876,
"preview": "package info.izumin.android.droidux.processor;\n\nimport com.google.auto.common.BasicAnnotationProcessor;\nimport com.googl"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/ReducerProcessingStep.java",
"chars": 1164,
"preview": "package info.izumin.android.droidux.processor;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common."
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/StoreProcessingStep.java",
"chars": 1687,
"preview": "package info.izumin.android.droidux.processor;\n\nimport com.google.common.collect.ImmutableSet;\nimport com.google.common."
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidDispatchableDeclarationException.java",
"chars": 280,
"preview": "package info.izumin.android.droidux.processor.exception;\n\n/**\n * Created by izumin on 11/7/15.\n */\npublic class InvalidD"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidReducerDeclarationException.java",
"chars": 270,
"preview": "package info.izumin.android.droidux.processor.exception;\n\n/**\n * Created by izumin on 11/8/15.\n */\npublic class InvalidR"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/exception/InvalidStoreDelcarationException.java",
"chars": 267,
"preview": "package info.izumin.android.droidux.processor.exception;\n\n/**\n * Created by izumin on 11/24/15.\n */\npublic class Invalid"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreBuilderClassGenerator.java",
"chars": 8609,
"preview": "package info.izumin.android.droidux.processor.generator;\n\nimport com.google.common.base.Function;\nimport com.google.comm"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreClassGenerator.java",
"chars": 8255,
"preview": "package info.izumin.android.droidux.processor.generator;\n\nimport android.databinding.BaseObservable;\n\nimport com.google."
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/generator/StoreImplClassGenerator.java",
"chars": 5486,
"preview": "package info.izumin.android.droidux.processor.generator;\n\nimport com.google.common.base.Function;\nimport com.google.comm"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/BuilderModel.java",
"chars": 1702,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.squareup.javapoet.ClassName;\nimport com.squareup.javapo"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatchableModel.java",
"chars": 2328,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.common."
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/DispatcherModel.java",
"chars": 853,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.squareup.javapoet.FieldSpec;\n\nimport javax.lang.model.e"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/ReducerModel.java",
"chars": 3271,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.squareup.javapoet.ClassName;\n\nimport java.util.ArrayLis"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreImplModel.java",
"chars": 3029,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.squareup.javapoet.ClassName;\n\nimport static info.izumin"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreMethodModel.java",
"chars": 6152,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport android.databinding.Bindable;\n\nimport com.google.auto.commo"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/model/StoreModel.java",
"chars": 4710,
"preview": "package info.izumin.android.droidux.processor.model;\n\nimport com.google.common.base.Function;\nimport com.google.common.b"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/AnnotationUtils.java",
"chars": 3312,
"preview": "package info.izumin.android.droidux.processor.util;\n\nimport com.google.common.base.Function;\nimport com.google.common.ba"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/PoetUtils.java",
"chars": 1510,
"preview": "package info.izumin.android.droidux.processor.util;\n\nimport com.squareup.javapoet.AnnotationSpec;\nimport com.squareup.ja"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/util/StringUtils.java",
"chars": 1013,
"preview": "package info.izumin.android.droidux.processor.util;\n\n/**\n * Created by izumin on 11/2/15.\n */\npublic final class StringU"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/DispatchableValidator.java",
"chars": 2278,
"preview": "package info.izumin.android.droidux.processor.validator;\n\nimport com.squareup.javapoet.ClassName;\n\nimport javax.lang.mod"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/ReducerValidator.java",
"chars": 2226,
"preview": "package info.izumin.android.droidux.processor.validator;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.com"
},
{
"path": "droidux-processor/src/main/java/info/izumin/android/droidux/processor/validator/StoreValidator.java",
"chars": 2423,
"preview": "package info.izumin.android.droidux.processor.validator;\n\nimport com.google.auto.common.MoreTypes;\nimport com.google.com"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/DroiduxProcessorTest.java",
"chars": 8083,
"preview": "package info.izumin.android.droidux.processor;\n\nimport org.junit.Rule;\nimport org.junit.Test;\nimport org.junit.rules.Exp"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Counter.java",
"chars": 338,
"preview": "package info.izumin.android.droidux.processor.fixture;\n\n/**\n * Created by izumin on 11/2/15.\n */\npublic class Counter {\n"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/CounterReducer.java",
"chars": 1214,
"preview": "package info.izumin.android.droidux.processor.fixture;\n\nimport info.izumin.android.droidux.annotation.Dispatchable;\nimpo"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/Source.java",
"chars": 42296,
"preview": "package info.izumin.android.droidux.processor.fixture;\n\n/**\n * Created by izumin on 11/2/15.\n */\npublic final class Sour"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoList.java",
"chars": 844,
"preview": "package info.izumin.android.droidux.processor.fixture;\n\nimport java.util.ArrayList;\n\nimport info.izumin.android.droidux."
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/TodoListReducer.java",
"chars": 694,
"preview": "package info.izumin.android.droidux.processor.fixture;\n\nimport info.izumin.android.droidux.annotation.Dispatchable;\nimpo"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/AddTodoItemAction.java",
"chars": 452,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/ClearCountAction.java",
"chars": 316,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/CompleteTodoItemAction.java",
"chars": 440,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/IncrementCountAction.java",
"chars": 452,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/InitializeCountAction.java",
"chars": 455,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "droidux-processor/src/test/java/info/izumin/android/droidux/processor/fixture/action/SquareCountAction.java",
"chars": 319,
"preview": "package info.izumin.android.droidux.processor.fixture.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Create"
},
{
"path": "examples/counter/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "examples/counter/build.gradle",
"chars": 1299,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion project.compileSdkVersion\n buildToolsVersion"
},
{
"path": "examples/counter/proguard-rules.pro",
"chars": 657,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "examples/counter/src/main/AndroidManifest.xml",
"chars": 652,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/Counter.java",
"chars": 342,
"preview": "package info.izumin.android.droidux.example.counter;\n\n/**\n * Created by izumin on 12/6/15.\n */\npublic class Counter {\n "
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/CounterReducer.java",
"chars": 800,
"preview": "package info.izumin.android.droidux.example.counter;\n\nimport info.izumin.android.droidux.annotation.Dispatchable;\nimport"
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainActivity.java",
"chars": 1261,
"preview": "package info.izumin.android.droidux.example.counter;\n\nimport android.databinding.DataBindingUtil;\nimport android.os.Bund"
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/MainEventHandlers.java",
"chars": 237,
"preview": "package info.izumin.android.droidux.example.counter;\n\nimport android.view.View;\n\n/**\n * Created by izumin on 12/6/15.\n *"
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/RootStore.java",
"chars": 379,
"preview": "package info.izumin.android.droidux.example.counter;\n\nimport android.databinding.Bindable;\n\nimport info.izumin.android.d"
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/DecrementCountAction.java",
"chars": 283,
"preview": "package info.izumin.android.droidux.example.counter.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Created "
},
{
"path": "examples/counter/src/main/java/info/izumin/android/droidux/example/counter/action/IncrementCountAction.java",
"chars": 283,
"preview": "package info.izumin.android.droidux.example.counter.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Created "
},
{
"path": "examples/counter/src/main/res/layout/activity_main.xml",
"chars": 2158,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/counter/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "examples/counter/src/main/res/values/dimens.xml",
"chars": 318,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "examples/counter/src/main/res/values/strings.xml",
"chars": 159,
"preview": "<resources>\n <string name=\"app_name\">Counter</string>\n\n <string name=\"btn_increment\">+</string>\n <string name=\""
},
{
"path": "examples/counter/src/main/res/values/styles.xml",
"chars": 383,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "examples/counter/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "examples/todomvc/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "examples/todomvc/build.gradle",
"chars": 1382,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion project.compileSdkVersion\n buildToolsVersion"
},
{
"path": "examples/todomvc/proguard-rules.pro",
"chars": 657,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "examples/todomvc/src/androidTest/java/info/izumin/android/droidux/ApplicationTest.java",
"chars": 358,
"preview": "package info.izumin.android.droidux;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <"
},
{
"path": "examples/todomvc/src/main/AndroidManifest.xml",
"chars": 826,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/App.java",
"chars": 844,
"preview": "package info.izumin.android.droidux.example.todomvc;\n\nimport android.app.Application;\n\nimport java.util.ArrayList;\n\nimpo"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivity.java",
"chars": 1066,
"preview": "package info.izumin.android.droidux.example.todomvc;\n\nimport android.databinding.DataBindingUtil;\nimport android.os.Bund"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/MainActivityHelper.java",
"chars": 4336,
"preview": "package info.izumin.android.droidux.example.todomvc;\n\nimport android.support.v7.app.AlertDialog;\nimport android.view.Men"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/RootStore.java",
"chars": 629,
"preview": "package info.izumin.android.droidux.example.todomvc;\n\nimport info.izumin.android.droidux.BaseStore;\nimport info.izumin.a"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/TodoListAdapter.java",
"chars": 1861,
"preview": "package info.izumin.android.droidux.example.todomvc;\n\nimport android.content.Context;\nimport android.databinding.DataBin"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/AddTodoAction.java",
"chars": 554,
"preview": "package info.izumin.android.droidux.example.todomvc.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.android.dr"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/ClearCompletedTodoAction.java",
"chars": 291,
"preview": "package info.izumin.android.droidux.example.todomvc.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Created "
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/DeleteTodoAction.java",
"chars": 545,
"preview": "package info.izumin.android.droidux.example.todomvc.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.android.dr"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/action/ToggleCompletedTodoAction.java",
"chars": 569,
"preview": "package info.izumin.android.droidux.example.todomvc.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.android.dr"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/entity/TodoList.java",
"chars": 1517,
"preview": "package info.izumin.android.droidux.example.todomvc.entity;\n\nimport com.google.gson.Gson;\n\nimport java.util.List;\n\nimpor"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/middleware/Logger.java",
"chars": 882,
"preview": "package info.izumin.android.droidux.example.todomvc.middleware;\n\nimport android.util.Log;\n\nimport info.izumin.android.dr"
},
{
"path": "examples/todomvc/src/main/java/info/izumin/android/droidux/example/todomvc/reducer/TodoListReducer.java",
"chars": 2541,
"preview": "package info.izumin.android.droidux.example.todomvc.reducer;\n\nimport java.util.List;\n\nimport info.izumin.android.droidux"
},
{
"path": "examples/todomvc/src/main/res/layout/activity_main.xml",
"chars": 1720,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todomvc/src/main/res/layout/list_item_todo.xml",
"chars": 1259,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todomvc/src/main/res/menu/main_manu.xml",
"chars": 316,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "examples/todomvc/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "examples/todomvc/src/main/res/values/dimens.xml",
"chars": 254,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "examples/todomvc/src/main/res/values/strings.xml",
"chars": 718,
"preview": "<resources>\n <string name=\"app_name\">TodoMVC</string>\n <string name=\"title_activity_main\">TodoMVC</string>\n\n <s"
},
{
"path": "examples/todomvc/src/main/res/values/styles.xml",
"chars": 705,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "examples/todomvc/src/main/res/values-v21/styles.xml",
"chars": 327,
"preview": "<resources>>\n <style name=\"AppTheme.NoActionBar\">\n <item name=\"windowActionBar\">false</item>\n <item nam"
},
{
"path": "examples/todomvc/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "examples/todos-with-dagger/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "examples/todos-with-dagger/build.gradle",
"chars": 1887,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion project.compileSdkVersion\n buildToolsVersion"
},
{
"path": "examples/todos-with-dagger/proguard-rules.pro",
"chars": 657,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "examples/todos-with-dagger/src/androidTest/java/info/izumin/android/droidux/example/todoswithdagger/ApplicationTest.java",
"chars": 382,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport android.app.Application;\nimport android.test.Applic"
},
{
"path": "examples/todos-with-dagger/src/main/AndroidManifest.xml",
"chars": 732,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/App.java",
"chars": 1062,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport android.app.Application;\n\nimport info.izumin.androi"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/AppComponent.java",
"chars": 490,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport javax.inject.Singleton;\n\nimport dagger.Component;\ni"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/AppModule.java",
"chars": 411,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport javax.inject.Singleton;\n\nimport dagger.Module;\nimpo"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/RootStore.java",
"chars": 540,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport info.izumin.android.droidux.BaseStore;\nimport info."
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/AddTodoAction.java",
"chars": 562,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.an"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ClearCompletedTodoAction.java",
"chars": 299,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * "
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ClearNewTodoTextAction.java",
"chars": 340,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * "
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/DeleteTodoAction.java",
"chars": 553,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.an"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/ToggleCompletedTodoAction.java",
"chars": 577,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.an"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/action/UpdateNewTodoTextAction.java",
"chars": 470,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * "
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/adapter/TodoListAdapter.java",
"chars": 2061,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.adapter;\n\nimport android.content.Context;\nimport android.dat"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/entity/TodoList.java",
"chars": 1663,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.entity;\n\nimport com.google.gson.Gson;\n\nimport java.util.Arra"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainActivity.java",
"chars": 3745,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport android.databinding.DataBindingUtil;\nim"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainComponent.java",
"chars": 272,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport dagger.Subcomponent;\n\n/**\n * Created by"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainEventHandlers.java",
"chars": 417,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport android.view.View;\nimport android.widge"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainModule.java",
"chars": 600,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport dagger.Module;\nimport dagger.Provides;\n"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainPresenter.java",
"chars": 2935,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport info.izumin.android.droidux.example.tod"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/module/main/MainView.java",
"chars": 321,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.module.main;\n\nimport android.support.annotation.StringRes;\n\n"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/reducer/TodoListReducer.java",
"chars": 2558,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.reducer;\n\nimport info.izumin.android.droidux.annotation.Disp"
},
{
"path": "examples/todos-with-dagger/src/main/java/info/izumin/android/droidux/example/todoswithdagger/util/ViewBindingUtils.java",
"chars": 602,
"preview": "package info.izumin.android.droidux.example.todoswithdagger.util;\n\nimport android.databinding.BindingAdapter;\nimport and"
},
{
"path": "examples/todos-with-dagger/src/main/res/layout/activity_main.xml",
"chars": 2311,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todos-with-dagger/src/main/res/layout/list_item_todo.xml",
"chars": 1267,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todos-with-dagger/src/main/res/menu/main_manu.xml",
"chars": 316,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "examples/todos-with-dagger/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "examples/todos-with-dagger/src/main/res/values/dimens.xml",
"chars": 211,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "examples/todos-with-dagger/src/main/res/values/strings.xml",
"chars": 834,
"preview": "<resources>\n <string name=\"app_name\">Todos with Dagger</string>\n <string name=\"title_activity_main\">Todos with Dag"
},
{
"path": "examples/todos-with-dagger/src/main/res/values/styles.xml",
"chars": 383,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "examples/todos-with-dagger/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "examples/todos-with-dagger/src/test/java/info/izumin/android/droidux/example/todoswithdagger/ExampleUnitTest.java",
"chars": 344,
"preview": "package info.izumin.android.droidux.example.todoswithdagger;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n"
},
{
"path": "examples/todos-with-undo/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "examples/todos-with-undo/build.gradle",
"chars": 1389,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion project.compileSdkVersion\n buildToolsVersion"
},
{
"path": "examples/todos-with-undo/proguard-rules.pro",
"chars": 657,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "examples/todos-with-undo/src/androidTest/java/info/izumin/android/droidux/example/todoswithundo/ApplicationTest.java",
"chars": 380,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport android.app.Application;\nimport android.test.Applicat"
},
{
"path": "examples/todos-with-undo/src/main/AndroidManifest.xml",
"chars": 718,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/App.java",
"chars": 822,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport android.app.Application;\n\nimport info.izumin.android."
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/MainActivity.java",
"chars": 1072,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport android.databinding.DataBindingUtil;\nimport android.o"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/MainActivityHelper.java",
"chars": 4888,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport android.support.v7.app.AlertDialog;\nimport android.vi"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/RootStore.java",
"chars": 534,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport info.izumin.android.droidux.BaseStore;\nimport info.iz"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/TodoListAdapter.java",
"chars": 1851,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport android.content.Context;\nimport android.databinding.D"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/AddTodoAction.java",
"chars": 560,
"preview": "package info.izumin.android.droidux.example.todoswithundo.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.andr"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ClearCompletedTodoAction.java",
"chars": 297,
"preview": "package info.izumin.android.droidux.example.todoswithundo.action;\n\nimport info.izumin.android.droidux.Action;\n\n/**\n * Cr"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/DeleteTodoAction.java",
"chars": 551,
"preview": "package info.izumin.android.droidux.example.todoswithundo.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.andr"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/action/ToggleCompletedTodoAction.java",
"chars": 575,
"preview": "package info.izumin.android.droidux.example.todoswithundo.action;\n\nimport com.google.gson.Gson;\n\nimport info.izumin.andr"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/entity/TodoList.java",
"chars": 1661,
"preview": "package info.izumin.android.droidux.example.todoswithundo.entity;\n\nimport com.google.gson.Gson;\n\nimport java.util.ArrayL"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/middleware/Logger.java",
"chars": 923,
"preview": "package info.izumin.android.droidux.example.todoswithundo.middleware;\n\nimport android.util.Log;\n\nimport info.izumin.andr"
},
{
"path": "examples/todos-with-undo/src/main/java/info/izumin/android/droidux/example/todoswithundo/reducer/TodoListReducer.java",
"chars": 2715,
"preview": "package info.izumin.android.droidux.example.todoswithundo.reducer;\n\nimport info.izumin.android.droidux.annotation.Dispat"
},
{
"path": "examples/todos-with-undo/src/main/res/layout/activity_main.xml",
"chars": 1720,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todos-with-undo/src/main/res/layout/list_item_todo.xml",
"chars": 1265,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tool"
},
{
"path": "examples/todos-with-undo/src/main/res/menu/main_manu.xml",
"chars": 568,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:app=\"h"
},
{
"path": "examples/todos-with-undo/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "examples/todos-with-undo/src/main/res/values/dimens.xml",
"chars": 254,
"preview": "<resources>\n <!-- Default screen margins, per the Android Design guidelines. -->\n <dimen name=\"activity_horizontal"
},
{
"path": "examples/todos-with-undo/src/main/res/values/strings.xml",
"chars": 830,
"preview": "<resources>\n <string name=\"app_name\">Todos with undo</string>\n <string name=\"title_activity_main\">Todos with undo<"
},
{
"path": "examples/todos-with-undo/src/main/res/values/styles.xml",
"chars": 705,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
},
{
"path": "examples/todos-with-undo/src/main/res/values-w820dp/dimens.xml",
"chars": 358,
"preview": "<resources>\n <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n (such as s"
},
{
"path": "examples/todos-with-undo/src/test/java/info/izumin/android/droidux/example/todoswithundo/ExampleUnitTest.java",
"chars": 342,
"preview": "package info.izumin.android.droidux.example.todoswithundo;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 230,
"preview": "#Mon Jan 01 18:04:23 JST 2018\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 978,
"preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 5080,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2314,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "middlewares/droidux-thunk/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "middlewares/droidux-thunk/build.gradle",
"chars": 565,
"preview": "apply plugin: 'java'\napply plugin: 'groovy'\napply plugin: 'com.novoda.bintray-release'\n\ntargetCompatibility = JavaVersio"
},
{
"path": "middlewares/droidux-thunk/proguard-rules.pro",
"chars": 657,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /u"
},
{
"path": "middlewares/droidux-thunk/src/main/AndroidManifest.xml",
"chars": 281,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"info.izumin.android.droidux.thunk\">\n\n "
},
{
"path": "middlewares/droidux-thunk/src/main/java/info/izumin/android/droidux/thunk/AsyncAction.java",
"chars": 305,
"preview": "package info.izumin.android.droidux.thunk;\n\nimport info.izumin.android.droidux.Action;\nimport info.izumin.android.droidu"
},
{
"path": "middlewares/droidux-thunk/src/main/java/info/izumin/android/droidux/thunk/ThunkMiddleware.java",
"chars": 1366,
"preview": "package info.izumin.android.droidux.thunk;\n\nimport info.izumin.android.droidux.Action;\nimport info.izumin.android.droidu"
},
{
"path": "middlewares/droidux-thunk/src/main/res/values/strings.xml",
"chars": 75,
"preview": "<resources>\n <string name=\"app_name\">DroiduxThunk</string>\n</resources>\n"
},
{
"path": "middlewares/droidux-thunk/src/test/groovy/info/izumin/android/droidux/thunk/ThunkMiddlewareTest.groovy",
"chars": 2979,
"preview": "package info.izumin.android.droidux.thunk\n\nimport info.izumin.android.droidux.Action\nimport info.izumin.android.droidux."
},
{
"path": "settings.gradle",
"chars": 180,
"preview": "include ':droidux', ':droidux-processor', ':middlewares:droidux-thunk'\ninclude ':examples:counter', ':examples:todomvc',"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the izumin5210/Droidux GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 183 files (265.8 KB), approximately 66.0k tokens, and a symbol index with 508 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.