Skip to content

Commit

Permalink
Merge branch 'release/1.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
senneco committed Nov 14, 2016
2 parents 810dba5 + ef531d1 commit 45c8e36
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 252 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,29 +75,29 @@ Base modules integration:
```groovy
dependencies {
...
compile 'com.arello-mobile:moxy:1.1.2'
provided 'com.arello-mobile:moxy-compiler:1.1.2'
compile 'com.arello-mobile:moxy:1.2.0'
provided 'com.arello-mobile:moxy-compiler:1.2.0'
}
```
If you want to see generated code, use `apt` instead of `provided` dependency type:
```groovy
dependencies {
...
apt 'com.arello-mobile:moxy-compiler:1.1.2'
apt 'com.arello-mobile:moxy-compiler:1.2.0'
}
```
For additional base view classes `MvpActivity` and `MvpFragment` add this:
```groovy
dependencies {
...
compile 'com.arello-mobile:moxy-android:1.1.2'
compile 'com.arello-mobile:moxy-android:1.2.0'
}
```
If you planing to use AppCompat, then you can use `MvpAppCompatActivity` and `MvpAppCompatFragment`. Then add this:
```groovy
dependencies {
...
compile 'com.arello-mobile:moxy-app-compat:1.1.2'
compile 'com.arello-mobile:moxy-app-compat:1.2.0'
compile 'com.android.support:appcompat-v7:$support_version'
}
```
Expand All @@ -106,7 +106,7 @@ If you are using kotlin, use `kapt` instead of `provided`/`apt` dependency type
```groovy
dependencies {
...
kapt 'com.arello-mobile:moxy-compiler:1.1.2'
kapt 'com.arello-mobile:moxy-compiler:1.2.0'
}
kapt {
generateStubs = true
Expand Down
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ allprojects {
}

ext {
targetVersionCode = 27
targetVersionName = "1.1.2"
targetVersionCode = 28
targetVersionName = "1.2.0"
}

task clean(type: Delete) {
Expand Down
4 changes: 2 additions & 2 deletions moxy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,8 @@ assemble.dependsOn copyVersion

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compileOnly 'com.google.android:android:1.5_r3'
javadocDeps 'com.google.android:android:1.5_r3'
compileOnly 'com.google.android:android:1.6_r2'
javadocDeps 'com.google.android:android:1.6_r2'

testCompile project(':moxy-compiler')
testCompile 'com.google.android:android:1.5_r3'
Expand Down
7 changes: 5 additions & 2 deletions moxy/src/main/java/com/arellomobile/mvp/MvpDelegate.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* so the instance returned from {@link #MvpDelegate(Object)}} should be kept
* until the Object is destroyed.
*
* @author Yuri Shmakov
* @author Alexander Blinov
* @author Konstantin Tckhovrebov
*/
Expand Down Expand Up @@ -146,12 +147,14 @@ public void onDetach() {
* <p>Destroy presenters.</p>
*/
public void onDestroy() {
PresentersCounter presentersCounter = MvpFacade.getInstance().getPresentersCounter();
PresenterStore presenterStore = MvpFacade.getInstance().getPresenterStore();

for (MvpPresenter<?> presenter : mPresenters) {
if (presenter.getPresenterType() == PresenterType.LOCAL) {
boolean isRejected = presentersCounter.rejectPresenter(presenter, mDelegateTag);
if (isRejected && presenter.getPresenterType() != PresenterType.GLOBAL) {
presenterStore.remove(presenter.getPresenterType(), presenter.getTag(), presenter.getPresenterClass());
presenter.onDestroy();
presenterStore.remove(PresenterType.LOCAL, presenter.getTag(), presenter.getPresenterClass());
}
}

Expand Down
12 changes: 11 additions & 1 deletion moxy/src/main/java/com/arellomobile/mvp/MvpFacade.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* @author Alexander Blinov
* @author Yuri Shmakov
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public final class MvpFacade {
private static volatile MvpFacade sInstance;

Expand All @@ -28,13 +29,14 @@ public static void init() {
}

private MvpFacade() {
mPresentersCounter = new PresentersCounter();
mPresenterStore = new PresenterStore();
mMvpProcessor = new MvpProcessor();
}

private PresenterStore mPresenterStore;

private MvpProcessor mMvpProcessor;
private PresentersCounter mPresentersCounter;

public PresenterStore getPresenterStore() {
return mPresenterStore;
Expand All @@ -51,4 +53,12 @@ public MvpProcessor getMvpProcessor() {
public void setMvpProcessor(MvpProcessor mvpProcessor) {
mMvpProcessor = mvpProcessor;
}

public PresentersCounter getPresentersCounter() {
return mPresentersCounter;
}

public void setPresentersCounter(PresentersCounter presentersCounter) {
mPresentersCounter = presentersCounter;
}
}
15 changes: 9 additions & 6 deletions moxy/src/main/java/com/arellomobile/mvp/MvpProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
* Date: 18-Dec-15
* Time: 13:16
*
* @author Alexander Blinov
* @author Yuri Shmakov
* @author Alexander Blinov
*/
public class MvpProcessor {
private static final String TAG = "MvpProcessor";
Expand Down Expand Up @@ -79,16 +79,14 @@ private <Delegated> PresenterBinder<? super Delegated> findPresenterBinderForCla
* 3)If {@link com.arellomobile.mvp.PresenterStore} doesn't contain MvpPresenter with current tag, {@link PresenterField} will create it
*
* @param presenterField info about presenter from {@link com.arellomobile.mvp.presenter.InjectPresenter}
* @param delegated class contains presenter
* @param delegateTag unique tag generated by {@link MvpDelegate#generateTag()}
* @param <Delegated> type of delegated
* @return MvpPresenter instance
*/
private <Delegated> MvpPresenter<? super Delegated> getMvpPresenter(PresenterField<?, ? super Delegated> presenterField, Delegated delegated, String delegateTag) {
private <Delegated> MvpPresenter<? super Delegated> getMvpPresenter(PresenterField<?, ? super Delegated> presenterField, String delegateTag) {
Class<? extends MvpPresenter<?>> presenterClass = presenterField.getPresenterClass();
PresenterStore presenterStore = MvpFacade.getInstance().getPresenterStore();

//TODO throw exception
PresenterType type = presenterField.getPresenterType();
//noinspection unchecked
String tag = type == PresenterType.LOCAL ? delegateTag + "$" : "";
Expand All @@ -100,6 +98,7 @@ private <Delegated> MvpPresenter<? super Delegated> getMvpPresenter(PresenterFie
return presenter;
}

//noinspection unchecked
presenter = (MvpPresenter<? super Delegated>) presenterField.providePresenter();

if (presenter == null) {
Expand Down Expand Up @@ -130,8 +129,11 @@ <Delegated> List<MvpPresenter<? super Delegated>> getMvpPresenters(Delegated del
Class<? super Delegated> aClass = (Class<Delegated>) delegated.getClass();
List<PresenterBinder<? super Delegated>> presenterBinders = new ArrayList<>();

MvpProcessor mvpProcessor = MvpFacade.getInstance().getMvpProcessor();
PresentersCounter presentersCounter = MvpFacade.getInstance().getPresentersCounter();

while (aClass != Object.class) {
PresenterBinder<? super Delegated> presenterBinder = MvpFacade.getInstance().getMvpProcessor().getPresenterBinder(aClass);
PresenterBinder<? super Delegated> presenterBinder = mvpProcessor.getPresenterBinder(aClass);

aClass = aClass.getSuperclass();

Expand All @@ -152,9 +154,10 @@ <Delegated> List<MvpPresenter<? super Delegated>> getMvpPresenters(Delegated del
List<? extends PresenterField<?, ? super Delegated>> presenterFields = presenterBinder.getPresenterFields();

for (PresenterField<?, ? super Delegated> presenterField : presenterFields) {
MvpPresenter<? super Delegated> presenter = getMvpPresenter(presenterField, delegated, delegateTag);
MvpPresenter<? super Delegated> presenter = getMvpPresenter(presenterField, delegateTag);

if (presenter != null) {
presentersCounter.injectPresenter(presenter, delegateTag);
presenters.add(presenter);
presenterField.setValue(presenter);
}
Expand Down
112 changes: 65 additions & 47 deletions moxy/src/main/java/com/arellomobile/mvp/PresenterStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,91 @@
* Date: 17-Dec-15
* Time: 16:05
*
* @author Yuri Shmakov
* @author Alexander Blinov
*/
@SuppressWarnings("WeakerAccess")
public class PresenterStore {
private Map<Class<? extends MvpPresenter>, Map<String, MvpPresenter>> mGlobalPresenters = new HashMap<>();
private Map<Class<? extends MvpPresenter>, Map<String, MvpPresenter>> mWeakPresenters = new WeakValueHashMap<>();
private Map<Key, MvpPresenter> mPresenters = new HashMap<>();

/**
* Add presenter to storage
*
* @param type Type is presenter local, global or weak
* @param tag Object to store presenter
* @param tag Tag of presenter
* @param clazz Presenter class
* @param instance Instance of MvpPresenter implementation to store
* @param <T> type of presenter
* @param <T> Type of presenter
*/
public <T extends MvpPresenter> void add(PresenterType type, String tag, Class<? extends MvpPresenter> clazz, T instance) {
Map<String, MvpPresenter> mvpPresenterMap;

final Map<Class<? extends MvpPresenter>, Map<String, MvpPresenter>> presenters = getPresenters(type);

if (presenters.containsKey(clazz)) {
mvpPresenterMap = presenters.get(clazz);
} else {
mvpPresenterMap = createPresentersStore(type);
presenters.put(clazz, mvpPresenterMap);
}

if (mvpPresenterMap.containsKey(tag)) {
throw new IllegalStateException("mvp multiple presenters map already contains tag");
}

mvpPresenterMap.put(tag, instance);
Key key = new Key(type, clazz, tag);
mPresenters.put(key, instance);
}

/**
* Get presenter on existing params
*
* @param type Type is presenter local, global or weak
* @param tag Tag of presenter
* @param clazz Presenter class
* @return Presenter if it's exists. Null otherwise (if it's no exists)
*/
public MvpPresenter get(PresenterType type, String tag, Class<? extends MvpPresenter> clazz) {
Map<String, MvpPresenter> tagMvpPresenterMap = getPresenters(type).get(clazz);

if (tagMvpPresenterMap == null) {
//TODO add builder
return null;
}

//TODO add builder if tagMvpPresenterMap.getPresenterFactory(tag) == null

return tagMvpPresenterMap.get(tag);
Key key = new Key(type, clazz, tag);
return mPresenters.get(key);
}

/**
* Remove presenter from store.
*
* @param type Type is presenter local, global or weak
* @param tag Tag of presenter
* @param clazz Presenter class
* @return Presenter which was removed
*/
public MvpPresenter remove(PresenterType type, String tag, Class<? extends MvpPresenter> clazz) {
Map<String, MvpPresenter> tagMvpPresenterMap = getPresenters(type).get(clazz);

if (tagMvpPresenterMap == null) {
return null;
}

return tagMvpPresenterMap.remove(tag);
Key key = new Key(type, clazz, tag);
return mPresenters.remove(key);
}

protected Map<Class<? extends MvpPresenter>, Map<String, MvpPresenter>> getPresenters(PresenterType type) {
if (type == PresenterType.WEAK) {
return mWeakPresenters;
}
private static class Key {
PresenterType mPresenterType;
Class<? extends MvpPresenter> mPresenterClass;
String mPresenterTag;

return mGlobalPresenters;
}
Key(PresenterType presenterType, Class<? extends MvpPresenter> presenterClass, String presenterTag) {
mPresenterType = presenterType;
mPresenterClass = presenterClass;
mPresenterTag = presenterTag;
}

protected Map<String, MvpPresenter> createPresentersStore(PresenterType type) {
if (type == PresenterType.WEAK) {
return new WeakValueHashMap<>();
@SuppressWarnings("SimplifiableIfStatement")
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

Key key = (Key) o;

if (mPresenterType != key.mPresenterType) {
return false;
}
if (!mPresenterClass.equals(key.mPresenterClass)) {
return false;
}
return mPresenterTag.equals(key.mPresenterTag);
}

return new HashMap<>();
@Override
public int hashCode() {
int result = mPresenterType.hashCode();
result = 31 * result + mPresenterClass.hashCode();
result = 31 * result + mPresenterTag.hashCode();
return result;
}
}
}
58 changes: 58 additions & 0 deletions moxy/src/main/java/com/arellomobile/mvp/PresentersCounter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.arellomobile.mvp;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* Date: 14-Nov-16
* Time: 04:39
*
* @author Yuri Shmakov
*/
@SuppressWarnings("WeakerAccess")
public class PresentersCounter {

private Map<MvpPresenter<?>, Set<String>> mConnections = new HashMap<>();

/**
* Save delegate tag when it inject presenter to delegate's object
*
* @param presenter Injected presenter
* @param delegateTag Delegate tag
*/
public void injectPresenter(MvpPresenter<?> presenter, String delegateTag) {
Set<String> delegateTags = mConnections.get(presenter);
if (delegateTags == null) {
delegateTags = new HashSet<>();
mConnections.put(presenter, delegateTags);
}

delegateTags.add(delegateTag);
}

/**
* Remove tag when delegate's object was fully destroyed
*
* @param presenter Rejected presenter
* @param delegateTag Delegate tag
* @return True if there are no links to this presenter and presenter be able to destroy. False otherwise
*/
public boolean rejectPresenter(MvpPresenter<?> presenter, String delegateTag) {
Set<String> delegateTags = mConnections.get(presenter);
if (delegateTags == null) {
return true;
}
delegateTags.remove(delegateTag);

return delegateTags.isEmpty();
}

@SuppressWarnings("unused")
public boolean isInjected(MvpPresenter<?> presenter) {
Set<String> mDelegateTags = mConnections.get(presenter);

return mDelegateTags != null && !mDelegateTags.isEmpty();
}
}
Loading

0 comments on commit 45c8e36

Please sign in to comment.