mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
slightly reduce memory usage — move settingsSavingComponents from ComponentStoreImpl because for each module we have instance
This commit is contained in:
@@ -25,7 +25,7 @@ const val APP_CONFIG = "\$APP_CONFIG$"
|
||||
private const val FILE_STORAGE_DIR = "options"
|
||||
private const val DEFAULT_STORAGE_SPEC = "${PathManager.DEFAULT_OPTIONS_FILE_NAME}${FileStorageCoreUtil.DEFAULT_EXT}"
|
||||
|
||||
class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager? = null) : ComponentStoreImpl() {
|
||||
class ApplicationStoreImpl(private val application: Application, pathMacroManager: PathMacroManager? = null) : ComponentStoreWithExtraComponents() {
|
||||
override val storageManager = ApplicationStorageManager(application, pathMacroManager)
|
||||
|
||||
// number of app components require some state, so, we load default state in test mode
|
||||
|
||||
@@ -23,7 +23,6 @@ import com.intellij.openapi.util.JDOMExternalizable
|
||||
import com.intellij.openapi.util.JDOMUtil
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.project.isDirectoryBased
|
||||
import com.intellij.ui.AppUIUtil
|
||||
import com.intellij.util.ArrayUtilRt
|
||||
import com.intellij.util.SmartList
|
||||
@@ -74,7 +73,6 @@ internal fun setRoamableComponentSaveThreshold(thresholdInSeconds: Int) {
|
||||
|
||||
abstract class ComponentStoreImpl : IComponentStore {
|
||||
private val components = Collections.synchronizedMap(THashMap<String, ComponentInfo>())
|
||||
private val settingsSavingComponents = com.intellij.util.containers.ContainerUtil.createLockFreeCopyOnWriteList<SettingsSavingComponent>()
|
||||
|
||||
internal open val project: Project?
|
||||
get() = null
|
||||
@@ -84,11 +82,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
|
||||
override abstract val storageManager: StateStorageManager
|
||||
|
||||
override final fun initComponent(component: Any, isService: Boolean) {
|
||||
if (component is SettingsSavingComponent) {
|
||||
settingsSavingComponents.add(component)
|
||||
}
|
||||
|
||||
override fun initComponent(component: Any, isService: Boolean) {
|
||||
var componentName = ""
|
||||
try {
|
||||
@Suppress("DEPRECATION")
|
||||
@@ -130,50 +124,27 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
return componentName
|
||||
}
|
||||
|
||||
override fun save(readonlyFiles: MutableList<SaveSessionAndFile>, isForce: Boolean) {
|
||||
var errors: MutableList<Throwable>? = null
|
||||
override final fun save(readonlyFiles: MutableList<SaveSessionAndFile>, isForce: Boolean) {
|
||||
val errors: MutableList<Throwable> = SmartList<Throwable>()
|
||||
|
||||
fun execute(handler: () -> Unit) {
|
||||
try {
|
||||
handler()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
if (errors == null) {
|
||||
errors = SmartList<Throwable>()
|
||||
}
|
||||
errors!!.add(e)
|
||||
}
|
||||
}
|
||||
|
||||
// component state uses scheme manager in an ipr project, so, we must save it before
|
||||
val isIprProject = project?.let { !it.isDirectoryBased } ?: false
|
||||
if (isIprProject) {
|
||||
settingsSavingComponents.firstOrNull { it is SchemeManagerFactoryBase }?.let {
|
||||
execute {
|
||||
it.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
beforeSaveComponents(errors)
|
||||
|
||||
val externalizationSession = if (components.isEmpty()) null else storageManager.startExternalization()
|
||||
if (externalizationSession != null) {
|
||||
errors = doSaveComponents(isForce, externalizationSession, errors)
|
||||
doSaveComponents(isForce, externalizationSession, errors)
|
||||
}
|
||||
|
||||
for (settingsSavingComponent in settingsSavingComponents) {
|
||||
if (!isIprProject || settingsSavingComponent !is SchemeManagerFactoryBase) {
|
||||
execute {
|
||||
settingsSavingComponent.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
afterSaveComponents(errors)
|
||||
|
||||
execute {
|
||||
try {
|
||||
saveAdditionalComponents(isForce)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
errors.add(e)
|
||||
}
|
||||
|
||||
if (externalizationSession != null) {
|
||||
errors = doSave(externalizationSession.createSaveSessions(), readonlyFiles, errors)
|
||||
doSave(externalizationSession.createSaveSessions(), readonlyFiles, errors)
|
||||
}
|
||||
CompoundRuntimeException.throwIfNotEmpty(errors)
|
||||
}
|
||||
@@ -181,10 +152,15 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
protected open fun saveAdditionalComponents(isForce: Boolean) {
|
||||
}
|
||||
|
||||
private fun doSaveComponents(isForce: Boolean, externalizationSession: ExternalizationSession, _errors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
protected open fun beforeSaveComponents(errors: MutableList<Throwable>) {
|
||||
}
|
||||
|
||||
protected open fun afterSaveComponents(errors: MutableList<Throwable>) {
|
||||
}
|
||||
|
||||
protected open fun doSaveComponents(isForce: Boolean, externalizationSession: ExternalizationSession, errors: MutableList<Throwable>): MutableList<Throwable>? {
|
||||
val isUseModificationCount = Registry.`is`("store.save.use.modificationCount", true)
|
||||
|
||||
var errors = _errors
|
||||
val names = ArrayUtilRt.toStringArray(components.keys)
|
||||
Arrays.sort(names)
|
||||
val timeLogPrefix = "Saving"
|
||||
@@ -223,9 +199,6 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
info.updateModificationCount(currentModificationCount)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
if (errors == null) {
|
||||
errors = SmartList<Throwable>()
|
||||
}
|
||||
errors.add(Exception("Cannot get $name component state", e))
|
||||
}
|
||||
|
||||
@@ -259,7 +232,9 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
runUndoTransparentWriteAction {
|
||||
try {
|
||||
VfsRootAccess.allowRootAccess(absolutePath)
|
||||
CompoundRuntimeException.throwIfNotEmpty(doSave(sessions))
|
||||
val errors: MutableList<Throwable> = SmartList<Throwable>()
|
||||
doSave(sessions, errors = errors)
|
||||
CompoundRuntimeException.throwIfNotEmpty(errors)
|
||||
}
|
||||
finally {
|
||||
VfsRootAccess.disallowRootAccess(absolutePath)
|
||||
@@ -283,12 +258,11 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
|
||||
protected open fun doSave(saveSessions: List<SaveSession>,
|
||||
readonlyFiles: MutableList<SaveSessionAndFile> = arrayListOf(),
|
||||
prevErrors: MutableList<Throwable>? = null): MutableList<Throwable>? {
|
||||
var errors = prevErrors
|
||||
errors: MutableList<Throwable>) {
|
||||
for (session in saveSessions) {
|
||||
errors = executeSave(session, readonlyFiles, prevErrors)
|
||||
executeSave(session, readonlyFiles, errors)
|
||||
}
|
||||
return errors
|
||||
return
|
||||
}
|
||||
|
||||
private fun initJdomExternalizable(@Suppress("DEPRECATION") component: JDOMExternalizable, componentName: String): String? {
|
||||
@@ -541,10 +515,7 @@ abstract class ComponentStoreImpl : IComponentStore {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun executeSave(session: SaveSession,
|
||||
readonlyFiles: MutableList<SaveSessionAndFile>,
|
||||
previousErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
var errors = previousErrors
|
||||
internal fun executeSave(session: SaveSession, readonlyFiles: MutableList<SaveSessionAndFile>, errors: MutableList<Throwable>) {
|
||||
try {
|
||||
session.save()
|
||||
}
|
||||
@@ -553,13 +524,8 @@ internal fun executeSave(session: SaveSession,
|
||||
readonlyFiles.add(SaveSessionAndFile(e.session ?: session, e.file))
|
||||
}
|
||||
catch (e: Exception) {
|
||||
if (errors == null) {
|
||||
errors = SmartList<Throwable>()
|
||||
}
|
||||
errors.add(e)
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
private fun findNonDeprecated(storages: Array<Storage>) = storages.firstOrNull { !it.deprecated } ?: throw AssertionError(
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.configurationStore
|
||||
|
||||
import com.intellij.openapi.components.SettingsSavingComponent
|
||||
import com.intellij.project.isDirectoryBased
|
||||
|
||||
abstract class ComponentStoreWithExtraComponents : ComponentStoreImpl() {
|
||||
private val settingsSavingComponents = com.intellij.util.containers.ContainerUtil.createLockFreeCopyOnWriteList<SettingsSavingComponent>()
|
||||
|
||||
override fun initComponent(component: Any, isService: Boolean) {
|
||||
if (component is SettingsSavingComponent) {
|
||||
settingsSavingComponents.add(component)
|
||||
}
|
||||
|
||||
super.initComponent(component, isService)
|
||||
}
|
||||
|
||||
override final fun beforeSaveComponents(errors: MutableList<Throwable>) {
|
||||
// component state uses scheme manager in an ipr project, so, we must save it before
|
||||
val isIprProject = project?.let { !it.isDirectoryBased } ?: false
|
||||
if (isIprProject) {
|
||||
settingsSavingComponents.firstOrNull { it is SchemeManagerFactoryBase }?.let {
|
||||
try {
|
||||
it.save()
|
||||
}
|
||||
catch(e: Throwable) {
|
||||
errors.add(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override final fun afterSaveComponents(errors: MutableList<Throwable>) {
|
||||
val isIprProject = project?.let { !it.isDirectoryBased } ?: false
|
||||
for (settingsSavingComponent in settingsSavingComponents) {
|
||||
if (!isIprProject || settingsSavingComponent !is SchemeManagerFactoryBase) {
|
||||
try {
|
||||
settingsSavingComponent.save()
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
errors.add(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ internal val PROJECT_FILE_STORAGE_ANNOTATION = FileStorageAnnotation(PROJECT_FIL
|
||||
internal val DEPRECATED_PROJECT_FILE_STORAGE_ANNOTATION = FileStorageAnnotation(PROJECT_FILE, true)
|
||||
|
||||
// cannot be `internal`, used in Upsource
|
||||
abstract class ProjectStoreBase(override final val project: ProjectImpl) : ComponentStoreImpl(), IProjectStore {
|
||||
abstract class ProjectStoreBase(override final val project: ProjectImpl) : ComponentStoreWithExtraComponents(), IProjectStore {
|
||||
// protected setter used in upsource
|
||||
// Zelix KlassMaster - ERROR: Could not find method 'getScheme()'
|
||||
var scheme = StorageScheme.DEFAULT
|
||||
@@ -302,7 +302,7 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
}
|
||||
}
|
||||
|
||||
override fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<SaveSessionAndFile>, prevErrors: MutableList<Throwable>?): MutableList<Throwable>? {
|
||||
override fun doSave(saveSessions: List<SaveSession>, readonlyFiles: MutableList<SaveSessionAndFile>, errors: MutableList<Throwable>) {
|
||||
try {
|
||||
saveProjectName()
|
||||
}
|
||||
@@ -310,17 +310,16 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
LOG.error("Unable to store project name", e)
|
||||
}
|
||||
|
||||
var errors = prevErrors
|
||||
beforeSave(readonlyFiles)
|
||||
|
||||
errors = super.doSave(saveSessions, readonlyFiles, errors)
|
||||
super.doSave(saveSessions, readonlyFiles, errors)
|
||||
|
||||
val notifications = NotificationsManager.getNotificationsManager().getNotificationsOfType(UnableToSaveProjectNotification::class.java, project)
|
||||
if (readonlyFiles.isEmpty()) {
|
||||
for (notification in notifications) {
|
||||
notification.expire()
|
||||
}
|
||||
return errors
|
||||
return
|
||||
}
|
||||
|
||||
if (!notifications.isEmpty()) {
|
||||
@@ -336,7 +335,7 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
val oldList = readonlyFiles.toTypedArray()
|
||||
readonlyFiles.clear()
|
||||
for (entry in oldList) {
|
||||
errors = executeSave(entry.session, readonlyFiles, errors)
|
||||
executeSave(entry.session, readonlyFiles, errors)
|
||||
}
|
||||
|
||||
CompoundRuntimeException.throwIfNotEmpty(errors)
|
||||
@@ -345,8 +344,6 @@ private open class ProjectStoreImpl(project: ProjectImpl, private val pathMacroM
|
||||
dropUnableToSaveProjectNotification(project, getFilesList(readonlyFiles))
|
||||
throw IComponentStore.SaveCancelledException()
|
||||
}
|
||||
|
||||
return errors
|
||||
}
|
||||
|
||||
protected open fun beforeSave(readonlyFiles: MutableList<SaveSessionAndFile>) {
|
||||
|
||||
+1
-16
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.openapi.components;
|
||||
|
||||
import com.intellij.openapi.application.Application;
|
||||
@@ -21,7 +7,6 @@ import com.intellij.openapi.application.Application;
|
||||
* Component or service which implements this interfaces will be asked to save ({@link #save}) custom settings (in their own custom way)
|
||||
* when {@link Application#saveSettings()} (for Application level components) or {@link com.intellij.openapi.project.Project#save()}
|
||||
* (for Project level components) is invoked.
|
||||
* @see BaseComponent
|
||||
*/
|
||||
public interface SettingsSavingComponent {
|
||||
void save();
|
||||
|
||||
Reference in New Issue
Block a user