From a598ebf72f33d335d5e2ef27b7da90de5782844a Mon Sep 17 00:00:00 2001 From: len Date: Wed, 6 Apr 2016 02:18:04 +0200 Subject: [PATCH] More crash fixes --- app/src/main/AndroidManifest.xml | 4 -- .../tachiyomi/event/ChapterCountEvent.kt | 15 ++++- .../ui/base/fragment/BaseRxFragment.java | 13 ++-- .../ui/base/presenter/BasePresenter.kt | 10 ++++ .../tachiyomi/ui/manga/MangaActivity.kt | 9 ++- .../tachiyomi/ui/manga/MangaPresenter.kt | 43 +++++-------- .../ui/manga/chapter/ChaptersPresenter.kt | 60 +++++++------------ .../ui/manga/info/MangaInfoPresenter.kt | 43 ++----------- .../manga/myanimelist/MyAnimeListPresenter.kt | 15 +---- .../tachiyomi/ui/reader/ReaderActivity.kt | 6 +- .../tachiyomi/ui/reader/ReaderPresenter.kt | 45 ++++++-------- .../ui/recent/RecentChaptersPresenter.kt | 3 +- .../eu/kanade/tachiyomi/util/SharedData.kt | 45 ++++++++++++++ 13 files changed, 147 insertions(+), 164 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/util/SharedData.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6a49a47d2..ce1af5850 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -32,11 +32,7 @@ - () + + val observable: Observable + get() = subject + + fun emit(count: Int) { + subject.onNext(count) + } +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java b/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java index 5a6518207..84044cdc8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/fragment/BaseRxFragment.java @@ -12,7 +12,7 @@ import nucleus.view.PresenterLifecycleDelegate; import nucleus.view.ViewWithPresenter; /** - * This class is an example of how an activity could controls it's presenter. + * This view is an example of how a view should control it's presenter. * You can inherit from this class or copy/paste this class's code to * create your own view implementation. * @@ -87,12 +87,11 @@ public abstract class BaseRxFragment

extends BaseFragment i @Override public void onPause() { super.onPause(); - presenterDelegate.onPause(getActivity().isFinishing() || shouldDestroyPresenter(this)); + presenterDelegate.onPause(getActivity().isFinishing() || isRemoving(this)); } - private boolean shouldDestroyPresenter(Fragment fragment) { - if (fragment == null) return false; - else return fragment.isRemoving() || shouldDestroyPresenter(fragment.getParentFragment()); + private static boolean isRemoving(Fragment fragment) { + Fragment parent = fragment.getParentFragment(); + return fragment.isRemoving() || (parent != null && isRemoving(parent)); } - -} \ No newline at end of file +} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt index c361446c9..bd205f72b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/presenter/BasePresenter.kt @@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.base.presenter import android.content.Context import nucleus.view.ViewWithPresenter import org.greenrobot.eventbus.EventBus +import rx.Observable open class BasePresenter> : RxPresenter() { @@ -16,4 +17,13 @@ open class BasePresenter> : RxPresenter() { EventBus.getDefault().unregister(this) } + fun Observable.subscribeFirst(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) + = compose(deliverFirst()).subscribe(split(onNext, onError)) + + fun Observable.subscribeLatestCache(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) + = compose(deliverLatestCache()).subscribe(split(onNext, onError)) + + fun Observable.subscribeReplay(onNext: (V, T) -> Unit, onError: ((V, Throwable) -> Unit)? = null) + = compose(deliverReplay()).subscribe(split(onNext, onError)) + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.kt index 47c092bd0..76eb210ee 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaActivity.kt @@ -13,15 +13,16 @@ import android.support.v4.app.FragmentPagerAdapter import android.support.v4.content.ContextCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Manga +import eu.kanade.tachiyomi.event.MangaEvent import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersFragment import eu.kanade.tachiyomi.ui.manga.info.MangaInfoFragment import eu.kanade.tachiyomi.ui.manga.myanimelist.MyAnimeListFragment +import eu.kanade.tachiyomi.util.SharedData import kotlinx.android.synthetic.main.activity_manga.* import kotlinx.android.synthetic.main.tab_layout.* import kotlinx.android.synthetic.main.toolbar.* import nucleus.factory.RequiresPresenter -import org.greenrobot.eventbus.EventBus @RequiresPresenter(MangaPresenter::class) class MangaActivity : BaseRxActivity() { @@ -33,11 +34,9 @@ class MangaActivity : BaseRxActivity() { val CHAPTERS_FRAGMENT = 1 val MYANIMELIST_FRAGMENT = 2 - fun newIntent(context: Context, manga: Manga?): Intent { + fun newIntent(context: Context, manga: Manga): Intent { val intent = Intent(context, MangaActivity::class.java) - if (manga != null) { - EventBus.getDefault().postSticky(manga) - } + SharedData.put(MangaEvent(manga)) return intent } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt index 3b68a3986..d7d1867ec 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt @@ -4,11 +4,10 @@ import android.os.Bundle import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager +import eu.kanade.tachiyomi.event.ChapterCountEvent import eu.kanade.tachiyomi.event.MangaEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode +import eu.kanade.tachiyomi.util.SharedData import rx.Observable import javax.inject.Inject @@ -37,32 +36,26 @@ class MangaPresenter : BasePresenter() { */ private val MANGA_KEY = "manga_key" - /** - * Id of the restartable that notifies the view of a manga. - */ - private val GET_MANGA = 1 - override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) - if (savedState != null) { - manga = savedState.getSerializable(MANGA_KEY) as Manga - } - - restartableLatestCache(GET_MANGA, - { Observable.just(manga) - .doOnNext { EventBus.getDefault().postSticky(MangaEvent(it)) } }, - { view, manga -> view.onSetManga(manga) }) - if (savedState == null) { - registerForEvents() + manga = SharedData.get(MangaEvent::class.java)!!.manga + } else { + manga = savedState.getSerializable(MANGA_KEY) as Manga + SharedData.put(MangaEvent(manga)) } + + // Prepare a subject to communicate the chapters and info presenters for the chapter count. + SharedData.put(ChapterCountEvent()) + + add(Observable.just(manga) + .subscribeLatestCache({ view, manga -> view.onSetManga(manga) })) } override fun onDestroy() { - // Avoid new instances receiving wrong manga - EventBus.getDefault().removeStickyEvent(MangaEvent::class.java) - + SharedData.remove(MangaEvent::class.java) + SharedData.remove(ChapterCountEvent::class.java) super.onDestroy() } @@ -71,12 +64,4 @@ class MangaPresenter : BasePresenter() { super.onSave(state) } - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(manga: Manga) { - EventBus.getDefault().removeStickyEvent(manga) - unregisterForEvents() - this.manga = manga - start(GET_MANGA) - } - } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt index 97a68756d..90bdbaa28 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersPresenter.kt @@ -15,9 +15,8 @@ import eu.kanade.tachiyomi.event.DownloadChaptersEvent import eu.kanade.tachiyomi.event.MangaEvent import eu.kanade.tachiyomi.event.ReaderEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.util.SharedData import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import rx.Observable import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers @@ -47,20 +46,15 @@ class ChaptersPresenter : BasePresenter() { var hasRequested: Boolean = false private set - private val GET_MANGA = 1 - private val DB_CHAPTERS = 2 - private val FETCH_CHAPTERS = 3 - private val CHAPTER_STATUS_CHANGES = 4 + private val DB_CHAPTERS = 1 + private val FETCH_CHAPTERS = 2 + private val CHAPTER_STATUS_CHANGES = 3 override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) chaptersSubject = PublishSubject.create() - startableLatestCache(GET_MANGA, - { Observable.just(manga) }, - { view, manga -> view.onNextManga(manga) }) - startableLatestCache(DB_CHAPTERS, { getDbChaptersObs() }, { view, chapters -> view.onNextChapters(chapters) }) @@ -75,36 +69,26 @@ class ChaptersPresenter : BasePresenter() { { view, download -> view.onChapterStatusChange(download) }, { view, error -> Timber.e(error.cause, error.message) }) - registerForEvents() - } + manga = SharedData.get(MangaEvent::class.java)!!.manga + add(Observable.just(manga) + .subscribeLatestCache({ view, manga -> view.onNextManga(manga) })) - override fun onDestroy() { - unregisterForEvents() - EventBus.getDefault().removeStickyEvent(ChapterCountEvent::class.java) - super.onDestroy() - } + source = sourceManager.get(manga.source)!! + start(DB_CHAPTERS) - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(event: MangaEvent) { - this.manga = event.manga - start(GET_MANGA) - - if (isUnsubscribed(DB_CHAPTERS)) { - source = sourceManager.get(manga.source)!! - start(DB_CHAPTERS) - - add(db.getChapters(manga).asRxObservable() - .subscribeOn(Schedulers.io()) - .doOnNext { chapters -> - this.chapters = chapters - EventBus.getDefault().postSticky(ChapterCountEvent(chapters.size)) - for (chapter in chapters) { - setChapterStatus(chapter) - } - start(CHAPTER_STATUS_CHANGES) + add(db.getChapters(manga).asRxObservable() + .subscribeOn(Schedulers.io()) + .doOnNext { chapters -> + this.chapters = chapters + SharedData.get(ChapterCountEvent::class.java)?.let { + it.emit(chapters.size) } - .subscribe { chaptersSubject.onNext(it) }) - } + for (chapter in chapters) { + setChapterStatus(chapter) + } + start(CHAPTER_STATUS_CHANGES) + } + .subscribe { chaptersSubject.onNext(it) }) } fun fetchChaptersFromSource() { @@ -179,7 +163,7 @@ class ChaptersPresenter : BasePresenter() { } fun onOpenChapter(chapter: Chapter) { - EventBus.getDefault().postSticky(ReaderEvent(manga, chapter)) + SharedData.put(ReaderEvent(manga, chapter)) } fun getNextUnreadChapter(): Chapter? { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt index d472e829c..e2136cc24 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/info/MangaInfoPresenter.kt @@ -9,8 +9,7 @@ import eu.kanade.tachiyomi.data.source.base.Source import eu.kanade.tachiyomi.event.ChapterCountEvent import eu.kanade.tachiyomi.event.MangaEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode +import eu.kanade.tachiyomi.util.SharedData import rx.Observable import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers @@ -50,11 +49,6 @@ class MangaInfoPresenter : BasePresenter() { */ @Inject lateinit var coverCache: CoverCache - /** - * Count of chapters. - */ - private var count = -1 - /** * The id of the restartable. */ @@ -63,12 +57,7 @@ class MangaInfoPresenter : BasePresenter() { /** * The id of the restartable. */ - private val GET_CHAPTER_COUNT = 2 - - /** - * The id of the restartable. - */ - private val FETCH_MANGA_INFO = 3 + private val FETCH_MANGA_INFO = 2 override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) @@ -78,39 +67,19 @@ class MangaInfoPresenter : BasePresenter() { { Observable.just(manga) }, { view, manga -> view.onNextManga(manga, source) }) - // Update chapter count. - startableLatestCache(GET_CHAPTER_COUNT, - { Observable.just(count) }, - { view, count -> view.setChapterCount(count) }) - // Fetch manga info from source. startableFirst(FETCH_MANGA_INFO, { fetchMangaObs() }, { view, manga -> view.onFetchMangaDone() }, { view, error -> view.onFetchMangaError() }) - // Listen for events. - registerForEvents() - } - - override fun onDestroy() { - unregisterForEvents() - super.onDestroy() - } - - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(event: MangaEvent) { - manga = event.manga + manga = SharedData.get(MangaEvent::class.java)!!.manga source = sourceManager.get(manga.source)!! refreshManga() - } - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(event: ChapterCountEvent) { - if (count != event.count) { - count = event.count - // Update chapter count - start(GET_CHAPTER_COUNT) + // Update chapter count + SharedData.get(ChapterCountEvent::class.java)?.let { + add(it.observable.subscribeLatestCache({ view, count -> view.setChapterCount(count) })) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.kt index ab6b4be95..510a57ca0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/myanimelist/MyAnimeListPresenter.kt @@ -9,9 +9,8 @@ import eu.kanade.tachiyomi.data.database.models.MangaSync import eu.kanade.tachiyomi.data.mangasync.MangaSyncManager import eu.kanade.tachiyomi.event.MangaEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.util.SharedData import eu.kanade.tachiyomi.util.toast -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode import rx.Observable import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers @@ -59,17 +58,7 @@ class MyAnimeListPresenter : BasePresenter() { { view, result -> view.onRefreshDone() }, { view, error -> view.onRefreshError(error) }) - registerForEvents() - } - - override fun onDestroy() { - unregisterForEvents() - super.onDestroy() - } - - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(event: MangaEvent) { - manga = event.manga + manga = SharedData.get(MangaEvent::class.java)!!.manga start(GET_MANGA_SYNC) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index a325b74f5..ff7a12940 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -36,6 +36,7 @@ import kotlinx.android.synthetic.main.reader_menu.* import nucleus.factory.RequiresPresenter import rx.Subscription import rx.subscriptions.CompositeSubscription +import timber.log.Timber import java.text.DecimalFormat @RequiresPresenter(ReaderPresenter::class) @@ -83,7 +84,7 @@ class ReaderActivity : BaseRxActivity() { val preferences: PreferencesHelper get() = presenter.prefs - public override fun onCreate(savedState: Bundle?) { + override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) setContentView(R.layout.activity_reader) @@ -189,8 +190,9 @@ class ReaderActivity : BaseRxActivity() { } } - fun onChapterError() { + fun onChapterError(error: Throwable) { finish() + Timber.e(error, error.message) toast(R.string.page_list_error) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt index 44a900403..1a08cf1f8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt @@ -17,9 +17,7 @@ import eu.kanade.tachiyomi.data.source.base.Source import eu.kanade.tachiyomi.data.source.model.Page import eu.kanade.tachiyomi.event.ReaderEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter -import org.greenrobot.eventbus.EventBus -import org.greenrobot.eventbus.Subscribe -import org.greenrobot.eventbus.ThreadMode +import eu.kanade.tachiyomi.util.SharedData import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers @@ -72,19 +70,26 @@ class ReaderPresenter : BasePresenter() { override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) - if (savedState != null) { + if (savedState == null) { + val event = SharedData.remove(ReaderEvent::class.java)!! + manga = event.manga + chapter = event.chapter + } else { manga = savedState.getSerializable(MANGA_KEY) as Manga - source = sourceManager.get(manga.source)!! chapter = savedState.getSerializable(CHAPTER_KEY) as Chapter requestedPage = savedState.getInt(PAGE_KEY) - initializeSubjects() } + source = sourceManager.get(manga.source)!! + + initializeSubjects() + startableLatestCache(GET_ADJACENT_CHAPTERS, { getAdjacentChaptersObservable() }, { view, pair -> view.onAdjacentChapters(pair.first, pair.second) }) - startable(PRELOAD_NEXT_CHAPTER, { getPreloadNextChapterObservable() }, + startable(PRELOAD_NEXT_CHAPTER, + { getPreloadNextChapterObservable() }, { }, { error -> Timber.e("Error preloading chapter") }) @@ -95,38 +100,24 @@ class ReaderPresenter : BasePresenter() { restartableLatestCache(GET_PAGE_LIST, { getPageListObservable(chapter) }, { view, chapter -> view.onChapterReady(manga, chapter, currentPage) }, - { view, error -> view.onChapterError() }) + { view, error -> view.onChapterError(error) }) if (savedState == null) { - registerForEvents() + loadChapter(chapter) + if (prefs.autoUpdateMangaSync()) { + start(GET_MANGA_SYNC) + } } } - override fun onDestroy() { - unregisterForEvents() - super.onDestroy() - } - override fun onSave(state: Bundle) { onChapterLeft() state.putSerializable(MANGA_KEY, manga) state.putSerializable(CHAPTER_KEY, chapter) - state.putSerializable(PAGE_KEY, requestedPage) + state.putSerializable(PAGE_KEY, currentPage?.pageNumber ?: 0) super.onSave(state) } - @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) - fun onEvent(event: ReaderEvent) { - EventBus.getDefault().removeStickyEvent(event) - manga = event.manga - source = sourceManager.get(manga.source)!! - initializeSubjects() - loadChapter(event.chapter) - if (prefs.autoUpdateMangaSync()) { - start(GET_MANGA_SYNC) - } - } - private fun initializeSubjects() { // Listen for pages initialization events pageInitializerSubject = PublishSubject.create() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.kt index ab9e86be2..55e2f4987 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/RecentChaptersPresenter.kt @@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.event.DownloadChaptersEvent import eu.kanade.tachiyomi.event.ReaderEvent import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter +import eu.kanade.tachiyomi.util.SharedData import org.greenrobot.eventbus.EventBus import rx.Observable import rx.android.schedulers.AndroidSchedulers @@ -256,7 +257,7 @@ class RecentChaptersPresenter : BasePresenter() { * @param item chapter that is opened */ fun onOpenChapter(item: MangaChapter) { - EventBus.getDefault().postSticky(ReaderEvent(item.manga, item.chapter)) + SharedData.put(ReaderEvent(item.manga, item.chapter)) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/SharedData.kt b/app/src/main/java/eu/kanade/tachiyomi/util/SharedData.kt new file mode 100644 index 000000000..6c0daedc2 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/util/SharedData.kt @@ -0,0 +1,45 @@ +package eu.kanade.tachiyomi.util + +import java.util.* + +/** + * This singleton is used to share some objects within the application, useful to communicate + * different parts of the app. + * + * It stores the objects in a map using the type of the object as key, so that only one object per + * class is stored at once. + */ +object SharedData { + + /** + * Map where the objects are saved. + */ + private val map = HashMap, Any>() + + /** + * Publish an object to the shared data. + * + * @param data the object to put. + */ + fun put(data: T) { + map.put(data.javaClass, data) + } + + /** + * Retrieves an object from the shared data. + * + * @param classType the class of the object to retrieve. + * @return an object of type T or null if it's not found. + */ + @Suppress("UNCHECKED_CAST") + fun get(classType: Class) = map[classType] as? T + + /** + * Removes an object from the shared data. + * + * @param classType the class of the object to remove. + * @return the object removed, null otherwise. + */ + fun remove(classType: Class) = get(classType)?.apply { map.remove(classType) } + +}