aboutsummaryrefslogtreecommitdiff
path: root/core/src/main/kotlin/ca/allanwang/kau/kotlin/LazyContext.kt
blob: e2a59d796d39613880ed3e40e85c91feb2b5595c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/*
 * Copyright 2018 Allan Wang
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ca.allanwang.kau.kotlin

import android.content.Context
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.view.animation.Interpolator
import androidx.annotation.AnimRes
import androidx.annotation.InterpolatorRes

/**
 * Created by Allan Wang on 2017-05-30.
 *
 * Lazy retrieval of context based items
 * Items are retrieved using delegateName(context)
 *
 */
fun lazyInterpolator(@InterpolatorRes id: Int) = lazyContext<Interpolator> { AnimationUtils.loadInterpolator(it, id) }

fun lazyAnimation(@AnimRes id: Int) = lazyContext<Animation> { AnimationUtils.loadAnimation(it, id) }

fun <T> lazyContext(initializer: (context: Context) -> T): LazyContext<T> = LazyContext(initializer)

class LazyContext<out T>(private val initializer: (context: Context) -> T, lock: Any? = null) {
    @Volatile
    private var _value: Any? = UNINITIALIZED
    private val lock = lock ?: this

    fun invalidate() {
        _value = UNINITIALIZED
    }

    operator fun invoke(context: Context): T {
        val _v1 = _value
        if (_v1 !== UNINITIALIZED)
            @Suppress("UNCHECKED_CAST")
            return _v1 as T

        return synchronized(lock) {
            val _v2 = _value
            if (_v2 !== UNINITIALIZED) {
                @Suppress("UNCHECKED_CAST")
                _v2 as T
            } else {
                val typedValue = initializer(context)
                _value = typedValue
                typedValue
            }
        }
    }
}