/* _____ _
* |_ _| |_ _ _ ___ ___ _ __ __ _
* | | | ' \| '_/ -_) -_) ' \/ _` |_
* |_| |_||_|_| \___\___|_|_|_\__,_(_)
*
* Threema for Android
* Copyright (c) 2024 Threema GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package ch.threema.data
import ch.threema.data.models.BaseModel
import ch.threema.data.models.ContactModel
import ch.threema.data.models.EditHistoryListModel
import ch.threema.data.models.EmojiReactionsModel
import ch.threema.data.models.GroupIdentity
import ch.threema.data.models.GroupModel
import ch.threema.data.repositories.EmojiReactionsRepository
/**
* The model cache holds a [ModelTypeCache] for every model type.
*
* Note: This class should be initialized only once in the application
* (except for use cases like testing).
*/
class ModelCache {
// Contacts are identified by their identity
val contacts = ModelTypeCache()
// Groups are identified by their group identity (creator identity and group id)
val groups = ModelTypeCache()
// Edit history entries are identified by their reference to a message's uid
val editHistory = ModelTypeCache()
// Emoji reactions are uniquely identified by a composition of the message's id (int) and type
val emojiReaction = ModelTypeCache()
}
/**
* The model type cache holds models of a certain type. It ensures that every model
* is instantiated only once.
*
* Internally, it uses a [WeakValueMap], so the values are not prevented from being
* garbage collected by the cache.
*/
class ModelTypeCache> {
private val map = WeakValueMap()
/**
* Return the cached model with the specified [identifier].
*/
fun get(identifier: TIdentifier): TModel? = this.map.get(identifier)
/**
* Return the cached model with the specified [identifier].
*
* If it cannot be found, create the model using the [miss] function, cache it
* and return it.
*/
fun getOrCreate(identifier: TIdentifier, miss: () -> TModel?): TModel? = this.map.getOrCreate(identifier, miss)
/**
* Remove the model with the specified [identifier] from the cache and return it.
*/
fun remove(identifier: TIdentifier): TModel? = this.map.remove(identifier)
}