Arkadii Ivanov
02/09/2024, 9:40 AMelectrolobzik
02/09/2024, 9:48 AMelectrolobzik
02/09/2024, 9:50 AMArkadii Ivanov
02/09/2024, 9:59 AMArkadii Ivanov
02/09/2024, 10:01 AMfun onComponentUsed() {}
(or similar). Then in DefaultComponentContext
we can increment the counter and throw if it's >1. Then create a compiler plugin (perhaps KSP) that would generate the following code for every class that implements ComponentContext
.
init { onComponentUsed() }
Arkadii Ivanov
02/09/2024, 10:07 AMelectrolobzik
02/09/2024, 10:12 AMArkadii Ivanov
02/09/2024, 10:37 AMstateKeeper.register(key = "saved_state")
, which is also being done in the parent. This will crash if ComponentContext is reused.
2. It's ok to extract some logic from a component to a separate class.
a. It's ok to pass ComponentContext to those classes.
b. It's ok to delegate ComponentContext in those classes.
c. There will be a crash if there are two classes that use the same key
for StateKeeper#register
, or childStack
, etc.
This leads me to a conclusion that components are no different from just extracted classes. We can also require using childContext
when passing ComonentContext
to extracted classes. But this is also error-prone and will lead to runtime errors if the developer forgets to use childContext
and the check is triggered.
This leads me to the conclusion that it would be better to check if we can improve the error messages when keys are reused. Because this is the actual problem. If somehow we will manage to replace errors like "Another supplier is already registered with the key: Blah" with something like "Can't create another Child Stack with the key: Blah. Make sure you are not passing the parent ComponentContext to a child component. If your component has two Child Stacks, then specify a key for each of them.", then this would be much better. This is also a runtime check, not much different from a dedicated runtime check for passing parent ComponentContext to children.electrolobzik
02/10/2024, 11:56 AMelectrolobzik
02/10/2024, 11:57 AMArkadii Ivanov
02/10/2024, 4:47 PMAlso there are the cases, when no crashes will happen, by lifecycle events simply will not work correctlyI don't see how this can be covered. We can't distinguish between normal classes and component classes. It might be valid to pass the parent
ComponentContext
to a normal class. Currently - the way how we pass ComponentContext defines whether the class is a component or not (components receive child ComponentContext
, whereas normal classes receive parent ComponentContext
).
We could mark a component with a special interface - interface Component
. But I'm not sure if it's a good idea to introduce the interface just for the sake of runtime checks.
I will need to think about it.electrolobzik
02/11/2024, 8:53 AMArkadii Ivanov
02/11/2024, 10:10 AMelectrolobzik
02/11/2024, 10:13 AMArkadii Ivanov
02/11/2024, 10:16 AMchildContext
function. This means that the user may add the Component
interface to the component class, or may not. There is no compile-time check, the interface is simply not required for the system to work. And it might be a mistake to pass the parent context instead, or it might not.
Also, we have the children
navigation. Currently it doesn't enforce any base interfaces for child components - the type is simply T : Any
. This is by design. So again, it's optional for the user whether to add the Component
interface or not.electrolobzik
02/11/2024, 10:20 AMArkadii Ivanov
02/11/2024, 10:20 AMcheckComponentContextUsage()
to ComponentContext
interface.
2. Treat every class that implements ComponentContext
interface as a component.
3. Create a compiler plugin (e.g. KSP) that adds init { checkComponentContextUsage() }
to every component class.
By enabling the compiler plugin a user opt-ins to this behaviour and gets runtime checks. Now if they want to extract some component logic to a separate class AND they want to also implement ComponentContext
in that class, they have to use childContext
, which doesn't hurt actually.
But KSP for KMP is still experimental AFAIK. Plus I'm not sure I have capacity for this. 😐Arkadii Ivanov
02/11/2024, 10:21 AMelectrolobzik
02/11/2024, 10:24 AMelectrolobzik
02/11/2024, 10:35 AMArkadii Ivanov
02/11/2024, 10:53 AM