• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.car.customization.tool.domain
18 
19 /**
20  * A base class for state machines.
21  *
22  * It provides all the basic properties and functions and also implements the Observer pattern
23  * to make the state machine "reactive".
24  *
25  * @property allowDuplicates defines if the state observers should be notified or not
26  * if the new state produced by the reducer function is the same as the previous one.
27  */
28 internal abstract class StateMachine<STATE, ACTION>(
29     private val allowDuplicates: Boolean,
30 ) : Subject<STATE>() {
31 
32     /**
33      * The current state of the tool.
34      */
35     protected abstract var currentState: STATE
36 
37     /**
38      * The entity that observes the changes in the state.
39      */
40     private var observable: Observer<STATE>? = null
41 
42     /**
43      * Registers an observer for state updates. When registering the observer also receives
44      * immediately the current state (Hot observable).
45      */
registernull46     final override fun register(observer: Observer<STATE>) {
47         observable = observer
48         observer.render(currentState)
49     }
50 
51     /**
52      * Removes an observer from the list.
53      */
unregisternull54     final override fun unregister() {
55         observable = null
56     }
57 
58     /**
59      * Notifies the new state to all of the [Observer].
60      */
updateStatenull61     final override fun updateState(newState: STATE) {
62         if (!allowDuplicates && currentState != newState) {
63             currentState = newState
64             observable?.render(newState)
65         }
66     }
67 
68     /**
69      * Public function to accept actions from outside.
70      */
handleActionnull71     fun handleAction(action: ACTION) {
72         updateState(reducer(currentState, action))
73     }
74 
75     /**
76      * This function processes the current state and an action to produce a new one.
77      */
reducernull78     protected abstract fun reducer(state: STATE, action: ACTION): STATE
79 }
80