Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace event listener with FragmentDelegate class. #321

Merged
merged 1 commit into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -132,20 +132,16 @@ class FormulaFragment : Fragment(), BaseFormulaFragment<Any> {

val fragmentId = getFormulaFragmentId()
val environment = FormulaFragmentDelegate.fragmentEnvironment()
val fragmentDelegate = environment.fragmentDelegate

try {
val start = SystemClock.uptimeMillis()
view.setOutput(output)
val end = SystemClock.uptimeMillis()

environment.eventListener?.onRendered(
fragmentId = fragmentId,
durationInMillis = end - start,
)
fragmentDelegate.setOutput(fragmentId, output, view.setOutput)

if (firstRender) {
val end = SystemClock.uptimeMillis()

firstRender = false
environment.eventListener?.onFirstModelRendered(
fragmentDelegate.onFirstModelRendered(
fragmentId = fragmentId,
durationInMillis = end - (initializedAtMillis ?: SystemClock.uptimeMillis()),
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,54 @@
package com.instacart.formula.android

import android.view.LayoutInflater
import android.view.ViewGroup

data class FragmentEnvironment(
val logger: (String) -> Unit = {},
val onScreenError: (FragmentKey, Throwable) -> Unit = { _, it -> throw it },
val eventListener: EventListener? = null,
val fragmentDelegate: FragmentDelegate = FragmentDelegate(),
) {

/**
* Introspection API to track various formula fragment events and their performance.
*/
interface EventListener {
open class FragmentDelegate {

/**
* Called after [FeatureFactory.initialize] is called.
* Instantiates the feature.
*/
fun onFeatureInitialized(fragmentId: FragmentId, durationInMillis: Long)
fun <DependenciesT, KeyT: FragmentKey> initializeFeature(
fragmentId: FragmentId,
factory: FeatureFactory<DependenciesT, KeyT>,
dependencies: DependenciesT,
key: KeyT,
): Feature<*> {
return factory.initialize(dependencies, key)
}

/**
* Called when [FormulaFragment] view is inflated.
* Called from [FormulaFragment.onCreateView] to instantiate the view.
*/
fun onViewInflated(fragmentId: FragmentId, durationInMillis: Long)
fun createView(
fragmentId: FragmentId,
viewFactory: ViewFactory<Any>,
inflater: LayoutInflater,
container: ViewGroup?,
): FeatureView<Any> {
return viewFactory.create(inflater, container)
}

/**
* Called after render model was applied to the [FeatureView].
* Called when we are ready to apply [output] to the view.
*/
fun onRendered(fragmentId: FragmentId, durationInMillis: Long)
fun setOutput(fragmentId: FragmentId, output: Any, applyOutputToView: (Any) -> Unit) {
applyOutputToView(output)
}

/**
* Called after first render model is rendered. The [durationInMillis] starts
* when formula fragment is initialized and ends after first render model is applied.
*/
fun onFirstModelRendered(fragmentId: FragmentId, durationInMillis: Long)
fun onFirstModelRendered(fragmentId: FragmentId, durationInMillis: Long) = Unit
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be replaced as well

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,12 @@ internal class FeatureBinding<in Component, in Dependencies, in Key : FragmentKe
Action.onData(fragmentId).onEvent {
transition {
try {
val start = SystemClock.uptimeMillis()
val dependencies = toDependencies(input.component)
val feature = feature.initialize(dependencies, key as Key)
val end = SystemClock.uptimeMillis()
input.environment.eventListener?.onFeatureInitialized(
val feature = input.environment.fragmentDelegate.initializeFeature(
fragmentId = fragmentId,
durationInMillis = end - start,
factory = feature,
dependencies = dependencies,
key = key as Key,
)
input.onInitializeFeature(FeatureEvent.Init(fragmentId, feature))
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.instacart.formula.android.internal

import android.os.SystemClock
import android.view.LayoutInflater
import android.view.ViewGroup
import com.instacart.formula.android.FeatureView
Expand All @@ -20,7 +19,6 @@ internal class FormulaFragmentViewFactory(

@Suppress("UNCHECKED_CAST")
override fun create(inflater: LayoutInflater, container: ViewGroup?): FeatureView<Any> {
val start = SystemClock.uptimeMillis()
val key = fragmentId.key
val featureEvent = featureProvider.getFeature(fragmentId) ?: throw IllegalStateException("Could not find feature for $key.")
val viewFactory = factory ?: when (featureEvent) {
Expand All @@ -35,9 +33,7 @@ internal class FormulaFragmentViewFactory(
}
}
this.factory = viewFactory
val view = viewFactory.create(inflater, container)
val endTime = SystemClock.uptimeMillis()
environment.eventListener?.onViewInflated(fragmentId, endTime - start)
return view
val delegate = environment.fragmentDelegate
return delegate.createView(fragmentId, viewFactory, inflater, container)
}
}
Loading