diff --git a/engine/src/main/java/org/terasology/engine/core/TerasologyEngine.java b/engine/src/main/java/org/terasology/engine/core/TerasologyEngine.java index ffeeaf41560..bb7c5d36cf6 100644 --- a/engine/src/main/java/org/terasology/engine/core/TerasologyEngine.java +++ b/engine/src/main/java/org/terasology/engine/core/TerasologyEngine.java @@ -29,7 +29,6 @@ import org.terasology.engine.core.subsystem.common.ThreadManagerSubsystem; import org.terasology.engine.core.subsystem.common.TimeSubsystem; import org.terasology.engine.core.subsystem.common.WorldGenerationSubsystem; -import org.terasology.engine.core.subsystem.rendering.ModuleRenderingSubsystem; import org.terasology.engine.entitySystem.prefab.Prefab; import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab; import org.terasology.engine.i18n.I18nSubsystem; @@ -175,7 +174,6 @@ public TerasologyEngine(TimeSubsystem timeSubsystem, Collection this.allSubsystems.add(new GameSubsystem()); this.allSubsystems.add(new I18nSubsystem()); this.allSubsystems.add(new TelemetrySubSystem()); - this.allSubsystems.add(new ModuleRenderingSubsystem()); // add all subsystem as engine module part. (needs for ECS classes loaded from external subsystems) allSubsystems.stream().map(Object::getClass).forEach(this::addToClassesOnClasspathsToAddToEngine); @@ -489,7 +487,6 @@ public boolean tick() { } Iterator updateCycles = timeSubsystem.getEngineTime().tick(); - CoreRegistry.setContext(currentState.getContext()); rootContext.get(NetworkSystem.class).setContext(currentState.getContext()); for (EngineSubsystem subsystem : allSubsystems) { @@ -586,6 +583,7 @@ private void switchState(GameState newState) { if (currentState != null) { currentState.dispose(); } + CoreRegistry.setContext(newState.getContext()); currentState = newState; LoggingContext.setGameState(newState); newState.init(this); diff --git a/engine/src/main/java/org/terasology/engine/core/bootstrap/EnvironmentSwitchHandler.java b/engine/src/main/java/org/terasology/engine/core/bootstrap/EnvironmentSwitchHandler.java index d24027b9322..152a3ab6862 100644 --- a/engine/src/main/java/org/terasology/engine/core/bootstrap/EnvironmentSwitchHandler.java +++ b/engine/src/main/java/org/terasology/engine/core/bootstrap/EnvironmentSwitchHandler.java @@ -107,7 +107,6 @@ public void handleSwitchToGameEnvironment(Context context) { autoConfigManager.loadConfigsIn(context); ModuleAwareAssetTypeManager assetTypeManager = context.get(ModuleAwareAssetTypeManager.class); - /* * The registering of the prefab formats is done in this method, because it needs to be done before * the environment of the asset manager gets changed. @@ -116,6 +115,7 @@ public void handleSwitchToGameEnvironment(Context context) { * existing then yet. */ unregisterPrefabFormats(assetTypeManager); + registeredPrefabFormat = new PrefabFormat(componentLibrary, typeHandlerLibrary); assetTypeManager.getAssetFileDataProducer(assetTypeManager .getAssetType(Prefab.class) diff --git a/engine/src/main/java/org/terasology/engine/core/modes/StateIngame.java b/engine/src/main/java/org/terasology/engine/core/modes/StateIngame.java index 5ec94ad180b..0c3bf91a4a2 100644 --- a/engine/src/main/java/org/terasology/engine/core/modes/StateIngame.java +++ b/engine/src/main/java/org/terasology/engine/core/modes/StateIngame.java @@ -8,11 +8,13 @@ import org.terasology.engine.core.ComponentSystemManager; import org.terasology.engine.core.GameEngine; import org.terasology.engine.core.GameThread; +import org.terasology.engine.core.TerasologyConstants; import org.terasology.engine.core.bootstrap.EnvironmentSwitchHandler; import org.terasology.engine.core.module.ModuleManager; import org.terasology.engine.core.subsystem.DisplayDevice; import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager; import org.terasology.engine.entitySystem.event.internal.EventSystem; +import org.terasology.engine.entitySystem.prefab.Prefab; import org.terasology.engine.entitySystem.systems.UpdateSubscriberSystem; import org.terasology.engine.game.GameManifest; import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker; @@ -28,7 +30,13 @@ import org.terasology.engine.rendering.nui.layers.mainMenu.MessagePopup; import org.terasology.engine.rendering.world.WorldRenderer; import org.terasology.engine.rendering.world.WorldRenderer.RenderingStage; +import org.terasology.engine.world.block.loader.BlockFamilyDefinition; import org.terasology.engine.world.chunks.ChunkProvider; +import org.terasology.gestalt.assets.Asset; +import org.terasology.gestalt.assets.AssetType; +import org.terasology.gestalt.assets.ResourceUrn; +import org.terasology.gestalt.assets.management.AssetTypeManager; +import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager; import org.terasology.gestalt.module.Module; import org.terasology.gestalt.module.ModuleEnvironment; import org.terasology.nui.databinding.ReadOnlyBinding; @@ -103,6 +111,19 @@ public void dispose(boolean shuttingDown) { ChunkProvider chunkProvider = context.get(ChunkProvider.class); chunkProvider.dispose(); + AssetTypeManager assetTypeManager = context.get(ModuleAwareAssetTypeManager.class); + // dispose all module assets + assetTypeManager.getAssetTypes().forEach(assetType -> { + for (ResourceUrn urn : assetType.getLoadedAssetUrns()) { + if (!urn.getModuleName().equals(TerasologyConstants.ENGINE_MODULE)) { + assetType.getAsset(urn).ifPresent(Asset::dispose); + } + } + }); + // dispose engine assets that should not be kept when switching game states + assetTypeManager.getAssetType(BlockFamilyDefinition.class).ifPresent(AssetType::disposeAll); + assetTypeManager.getAssetType(Prefab.class).ifPresent(AssetType::disposeAll); + boolean save = networkSystem.getMode().isAuthority(); if (save) { storageManager.waitForCompletionOfPreviousSaveAndStartSaving(); diff --git a/engine/src/main/java/org/terasology/engine/core/modes/StateLoading.java b/engine/src/main/java/org/terasology/engine/core/modes/StateLoading.java index f93ba8ec005..f303a955e5b 100644 --- a/engine/src/main/java/org/terasology/engine/core/modes/StateLoading.java +++ b/engine/src/main/java/org/terasology/engine/core/modes/StateLoading.java @@ -29,6 +29,7 @@ import org.terasology.engine.core.modes.loadProcesses.InitialiseSystems; import org.terasology.engine.core.modes.loadProcesses.InitialiseWorld; import org.terasology.engine.core.modes.loadProcesses.InitialiseWorldGenerator; +import org.terasology.engine.core.modes.loadProcesses.InitialiseRendering; import org.terasology.engine.core.modes.loadProcesses.JoinServer; import org.terasology.engine.core.modes.loadProcesses.LoadEntities; import org.terasology.engine.core.modes.loadProcesses.LoadExtraBlockData; @@ -141,6 +142,7 @@ public void init(GameEngine engine) { private void initClient() { loadProcesses.add(new JoinServer(context, gameManifest, joinStatus)); + loadProcesses.add(new InitialiseRendering(context)); loadProcesses.add(new InitialiseEntitySystem(context)); loadProcesses.add(new RegisterBlocks(context, gameManifest)); loadProcesses.add(new InitialiseGraphics(context)); @@ -165,6 +167,9 @@ private void initClient() { private void initHost() { loadProcesses.add(new RegisterMods(context, gameManifest)); + if(netMode.hasLocalClient()) { + loadProcesses.add(new InitialiseRendering(context)); + } loadProcesses.add(new InitialiseEntitySystem(context)); loadProcesses.add(new RegisterBlocks(context, gameManifest)); loadProcesses.add(new InitialiseGraphics(context)); diff --git a/engine/src/main/java/org/terasology/engine/core/modes/loadProcesses/InitialiseRendering.java b/engine/src/main/java/org/terasology/engine/core/modes/loadProcesses/InitialiseRendering.java new file mode 100644 index 00000000000..eb3a7394799 --- /dev/null +++ b/engine/src/main/java/org/terasology/engine/core/modes/loadProcesses/InitialiseRendering.java @@ -0,0 +1,42 @@ +// Copyright 2021 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +package org.terasology.engine.core.modes.loadProcesses; + +import org.terasology.engine.context.Context; +import org.terasology.engine.core.modes.SingleStepLoadProcess; +import org.terasology.engine.core.module.rendering.RenderingModuleRegistry; + +/** + * Add {@link RenderingModuleRegistry} to the game {@link Context}. + * + * The rendering system is required whenever a client starts or joins a game. As rendering may fail to re-initialise + * correctly when it has previously been constructed, this loading process will populate the {@link Context} with a + * freshly created rendering system. + * + * When switching the game state, the rendering system can just be disposed with the old state. + */ +public class InitialiseRendering extends SingleStepLoadProcess { + private final Context context; + + public InitialiseRendering(Context context) { + this.context = context; + } + + + @Override + public String getMessage() { + return "Initialising Rendering System..."; + } + + @Override + public boolean step() { + context.put(RenderingModuleRegistry.class, new RenderingModuleRegistry()); + return true; + } + + @Override + public int getExpectedCost() { + return 1; + } +} diff --git a/engine/src/main/java/org/terasology/engine/core/subsystem/rendering/ModuleRenderingSubsystem.java b/engine/src/main/java/org/terasology/engine/core/subsystem/rendering/ModuleRenderingSubsystem.java deleted file mode 100644 index d300558d5e8..00000000000 --- a/engine/src/main/java/org/terasology/engine/core/subsystem/rendering/ModuleRenderingSubsystem.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2021 The Terasology Foundation -// SPDX-License-Identifier: Apache-2.0 -package org.terasology.engine.core.subsystem.rendering; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.terasology.engine.context.Context; -import org.terasology.engine.core.ComponentSystemManager; -import org.terasology.engine.core.GameEngine; -import org.terasology.engine.core.modes.GameState; -import org.terasology.engine.core.module.rendering.RenderingModuleRegistry; -import org.terasology.engine.core.subsystem.EngineSubsystem; -import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager; - -public class ModuleRenderingSubsystem implements EngineSubsystem { - private static final Logger logger = LoggerFactory.getLogger(ModuleRenderingSubsystem.class); - - private RenderingModuleRegistry renderingModuleRegistry; - - @Override - public String getName() { - return "ModuleRendering"; - } - - @Override - public void preInitialise(Context rootContext) { - - } - - @Override - public void initialise(GameEngine engine, Context rootContext) { - this.renderingModuleRegistry = new RenderingModuleRegistry(); - rootContext.put(RenderingModuleRegistry.class, this.renderingModuleRegistry); - } - - @Override - public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager) { - - } - - @Override - public void postInitialise(Context context) { - - } - - @Override - public void preUpdate(GameState currentState, float delta) { - - } - - @Override - public void postUpdate(GameState currentState, float delta) { - - } - - @Override - public void preShutdown() { - - } - - @Override - public void shutdown() { - - } - - @Override - public void registerSystems(ComponentSystemManager componentSystemManager) { - - } -} diff --git a/engine/src/main/java/org/terasology/engine/rendering/opengl/GLSLMaterial.java b/engine/src/main/java/org/terasology/engine/rendering/opengl/GLSLMaterial.java index bc5123eca44..3a65a2d0bc3 100644 --- a/engine/src/main/java/org/terasology/engine/rendering/opengl/GLSLMaterial.java +++ b/engine/src/main/java/org/terasology/engine/rendering/opengl/GLSLMaterial.java @@ -103,6 +103,7 @@ public void bindTextures() { for (int slot : textureMap.keys()) { Texture texture = textureMap.get(slot); if (texture.isDisposed()) { + textureMap.remove(slot); logger.error("Attempted to bind disposed texture {}", texture); } else { shaderManager.bindTexture(slot, texture); diff --git a/engine/src/main/java/org/terasology/engine/world/block/DefaultColorSource.java b/engine/src/main/java/org/terasology/engine/world/block/DefaultColorSource.java index 1d5ca12e2fa..593f683ecaf 100644 --- a/engine/src/main/java/org/terasology/engine/world/block/DefaultColorSource.java +++ b/engine/src/main/java/org/terasology/engine/world/block/DefaultColorSource.java @@ -17,12 +17,10 @@ public Colorc calcColor(int x, int y, int z) { COLOR_LUT { @Override public Colorc calcColor(int x, int y, int z) { + ColorProvider colorProvider = CoreRegistry.get(ColorProvider.class); + // Return white as default if there aren't any color providers if (colorProvider == null) { - colorProvider = CoreRegistry.get(ColorProvider.class); - // Return white as default if there aren't any color providers - if (colorProvider == null) { - return Color.white; - } + return Color.white; } return colorProvider.colorLut(x, y, z); } @@ -30,16 +28,12 @@ public Colorc calcColor(int x, int y, int z) { FOLIAGE_LUT { @Override public Colorc calcColor(int x, int y, int z) { + ColorProvider colorProvider = CoreRegistry.get(ColorProvider.class); + // Return white as default if there aren't any color providers if (colorProvider == null) { - colorProvider = CoreRegistry.get(ColorProvider.class); - // Return white as default if there aren't any color providers - if (colorProvider == null) { - return Color.white; - } + return Color.white; } return colorProvider.foliageLut(x, y, z); } }; - - private static ColorProvider colorProvider; }