Skip to content

Experimental Transformer module#44

Open
yigitozgumus wants to merge 6 commits intoTrendyol:mainfrom
yigitozgumus:transformer-module
Open

Experimental Transformer module#44
yigitozgumus wants to merge 6 commits intoTrendyol:mainfrom
yigitozgumus:transformer-module

Conversation

@yigitozgumus
Copy link
Copy Markdown
Member

Currently, Transmission Library offers inheritance based signal and effect override/extension mechanism.

This MR Introduces a TransformerModule which can be added to any Transformer by applyModule or applyModules.

The most important change proposed is the refactor of HandlerRegistry. Each signal or effect now can contain multiple StackedLambda's.

If you define a handler logic to a super type, like Transmission.Signal, it will be applied to every signal defined in that Transformer.

Here is the Module:

/**
 * Interface for defining reusable modules that can be applied to Transformers
 */
interface TransformerModule {
    /**
     * Configure handlers for a transformer
     * @param scope The handler scope to configure
     */
    fun configureHandlers(scope: HandlerScope) {}

    /**
     * Called when the transformer is cleared
     */
    fun onCleared() {}

    /**
     * Called when an error occurs in the transformer
     */
    fun onError(throwable: Throwable) {}
}

Here is an example Implementation

/**
 * Example module that logs signals and effects
 */
class LoggingModule(
    private val prefix: String = "",
    private val logAction: (String) -> Unit = { Log.d("Logging", it) }
) : TransformerModule {

    override fun configureHandlers(scope: HandlerScope) {
        // Log all signals
        scope.onSignal<Transmission.Signal> { signal ->
            val signalName = signal::class.simpleName ?: "UnknownSignal"
            logAction("$prefix Received signal: $signalName")
        }

        // Log all effects
        scope.onEffect<Transmission.Effect> { effect ->
            val effectName = effect::class.simpleName ?: "UnknownEffect"
            logAction("$prefix Processed effect: $effectName")
        }
    }

    override fun onError(throwable: Throwable) {
        logAction("$prefix Error: ${throwable.message}")
    }
}

If we apply this module, and set TransformerConfig to TypeAware, all the signals and effects inside the Transformer will also be able to execute the handler logic

init {
    applyModule(LoggingModule("ColorPicker"))
}

Here is an updated SignalHandler addition implementation which accounts for type aware signals and effects

    @PublishedApi
    internal fun <T : Transmission.Signal> addSignalHandler(
        signalClass: KClass<T>,
        sourceClass: KClass<*>,
        handler: suspend CommunicationScope.(signal: T) -> Unit
    ) {
        // Create a new stacked lambda for this handler
        val stackedLambda = StackedLambda<Transmission.Signal>()
        @Suppress("UNCHECKED_CAST")
        stackedLambda.addOperation(handler as SignalLambda)

        // Create the identified handler
        val identifiedHandler = IdentifiedHandler(sourceClass, stackedLambda)

        // Register the handler for the specified signal class
        signalHandlerRegistry.getOrPut(signalClass) { mutableListOf() }.add(identifiedHandler)

        // If type hierarchy awareness is enabled, register for subtypes too
        if (config.typeHierarchyAwarenessEnabled) {
            // Find all registered subclasses of this signal class and register the handler for them too
            // Only do this for supertypes, not for specific types
            for (registeredClass in signalHandlerRegistry.keys.toList()) {
                if (registeredClass != signalClass && registeredClass.isSubclassOf(signalClass)) {
                    // For each subclass, add this handler
                    val subclassHandlers =
                        signalHandlerRegistry.getOrPut(registeredClass) { mutableListOf() }

                    // Create a new stacked lambda with the same operation
                    val subclassStackedLambda = StackedLambda<Transmission.Signal>()
                    @Suppress("UNCHECKED_CAST")
                    subclassStackedLambda.addOperation(handler as SignalLambda)

                    // Add as a new identified handler
                    subclassHandlers.add(IdentifiedHandler(sourceClass, subclassStackedLambda))
                }
            }
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant