Coder Social home page Coder Social logo

sellmair / kompass Goto Github PK

View Code? Open in Web Editor NEW
345.0 11.0 12.0 33.39 MB

Kotlin Multiplatform Router for Android and iOS

License: MIT License

Kotlin 100.00%
router kotlin kotlin-library kotlin-android transition fragments custom-transitions animation mvvm mvvm-architecture

kompass's People

Contributors

heinrichreimer avatar isaac-udy avatar sellmair avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kompass's Issues

Support function accessors

Currently, unlike in 0.0.10, information of a destination can only be retrieved by a field like

class MyDestination(val id: Int)

can only retrieve the id by myDestination.id

What we want to support is:

class MyDestination(id: Int) {
  fun id(): Int
  // or fun getId(): Int
}

while retrieving id by

myDestination.id()

Erradic route restoration after process death

1:
05-04 18:54:01.422 1624-2049/system_process I/WindowState: WIN DEATH: Window{3ecd6d0 u0 io.sellmair.kompass.android.example/io.sellmair.kompass.android.example.MainActivity} 05-04 18:54:01.429 1624-3080/system_process I/ActivityManager: Process io.sellmair.kompass.android.example (pid 9647) has died 05-04 18:54:01.434 1340-1340/? I/Zygote: Process 9647 exited cleanly (1) 05-04 18:54:08.273 1624-1636/system_process I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=io.sellmair.kompass.android.example/.MainActivity (has extras)} from uid 10009 on display 0 05-04 18:54:10.208 9908-9908/io.sellmair.kompass.android.example D/Example: MainActivity.onCreate(Bundle[{android:viewHierarchyState=Bundle[mParcelledData.dataSize=660], android:support:fragments=androidx.fragment.app.FragmentManagerState@4319376, androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[EMPTY_PARCEL], android:fragments=android.app.FragmentManagerState@74ded77}]) 05-04 18:54:10.209 9908-9908/io.sellmair.kompass.android.example I/Kompass: restored routes: null 05-04 18:55:01.067 9931-9931/io.sellmair.kompass.android.example I/Kompass: restored routes: 05-04 18:55:09.148 9931-9931/io.sellmair.kompass.android.example I/Kompass: restored routes: 05-04 18:55:12.578 9931-9931/io.sellmair.kompass.android.example I/Kompass: restored routes: 05-04 18:55:14.866 9931-9931/io.sellmair.kompass.android.example I/Kompass: restored routes:

05-04 18:51:18.400 9647-9647/io.sellmair.kompass.android.example I/Kompass: transition to stack: ContactListRoute(searchString=null, contacts=[Contact(name=Julian B., phone=-, [email protected], nickname=Julian), Contact(name=Stefan K., phone=0176/43404485, [email protected], nickname=Steffen), Contact(name=Malte B., phone=08442/90909090, [email protected], nickname=Malthe), Contact(name=Klaus N., phone=0800/32-16-8, [email protected], nickname=Klaus), Contact(name=G. Nasir, phone=00491500-not-his-own, [email protected], nickname=Nasir), Contact(name=Mathias Q., phone=0176/46779438, [email protected], nickname=Mathias), Contact(name=Balazs T., phone=0152/837782458, email=balazs@, nickname=Balazs), Contact(name=Niko T., phone=0800/0800, email=niko@, nickname=Niko), Contact(name=Paul K., phone=0800/dj-paul-power, [email protected], nickname=Paul)]) 05-04 18:51:18.828 9647-9647/io.sellmair.kompass.android.example I/Kompass: transition to stack: ContactListRoute(searchString=null, contacts=[Contact(name=Julian B., phone=-, [email protected], nickname=Julian), Contact(name=Stefan K., phone=0176/43404485, [email protected], nickname=Steffen), Contact(name=Malte B., phone=08442/90909090, [email protected], nickname=Malthe), Contact(name=Klaus N., phone=0800/32-16-8, [email protected], nickname=Klaus), Contact(name=G. Nasir, phone=00491500-not-his-own, [email protected], nickname=Nasir), Contact(name=Mathias Q., phone=0176/46779438, [email protected], nickname=Mathias), Contact(name=Balazs T., phone=0152/837782458, email=balazs@, nickname=Balazs), Contact(name=Niko T., phone=0800/0800, email=niko@, nickname=Niko), Contact(name=Paul K., phone=0800/dj-paul-power, [email protected], nickname=Paul)]), ChatRoute(lastSeenTime=1556988678828, backgroundId=1, chatTitle=Mathias, savedAlreadyTypedText=, contact=Contact(name=Mathias Q., phone=0176/46779438, [email protected], nickname=Mathias)) 05-04 18:51:20.576 9647-9647/io.sellmair.kompass.android.example I/Kompass: saving routes: ContactListRoute(searchString=null, contacts=[Contact(name=Julian B., phone=-, [email protected], nickname=Julian), Contact(name=Stefan K., phone=0176/43404485, [email protected], nickname=Steffen), Contact(name=Malte B., phone=08442/90909090, [email protected], nickname=Malthe), Contact(name=Klaus N., phone=0800/32-16-8, [email protected], nickname=Klaus), Contact(name=G. Nasir, phone=00491500-not-his-own, [email protected], nickname=Nasir), Contact(name=Mathias Q., phone=0176/46779438, [email protected], nickname=Mathias), Contact(name=Balazs T., phone=0152/837782458, email=balazs@, nickname=Balazs), Contact(name=Niko T., phone=0800/0800, email=niko@, nickname=Niko), Contact(name=Paul K., phone=0800/dj-paul-power, [email protected], nickname=Paul)]), ChatRoute(lastSeenTime=1556988678828, backgroundId=1, chatTitle=Mathias, savedAlreadyTypedText=, contact=Contact(name=Mathias Q., phone=0176/46779438, [email protected], nickname=Mathias)) 05-04 18:51:20.611 9647-9653/io.sellmair.kompass.android.example I/art: System.exit called, status: 1 05-04 18:54:01.327 9647-9653/io.sellmair.kompass.android.example I/AndroidRuntime: VM exiting with result code 1, cleanup skipped. 05-04 18:54:01.422 1624-2049/system_process I/WindowState: WIN DEATH: Window{3ecd6d0 u0 io.sellmair.kompass.android.example/io.sellmair.kompass.android.example.MainActivity} 05-04 18:54:01.429 1624-3080/system_process I/ActivityManager: Process io.sellmair.kompass.android.example (pid 9647) has died 05-04 18:54:08.273 1624-1636/system_process I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=io.sellmair.kompass.android.example/.MainActivity (has extras)} from uid 10009 on display 0 05-04 18:54:08.317 1624-2047/system_process I/ActivityManager: Start proc 9908:io.sellmair.kompass.android.example/u0a75 for activity io.sellmair.kompass.android.example/.MainActivity 05-04 18:54:09.771 9908-9908/io.sellmair.kompass.android.example D/Example: Application.onCreate 05-04 18:54:10.208 9908-9908/io.sellmair.kompass.android.example D/Example: MainActivity.onCreate(Bundle[{android:viewHierarchyState=Bundle[mParcelledData.dataSize=660], android:support:fragments=androidx.fragment.app.FragmentManagerState@4319376, androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[EMPTY_PARCEL], android:fragments=android.app.FragmentManagerState@74ded77}]) 05-04 18:54:10.209 9908-9908/io.sellmair.kompass.android.example I/Kompass: restored routes: null 9914/io.sellmair.kompass.android.example I/art: System.exit called, status: 1 05-04 18:54:55.327 9908-9914/io.sellmair.kompass.android.example I/AndroidRuntime: VM exiting with result code 1, cleanup skipped. 05-04 18:54:55.483 1624-1780/system_process I/WindowState: WIN DEATH: Window{660ed23 u0 io.sellmair.kompass.android.example/io.sellmair.kompass.android.example.MainActivity} 05-04 18:54:55.520 1624-12358/system_process I/ActivityManager: Process io.sellmair.kompass.android.example (pid 9908) has died 05-04 18:54:59.659 1624-2183/system_process I/ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=io.sellmair.kompass.android.example/.MainActivity (has extras)} from uid 10009 on display 0 05-04 18:54:59.773 1624-2942/system_process I/ActivityManager: Start proc 9931:io.sellmair.kompass.android.example/u0a75 for activity io.sellmair.kompass.android.example/.MainActivity /data/app/io.sellmair.kompass.android.example-1/lib/x86_64 05-04 18:55:00.198 9931-9931/io.sellmair.kompass.android.example D/Example: Application.onCreate 05-04 18:55:01.065 9931-9931/io.sellmair.kompass.android.example D/Example: MainActivity.onCreate(Bundle[{android:viewHierarchyState=Bundle[mParcelledData.dataSize=660], android:support:fragments=androidx.fragment.app.FragmentManagerState@4319376, Kompass: RoutingStack=io.sellmair.kompass.android.ParcelableRoutingStackWrapper@74ded77, androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[EMPTY_PARCEL], android:fragments=android.app.FragmentManagerState@b928de4}]) 05-04 18:55:01.067 9931-9931/io.sellmair.kompass.android.example I/Kompass: restored routes:

Keep state on Process-Death

Kompass doesn't keep the current state on process-death.
Routing to a certain destination, terminating the app, re-opening will lead route to the last destination. This could be changed by separating lambdas and destinations from inside the backstack and serializing the backstack to the onSaveInstance bundle.

Replace annotation processing

Annotation processing will be replaced by either kotlin-android-extensions, kotlin serialization, or third party way of converting routes into Bundle and back.

androidx lifecycle dependency needed

The app crashes since it can not find LifecycleEventObserver which is part of androidx.lifecycle:lifecycle-extensions:2.1.0-alpha04. It would be nice if this extra dependency is not needed ๐Ÿค™๐Ÿผ.

Check if target is suitable

Currently, the compiler itself does not check whether or not the target for a given destination makes sense (if it is a suitable view, fragment or activity).
This will lead to a build failure that is hard to understand.

We should:

  • Check the correctness at kapt-time
  • Print a nice error message telling the user what is wrong

Support optional primitives

Int?, Float?, Double?, ... are represented by java.lang.* Objects in the JVM, which are currently not supported, but shoud!

New multi-router API

Previously (0.1.0) the Kompass interface was used to hold multiple routers (for multiple parts of the screen). Maybe (0.2.0) should also allow such usage?

Sample: LoginProcessingFragment can get stuck in loading state forever

Because of viewModel.stop() in onPause, if app is put to background and brought to foreground while LoginProcessingFragment is on front, then the app gets stuck here forever.

You might want to consider some form of observable that the is bound to onStart/onStop rather than onPause (and no counterpart).

After rotation, it still gets stuck on the screen:

Screenshot 2019-05-06 at 13 39 37

Decouple Android dependencies

I believe, Kompass is a great router not only for Android.
If we decouple the Android-related implementation detail into separate modules, we could use Kompass also for other frameworks.
I guess that would have a clear benefit and shouldn't even be too complicated as the only Android-dependent stuff is Bundle and how to set a sail, which of course can be generalized using some clever interfaces and modules.

Clearly, this would break some code, but I would like to investigate the idea further.

Can't use objects as destination

The annotation processor fails to generate the serialization methods for object destinations.

Suppose the following destination:

@Destination
object HomeDestination: PodDestination()

Kompass generates the following method:

fun Kompass.Companion.bundleAsHomeDestination(bundle: Bundle): HomeDestination = HomeDestination()

This calls HomeDestination() but should instead call HomeDestination.

Direct `FragmentRouteStorage`

It may be possible to implement a FragmentRouteStorage that takes the key of a route and retrieves the router later from the router by using the key again

Convenience extensions for Activity and Fragment

As an user of this library I want to get my destinations more straight forward.
I want to type

val myDestination = myDestination()

Instead of

val myDestination = arguments?.tryAsMyDestination()?:throw IllegalArgumentException()

Inside my fragment/activity

Proper constructor selection

Currently, as in 0.1.0-pre-alpha.3, we just pick the first constructor of a given destination and try to construct a bundle out of this constructor and vice versa.
What we should do (and did in 0.0.10) is:

  • Select the longest constructor
  • That has accessors for any argument

Update example gif

The current example gif does not show the LoginFailedDestination (which is kind of cool)

nested destinations

Support destinations like

class OuterDestination {
     @Destination
     class InnerDestination
}

FragmentEndpoint: back operations using wrong manager after config changes

Stacktrace from example app after rotating and pressing back

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:2053)
at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:796)
at io.sellmair.kompass.internal.pipe.FragmentEndpoint$navigateTo$1.invoke(FragmentEndpoint.kt:69)
at io.sellmair.kompass.internal.pipe.FragmentEndpoint$navigateTo$1.invoke(FragmentEndpoint.kt:14)
at io.sellmair.kompass.internal.BackStackImpl.backImmediate(BackStackImpl.kt:31)
at io.sellmair.kompass.internal.KompassImpl.backImmediate(Unknown Source:2)
at io.sellmair.kompass.BackStack$DefaultImpls.backImmediate$default(BackStack.kt:12)
at io.sellmair.example.MainActivity.onBackPressed(MainActivity.kt:28)
at android.app.Activity.onKeyUp(Activity.java:3007)
at android.view.KeyEvent.dispatch(KeyEvent.java:2715)
at android.app.Activity.dispatchKeyEvent(Activity.java:3299)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:534)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:58)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:316)
at com.android.internal.policy.DecorView.dispatchKeyEvent(DecorView.java:355)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4982)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4854)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4389)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4442)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4408)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4535)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4416)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4592)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4389)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4442)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4408)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4416)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4389)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4442)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4408)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4568)
at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4729)
at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2465)
at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2028)
at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2019)
at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2442)
at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6753)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:482)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Crash when creating ship from background thread

When accessing a ship initially from the background thread, handelables are created by this thread where

internal interface Handleable<T> {

    @UiThread // is then called by the background thread, hence crashing
    fun handle(handler: (T) -> Unit)

    @AnyThread
    fun handle(value: T)

    companion object
}

Process: io.sellmair.there, PID: 16293
io.sellmair.kompass.internal.precondition.KompassPreconditionException: Function not called from main thread
    at io.sellmair.kompass.internal.precondition.Precondition_requireMainThreadKt.throwMainThreadRequiredException(Precondition+requireMainThread.kt:14)
    at io.sellmair.kompass.internal.precondition.Precondition_requireMainThreadKt.requireMainThread(Precondition+requireMainThread.kt:9)
    at io.sellmair.kompass.internal.pipe.HandleableImpl.handle(Handleable+delegate.kt:31)
    at io.sellmair.kompass.internal.pipe.InstructionCrane.handle(Unknown Source:7)
    at io.sellmair.kompass.internal.pipe.InstructionPipePlusConnector.<init>(InstructionPipe+plus.kt:54)
    at io.sellmair.kompass.internal.pipe.InstructionPipe_plusKt.plus(InstructionPipe+plus.kt:18)
    at io.sellmair.kompass.internal.ShipImpl.<init>(ShipImpl.kt:65)
    at io.sellmair.kompass.internal.KompassImpl.createShip(KompassImpl.kt:22)
    at io.sellmair.kompass.internal.KompassImpl.access$createShip(KompassImpl.kt:6)
    at io.sellmair.kompass.internal.KompassImpl$get$1$1.invoke(KompassImpl.kt:17)
    at io.sellmair.kompass.internal.KompassImpl$get$1$1.invoke(KompassImpl.kt:6)
    at io.sellmair.kompass.internal.util.CurryKt$curry$1.invoke(curry.kt:5)
    at io.sellmair.kompass.internal.KompassImpl.get(KompassImpl.kt:32)
    at io.sellmair.there.scenes.ShipsKt.getHome(Ships.kt:5)
    at io.sellmair.there.component.home.HomeViewModel$1.invoke(HomeViewModel.kt:19)
    at io.sellmair.there.component.home.HomeViewModel$1.invoke(HomeViewModel.kt:12)
    at io.sellmair.state.StateStoreImpl$worker$1.cycle(StateStore.kt:155)
    at io.sellmair.state.StateStoreImpl$worker$1.run(StateStore.kt:122)

Failing Build when using AndroidX.

The annotation processor is failing when using androidX libs.
Here's the stacktrace.
[kapt] An exception occurred: java.lang.IllegalStateException: elementUtils.getTypeElement(this) must not be null at io.sellmair.kompass.compiler.extension.RenderContextUse$DefaultImpls.asElement(ProcessingEnvironment+use.kt:91) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.asElement(AutoMapVisitor.kt:13) at io.sellmair.kompass.compiler.extension.RenderContextUse$DefaultImpls.asType(ProcessingEnvironment+use.kt:95) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.asType(AutoMapVisitor.kt:13) at io.sellmair.kompass.compiler.extension.RenderContextUse$DefaultImpls.asType(ProcessingEnvironment+use.kt:119) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.asType(AutoMapVisitor.kt:13) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.destinationCase(AutoMapVisitor.kt:72) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.destinationCase(AutoMapVisitor.kt:61) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.buildImplementation(AutoMapVisitor.kt:39) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.visit(AutoMapVisitor.kt:26) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.visit(AutoMapVisitor.kt:16) at io.sellmair.kompass.compiler.destination.visitor.AutoMapVisitor.visit(AutoMapVisitor.kt:13) at io.sellmair.kompass.compiler.common.VisitorKt$plus$1.visit(Visitor.kt:10) at io.sellmair.kompass.compiler.common.VisitorKt$plus$1.visit(Visitor.kt:9) at io.sellmair.kompass.compiler.common.VisitorKt$plus$1.visit(Visitor.kt:9) at io.sellmair.kompass.compiler.DestinationProcessor.process(DestinationProcessor.kt:54) at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:99) at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:794) at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:705) at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91) at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1035) at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1176) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170) at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068) at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:55) at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:27) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:210) at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:175) at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:93) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:98) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:108) at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:85) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:370) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:61) at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:101) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:361) at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:126) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:154) at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:51) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:94) at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.java:50) at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:88) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:408) at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$1$1$2.invoke(CompileServiceImpl.kt:101) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:929) at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:101) at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137) at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:969) at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:928) at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:407) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346) at sun.rmi.transport.Transport$1.run(Transport.java:200) at sun.rmi.transport.Transport$1.run(Transport.java:197) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.Transport.serviceCall(Transport.java:196) at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) at java.security.AccessController.doPrivileged(Native Method) at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

Chain-Based routing

Currently Kompass only offers two way too route to a certain Destination


kompass.navigateTo(destination, replace=false)

Which will route to the new destination while adding it to the backstack.


kompass.navigateTo(destination, replace=true)

Which will clear the back-stack effectively and replace the whole screen with the new destination.


Goal

The goal is to provide a 'chain-like' routing mechanism which is able to just replace the last screen with a new destination.

An Example would be:
destination1 --navigateTo--> destination 2 ---replaceCurrent---> destination3
---back--> destination1

Discussion: DSL syntax

I'd like to start a bit of a discussion around the DSL syntax.

Multiple paths to one goal:

router.clear()
router.push(Route())
router { 
    clear() push Route()
}
router {
    clear()
    push(Route())
}

There are several ways to perform similar actions. The first way isn't correct, as it won't bundle up the actions as a single item, but my understanding is the last two ways are essentially the same. ฬ›I think it would be a better idea to have a single syntax, even if it means that a single "push" needs to be performed as:

router { push() }

Builder syntax:

router {
    clear() push RouteA() push RouteB() push RouteC()
}

The builder continuation syntax that allows a user to push a series of routes like this is inconsistent with the use of infix functions, as a user is unable to split these onto different lines. The following code will not compile:

router {
    clear() push RouteA()
        push RouteB()
        push RouteC()
}

I have two questions:

  1. Is the builder/continuation syntax actually useful? Could commands just be split onto different lines?
  2. If the builder/continuation syntax is useful, should the use of infix be removed, so a user can split the continuation over multple lines?

.sail method for fragments

create .sail method which internally uses

requireActivity for activity an childFragmentManager for manager

Soft-View-Referencing

Currently, References to views are held strongly by the back-stack.
We should change this reference to soft and re-create the view when necessary.

Self mapped, Self craned Destinations

Make it easier to work with kompass without annotation processing.
Destinations might want to implement dedicated interfaces to signal that they know how to crane and how to map them.

GetRouteSyntax should not contain an instance of router

Some fragments want to use methods like getRoute or by route() to get the route-specific information.

When implementing KompassFragment or GetRouteSyntax you also have to specify a router which is not needed if the fragment itself does no routing.
Any specific reason why this was designed that way?
Maybe I should use another interface instead? ๐Ÿค”

Ship.destination

Implement the following API:

interface KompassShip<Destination: Any> {
    // ... all the other stuff
    val location: Destination?
}

Question about destination .

Hi , currently im using your library its great and ease to implement and may i know how to identify which is destination is currently is active? or is there a currently function to that please let me know thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.