Skip to main content

Initialization of the MasterController (Android/Kotlin)

We communicate with the Master Controller by sending and receiving events. To simplify this process, we use a wrapper class called MasterControllerAdapter for Swift and MCHandler for Kotlin in our example app. These classes provide methods for interacting with the Master Controller, so we do not need to understand all the intricacies of its implementation.

Here are some important points about the MasterControllerAdapter/MCHandler class:

  • It serves as a single point of connection with the Master Controller, preventing the need to scatter connection code throughout the app.
  • It offers dedicated methods for sending events.
  • It provides a single method for receiving events from the Master Controller.
  • Observers can be added or removed to handle received events in different classes as needed.

We mainly use three methods to communicate with the Master Controller:

  1. postEvent(event: EventFrameworkEvent): This method sends an event to the Master Controller. We use it when we expect a result event after triggering an event on the Master Controller side. By implementing the then block on postEvent, we can retrieve and handle the result event. The postEvent() method returns a Future object, and its get() method returns an EventFrameworkEvent, which is the superclass of all events.

  2. forwardEvent(event: EventFrameworkEvent): Similar to postEvent(), this method sends events to the Master Controller. However, it operates as a "Fire and Forget" mechanism, meaning it does not expect a result event for the triggered event. We use this method when no result event is expected. Here you can find the events table.

  3. executeEvent(eventFrameworkEvent: EventFrameworkEvent?): This method receives events from the Master Controller.

MCHandler extends from SynchronousEventHandler (wrapper class available in MasterController library) which makes the methods for communicating with MasterController available to MCHandler.

MCHandler
class MCHandler private constructor(
private val context: Context
) : SynchronousEventHandler(context) {
private var mcEventHandler: SynchronousEventHandler? = null
/**
* Holds MCEventObserver to notify about Master Controller events
*/
private var observers: MutableList<MCEventObserver> = mutableListOf()
}

MCHandler is a singleton class with a getInstance() method that allows us to obtain its instance. When we create an instance of MCHandler, the constructor of SynchronousEventHandler is called, executing the necessary steps to initialize the Master Controller.

getInstance Method
companion object {
private var instance: MCHandler? = null
fun getInstance(context: Context): MCHandler {
synchronized(this) {
if (instance == null) {
instance = MCHandler(context)
instance?.setEventHandlerInstance(instance!!)
}
return instance!!
}
}
}

fun setEventHandlerInstance(eventHandler: SynchronousEventHandler) {
this.mcEventHandler = eventHandler
}

MCHandler class extends the SynchronousEventHandler class, which is an abstract class. Therefore, we need to override a method called executeEvent. This method is invoked whenever the Master Controller sends any event, meaning it is responsible for receiving events from the Master Controller.

executeEvent Method
@Synchronized
override fun executeEvent(event: EventFrameworkEvent?) {
if (observers.isNotEmpty()) {
observers.forEach { observer ->
event?.let {
observer.onEventReceived(it)
logDebug(
observer.javaClass.name + " is notified by " + observer.javaClass.name,
"processEvent",
TAG
)
}
}
} else {
logDebug(
"No observer attached to received event ==> $event",
"processEvent",
TAG
)
}
}

We need to add event observer to get the callback in your current class whenever Master Controller sends any event. There is method named addMCEventObserver which is responsible for adding event observer.

addMCEventObserver Method
/**
* Adds MCEventObserver instance to observers List.
*
* @param o - MCEventObserver instance
*/

@Synchronized
fun addMCEventObserver(o: MCEventObserver) {
observers.add(o)
logDebug(
o.javaClass.name + " has been added as MC Event observer",
"addMCEventObserver",
TAG
)
}

NOTE: It is important to remove the observer whenever we no longer need to listen for MasterController events.

There is a method called removeMCEventObserver that handles the removal of the observer.

removeMCEventObserver
/**
* Removes MCEventObserver instance from observers List.
*/

@Synchronized
fun removeMCEventObserver(observer: MCEventObserver) {
observers.remove(observer)
logDebug(
observer.javaClass.name + " has been removed as MC Event observer",
"removeMCEventObserver",
TAG
)
}

Below is a code snippet demonstrating how to use the provided methods in their respective implementation classes: Here is a code snippet for obtaining the instance of MCHandler:

Getting instance of MCHandler
mcHandler = MCHandler.getInstance(context of current Activity);

By adding an event observer to MCHandler, we can start listening to MC events. Below is a code snippet for adding an event observer:

Adding MC Event Observer
mcHandler?.addMCEventObserver(reference of MCEventObserver)

Following is the callback method where you receive a call when the MasterController sends any event (if an observer is added).

MC Event Callback Method
override fun onEventReceived(eventFrameworkEvent: EventFrameworkEvent) {
// Write code to handle the event
}

By removing the observer we can stop listening to MC events, Here is the code snippet:

Removing Event observer
mcHandler?.removeMCEventObserver(context of Activity)

Below is the diagram to understand the flow what we have mentioned above in the form of code: