temp: gestalt-di migration changes

This commit is contained in:
Benjamin Amos 2025-04-15 20:23:55 +01:00
parent 4e12a752a3
commit 9537e27db0
134 changed files with 2462 additions and 1003 deletions

View file

@ -0,0 +1,79 @@
## Engine Start-Up
```mermaid
graph TD;
PreInitialise[Pre-Initialise]
subgraph InitialiseManagers[Initialise Managers]
ModuleManager --> ModuleTypeRegistry --> ReflectFactory --> CopyStrategyLibrary --> TypeHandlerLibrary
TypeHandlerLibrary --> ModuleAwareAssetTypeHandler --> AssetManager
end
subgraph Initialise
ConfigurationSubsystem --> TimeSubsystem --> OtherSubsystems[Other Subsystems...] --> MonitoringSubsystem
MonitoringSubsystem --> PhysicsSubsystem --> CommandSubsystem --> NetworkSubsystem
NetworkSubsystem --> WorldGenerationSubsystem --> GameSubsystem --> I18nSubsystem --> TelemetrySubsystem
end
InitialiseAssets[Initialise Assets]
PostInitialise[Post-Initialise]
PreInitialise --> ModuleManager
AssetManager --> ConfigurationSubsystem
TelemetrySubsystem --> InitialiseAssets --> PostInitialise
```
### Why three phases?
_These are just my guesses based on the provided documentation._
#### Pre-initialise
This phase allows for doing most of the initialisation for a subsystem that does not rely on other subsystems.
Any subsystem state that needs to be accessed from other subsystems should be initialised here.
#### Initialise
This is the first point at which subsystems have access to the module context. Most subsystems will properly initialise
themselves here. It also allows subsystems to interact in a limited fashion, although this shouldn't be often needed.
#### Post-initialise
This is the last point at which a subsystem should initialise itself. After this stage, the subsystem should be
considered fully initialised. If a subsystem must depend immediately on other initialised subsystems, interact
with them here. This occurs after engine assets have been loaded.
#### Why is this not ideal?
- Most subsystems actually have an implicit undocumented dependency on `TimeSubsystem` and `ConfigurationSubsystem`.
These subsystems are hard-coded to always run first during engine start-up and as-such break the principle of
subsystem independence (subsystems should be allowed to initialise in any order within the same stage).
- These implicit dependencies prevent us from initialising subsystems in parallel, which is limiting potential
start-up performance.
- Currently, all subsystems are actually initialised in the sequence you see above for each stage.
This has the potential to harbour further implicit dependencies that we are yet unaware of.
- (It's also a blocker for migrating to use Gestalt-DI, which requires dependencies to declared up-front.)
#### Potential Improvements
- Change `TimeSubsystem` and `ConfigurationSubsystem` to be classified as managers. This would allow them to initialise
in sequence after `ModuleManager` but before subsystems' `initialise()`.
## Revised Start-Up Sequence (provisional)
```mermaid
graph TD;
PreInitialise[Pre-Initialise]
subgraph InitialiseManagers[Initialise Managers]
ModuleManager --> ModuleTypeRegistry --> ReflectFactory --> CopyStrategyLibrary --> TypeHandlerLibrary
TypeHandlerLibrary --> ModuleAwareAssetTypeHandler --> AssetManager
end
subgraph Initialise
ConfigurationSubsystem
TimeSubsystem
OtherSubsystems[Other Subsystems...]
MonitoringSubsystem
PhysicsSubsystem
CommandSubsystem
NetworkSubsystem
WorldGenerationSubsystem
GameSubsystem
I18nSubsystem
TelemetrySubsystem
end
InitialiseAssets[Initialise Assets]
PostInitialise[Post-Initialise]
PreInitialise --> ModuleManager
AssetManager --> Initialise
Initialise --> InitialiseAssets --> PostInitialise
```

View file

@ -0,0 +1,79 @@
### Engine States
```mermaid
graph TD;
subgraph MainMenu
subgraph MainMenuHandleInput[HandleInput]
MainMenuInputSystemHandleInput[InputSystem]
end
subgraph MainMenuUpdate[Update]
MainMenuNUIManagerUpdate[NUIManager] --> MainMenuEventSystemUpdate[EventSystem]
MainMenuEventSystemUpdate --> MainMenuStorageServiceWorkerUpdate[StorageServiceWorker]
end
subgraph MainMenuRender[Render]
MainMenuNUIManagerRender[NUIManager]
end
end
subgraph Loading
subgraph LoadingUpdate[Update]
LoadingLoadingScreenUpdate[LoadingScreen::updateStatus] --> LoadingNUIManagerUpdate[NUIManager]
LoadingNUIManagerUpdate--> LoadingStepUpdate[Step Update]
subgraph LoadingStepUpdate
direction TB
RegisterMods --> InitRenderingHeadlessCheck{!headless}
InitRenderingHeadlessCheck -->|true| InitialiseRendering --> InitialiseEntitySystem
InitRenderingHeadlessCheck -->|false| InitialiseEntitySystem
InitialiseEntitySystem --> RegisterBlocks --> InitGraphicsHeadlessCheck{!headless}
InitGraphicsHeadlessCheck -->|true| InitialiseGraphics --> LoadPrefabs
InitGraphicsHeadlessCheck -->|false| LoadPrefabs
LoadPrefabs --> ProcessBlockPrefabs
ProcessBlockPrefabs --> InitialiseComponentSystemManager --> InitInputHeadlessCheck{!headless}
InitInputHeadlessCheck -->|true| RegisterInputSystem --> RegisterSystems
InitInputHeadlessCheck -->|false| RegisterSystems
RegisterSystems --> InitialiseCommandSystem --> LoadExtraBlockData --> InitialiseWorld
InitialiseWorld --> RegisterBlockFamilies --> EnsureSaveGameConsistency
EnsureSaveGameConsistency --> InitialisePhysics --> InitialiseSystems --> PreBeginSystems
PreBeginSystems --> LoadEntities --> InitialiseBlockTypeEntities --> CreateWorldEntity
CreateWorldEntity --> InitialiseWorldGenerator --> InitialiseRecordAndReplay
InitialiseRecordAndReplay --> NetModeIsServerCheck{netMode.isServer}
NetModeIsServerCheck -->|true| StartServer --> PostBeginSystems
NetModeIsServerCheck -->|false| PostBeginSystems
PostBeginSystems --> NetModeHasLocalClientCheck{netMode.hasLocalClient}
NetModeHasLocalClientCheck -->|true| SetupLocalPlayer --> AwaitCharacterSpawn --> PrepareWorld
NetModeHasLocalClientCheck -->|false| PrepareWorld
PrepareWorld
end
end
subgraph LoadingRender[Render]
LoadingNUIManagerRender[NUIManager]
end
end
subgraph InGame
subgraph InGameHandleInput[HandleInput]
InGameHandleInputInputSystem[InputSystem]
end
subgraph InGameUpdate[Update]
InGameEventSystemUpdate[EventSystem] --> InGameComponentSystemsUpdate[UpdateSubscriberSystems]
InGameComponentSystemsUpdate --> InGameWorldRendererUpdate[WorldRenderer]
InGameWorldRendererUpdate --> InGameStorageManagerUpdate[StorageManager]
InGameStorageManagerUpdate --> InGameNUIManagerUpdate[NUIManager]
InGameNUIManagerUpdate --> InStorageServiceWorkerUpdate[StorageServiceWorker]
end
subgraph InGameRender[Render]
InGameDisplayDevicePrepareToRender[DisplayDevice::prepareToRender] --> InGameNUIManagerRender[NUIManager]
InGameNUIManagerRender--> InGameWorldRendererrRender[WorldRenderer]
end
end
MainMenu -->|Start Game| Loading
Loading -->|Failed| MainMenu
Loading -->|Succeeded| InGame
InGame -->|Exit To Main Menu| MainMenu
```

View file

@ -7,12 +7,15 @@
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.naming.Name;
import java.io.IOException;
@ -46,41 +49,48 @@ class Environment {
protected void reset(Set<Name> moduleNames) throws IOException {
this.context = new ContextImpl();
ServiceRegistry serviceRegistry = new ServiceRegistry();
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = new RecordAndReplayCurrentStatus();
context.put(RecordAndReplayCurrentStatus.class, recordAndReplayCurrentStatus);
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayCurrentStatus);
CoreRegistry.setContext(context);
setupPathManager();
Bullet.init(true, false);
setupConfig();
setupConfig(serviceRegistry);
setupModuleManager(moduleNames);
ModuleManager moduleManager = setupModuleManager(serviceRegistry, moduleNames);
setupDisplay();
setupDisplay(serviceRegistry);
setupAudio();
setupAudio(serviceRegistry);
AssetManager assetManager = setupAssetManager();
AssetManager assetManager = setupAssetManager(moduleManager, serviceRegistry);
setupBlockManager(assetManager);
setupBlockManager(serviceRegistry, assetManager);
setupExtraDataManager(context);
setupExtraDataManager(serviceRegistry, context);
setupCollisionManager();
setupCollisionManager(serviceRegistry);
setupNetwork();
setupNetwork(serviceRegistry);
setupEntitySystem();
setupEntitySystem(serviceRegistry);
setupStorageManager();
setupStorageManager(serviceRegistry);
setupComponentManager();
setupComponentManager(serviceRegistry);
setupWorldProvider();
setupWorldProvider(serviceRegistry);
setupCelestialSystem();
setupCelestialSystem(serviceRegistry);
this.context = new ContextImpl(serviceRegistry);
registerBlockTypeHandlers(this.context);
registerCollisionTypeHandlers(this.context);
initComponentManager(this.context);
loadPrefabs();
}
@ -89,7 +99,11 @@ protected void loadPrefabs() {
// empty
}
protected void setupComponentManager() {
protected void setupComponentManager(ServiceRegistry serviceRegistry) {
// empty
}
protected void initComponentManager(Context context) {
// empty
}
@ -97,61 +111,70 @@ protected void setupPathManager() throws IOException {
PathManager.getInstance();
}
protected void setupModuleManager(Set<Name> moduleNames) {
// empty
}
protected void setupDisplay() {
// empty
}
protected void setupConfig() {
// empty
}
protected void setupAudio() {
// empty
}
protected AssetManager setupAssetManager() {
protected ModuleManager setupModuleManager(ServiceRegistry serviceRegistry, Set<Name> moduleNames) {
// empty
return null;
}
protected AssetManager setupEmptyAssetManager() {
protected void setupDisplay(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupConfig(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupAudio(ServiceRegistry serviceRegistry) {
// empty
}
protected AssetManager setupAssetManager(ModuleManager moduleManager, ServiceRegistry serviceRegistry) {
// empty
return null;
}
protected void setupBlockManager(AssetManager assetManager) {
protected AssetManager setupEmptyAssetManager(ModuleManager moduleManager, ServiceRegistry serviceRegistry) {
// empty
return null;
}
protected void setupBlockManager(ServiceRegistry serviceRegistry, AssetManager assetManager) {
// empty
}
protected void setupExtraDataManager(Context context) {
protected void registerBlockTypeHandlers(Context context) {
// empty
}
protected void setupCollisionManager() {
protected void setupExtraDataManager(ServiceRegistry serviceRegistry, Context context) {
// empty
}
protected void setupEntitySystem() {
protected void setupCollisionManager(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupNetwork() {
protected void registerCollisionTypeHandlers(Context context) {
// empty
}
protected void setupStorageManager() throws IOException {
protected void setupEntitySystem(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupWorldProvider() {
protected void setupNetwork(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupCelestialSystem() {
protected void setupStorageManager(ServiceRegistry serviceRegistry) throws IOException {
// empty
}
protected void setupWorldProvider(ServiceRegistry serviceRegistry) {
// empty
}
protected void setupCelestialSystem(ServiceRegistry serviceRegistry) {
// empty
}

View file

@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.audio.AudioManager;
import org.terasology.engine.audio.StaticSound;
import org.terasology.engine.audio.StreamingSound;
@ -13,6 +14,7 @@
import org.terasology.engine.config.Config;
import org.terasology.engine.config.PlayerConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.PathManager;
@ -26,9 +28,10 @@
import org.terasology.engine.core.subsystem.headless.assets.HeadlessShader;
import org.terasology.engine.core.subsystem.headless.assets.HeadlessSkeletalMesh;
import org.terasology.engine.core.subsystem.headless.assets.HeadlessTexture;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.game.Game;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker;
import org.terasology.engine.logic.behavior.asset.BehaviorTree;
import org.terasology.engine.network.NetworkSystem;
@ -40,7 +43,9 @@
import org.terasology.engine.persistence.typeHandling.extensionTypes.CollisionGroupTypeHandler;
import org.terasology.engine.physics.CollisionGroup;
import org.terasology.engine.physics.CollisionGroupManager;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.CharacterStateEventPositionMap;
import org.terasology.engine.recording.DirectionAndOriginPosRecorder;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.RecordAndReplaySerializer;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.rendering.assets.animation.MeshAnimation;
@ -75,6 +80,7 @@
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.engine.world.internal.WorldInfo;
import org.terasology.engine.world.sun.BasicCelestialModel;
import org.terasology.engine.world.sun.CelestialModel;
import org.terasology.engine.world.sun.CelestialSystem;
import org.terasology.engine.world.sun.DefaultCelestialSystem;
import org.terasology.engine.world.time.WorldTime;
@ -83,7 +89,7 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.naming.Name;
import org.terasology.nui.asset.UIElement;
import org.terasology.nui.skin.UISkinAsset;
@ -121,71 +127,80 @@ public HeadlessEnvironment(Name... modules) {
}
@Override
protected void setupStorageManager() throws IOException {
ModuleManager moduleManager = context.get(ModuleManager.class);
EngineEntityManager engineEntityManager = context.get(EngineEntityManager.class);
BlockManager blockManager = context.get(BlockManager.class);
RecordAndReplaySerializer recordAndReplaySerializer = context.get(RecordAndReplaySerializer.class);
Path savePath = PathManager.getInstance().getSavePath("world1");
protected void setupStorageManager(ServiceRegistry serviceRegistry) throws IOException {
Game game = new Game();
game.load(new GameManifest("world1", "world1", 0));
serviceRegistry.with(Game.class).lifetime(Lifetime.Singleton).use(() -> game);
RecordAndReplayUtils recordAndReplayUtils = new RecordAndReplayUtils();
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = context.get(RecordAndReplayCurrentStatus.class);
serviceRegistry.with(RecordAndReplayUtils.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayUtils);
CharacterStateEventPositionMap characterStateEventPositionMap = new CharacterStateEventPositionMap();
serviceRegistry.with(CharacterStateEventPositionMap.class).lifetime(Lifetime.Singleton).use(() -> characterStateEventPositionMap);
DirectionAndOriginPosRecorderList directionAndOriginPosRecorderList = new DirectionAndOriginPosRecorderList();
serviceRegistry.with(DirectionAndOriginPosRecorderList.class).lifetime(Lifetime.Singleton).use(() -> directionAndOriginPosRecorderList);
serviceRegistry.with(RecordAndReplaySerializer.class).lifetime(Lifetime.Singleton);
ModuleEnvironment environment = context.get(ModuleManager.class).getEnvironment();
context.put(BlockFamilyLibrary.class, new BlockFamilyLibrary(environment, context));
ExtraBlockDataManager extraDataManager = context.get(ExtraBlockDataManager.class);
context.put(StorageManager.class, new ReadWriteStorageManager(savePath, moduleManager.getEnvironment(),
engineEntityManager, blockManager, extraDataManager, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus));
serviceRegistry.with(BlockFamilyLibrary.class).lifetime(Lifetime.Singleton).use(BlockFamilyLibrary.class);
serviceRegistry.with(StorageManager.class).lifetime(Lifetime.Singleton).use(ReadWriteStorageManager.class);
}
@Override
protected void setupNetwork() {
protected void setupNetwork(ServiceRegistry serviceRegistry) {
EngineTime mockTime = mock(EngineTime.class);
context.put(Time.class, mockTime);
NetworkSystem networkSystem = new NetworkSystemImpl(mockTime, getContext());
context.put(NetworkSystem.class, networkSystem);
serviceRegistry.with(Time.class).lifetime(Lifetime.Singleton).use(() -> mockTime);
serviceRegistry.with(EngineTime.class).lifetime(Lifetime.Singleton).use(() -> mockTime);
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(NetworkSystemImpl.class);
}
@Override
protected void setupEntitySystem() {
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
protected void setupEntitySystem(ServiceRegistry serviceRegistry) {
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
}
@Override
protected void setupCollisionManager() {
protected void setupCollisionManager(ServiceRegistry serviceRegistry) {
CollisionGroupManager collisionGroupManager = new CollisionGroupManager();
context.put(CollisionGroupManager.class, collisionGroupManager);
serviceRegistry.with(CollisionGroupManager.class).lifetime(Lifetime.Singleton).use(() -> collisionGroupManager);
}
@Override
protected void registerCollisionTypeHandlers(Context context) {
CollisionGroupManager collisionGroupManager = context.get(CollisionGroupManager.class);
context.get(TypeHandlerLibrary.class).addTypeHandler(CollisionGroup.class, new CollisionGroupTypeHandler(collisionGroupManager));
}
@Override
protected void setupBlockManager(AssetManager assetManager) {
protected void setupBlockManager(ServiceRegistry serviceRegistry, AssetManager assetManager) {
WorldAtlas worldAtlas = new NullWorldAtlas();
BlockManagerImpl blockManager = new BlockManagerImpl(worldAtlas, assetManager);
context.put(BlockManager.class, blockManager);
serviceRegistry.with(BlockManager.class).lifetime(Lifetime.Singleton).use(() -> blockManager);
}
@Override
protected void registerBlockTypeHandlers(Context context) {
BlockManager blockManager = context.get(BlockManager.class);
TypeHandlerLibrary typeHandlerLibrary = context.get(TypeHandlerLibrary.class);
typeHandlerLibrary.addTypeHandler(BlockFamily.class, new BlockFamilyTypeHandler(blockManager));
typeHandlerLibrary.addTypeHandler(Block.class, new BlockTypeHandler(blockManager));
}
@Override
protected void setupExtraDataManager(Context context) {
context.put(ExtraBlockDataManager.class, new ExtraBlockDataManager(context));
protected void setupExtraDataManager(ServiceRegistry serviceRegistry, Context context) {
serviceRegistry.with(ExtraBlockDataManager.class).lifetime(Lifetime.Singleton).use(ExtraBlockDataManager.class);
}
@Override
protected AssetManager setupEmptyAssetManager() {
protected AssetManager setupEmptyAssetManager(ModuleManager moduleManager, ServiceRegistry serviceRegistry) {
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
assetTypeManager.switchEnvironment(context.get(ModuleManager.class).getEnvironment());
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(ModuleAwareAssetTypeManager.class, assetTypeManager);
context.put(AssetManager.class, assetTypeManager.getAssetManager());
serviceRegistry.with(ModuleAwareAssetTypeManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager);
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
return assetTypeManager.getAssetManager();
}
@Override
protected AssetManager setupAssetManager() {
protected AssetManager setupAssetManager(ModuleManager moduleManager, ServiceRegistry serviceRegistry) {
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
// cast lambdas explicitly to avoid inconsistent compiler behavior wrt. type inference
@ -240,43 +255,47 @@ protected AssetManager setupAssetManager() {
assetTypeManager.createAssetType(Subtexture.class,
Subtexture::new);
assetTypeManager.switchEnvironment(context.get(ModuleManager.class).getEnvironment());
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(ModuleAwareAssetTypeManager.class, assetTypeManager);
context.put(AssetManager.class, assetTypeManager.getAssetManager());
serviceRegistry.with(ModuleAwareAssetTypeManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager);
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
return assetTypeManager.getAssetManager();
}
@Override
protected void setupAudio() {
protected void setupAudio(ServiceRegistry serviceRegistry) {
NullAudioManager audioManager = new NullAudioManager();
context.put(AudioManager.class, audioManager);
serviceRegistry.with(AudioManager.class).lifetime(Lifetime.Singleton).use(() -> audioManager);
}
@Override
protected void setupConfig() {
Config config = new Config(context);
protected void setupConfig(ServiceRegistry serviceRegistry) {
Config config = new Config();
config.loadDefaults();
context.put(Config.class, config);
context.put(StorageServiceWorker.class, mock(StorageServiceWorker.class));
context.put(PlayerConfig.class, mock(PlayerConfig.class));
serviceRegistry.with(Config.class).lifetime(Lifetime.Singleton).use(() -> config);
StorageServiceWorker storageServiceWorker = mock(StorageServiceWorker.class);
serviceRegistry.with(StorageServiceWorker.class).lifetime(Lifetime.Singleton).use(() -> storageServiceWorker);
PlayerConfig playerConfig = mock(PlayerConfig.class);
serviceRegistry.with(PlayerConfig.class).lifetime(Lifetime.Singleton).use(() -> playerConfig);
}
@Override
protected void setupModuleManager(Set<Name> moduleNames) throws RuntimeException {
protected ModuleManager setupModuleManager(ServiceRegistry serviceRegistry, Set<Name> moduleNames) throws RuntimeException {
TypeRegistry.WHITELISTED_CLASSES = ExternalApiWhitelist.CLASSES.stream().map(Class::getName).collect(Collectors.toSet());
ModuleManager moduleManager = ModuleManagerFactory.create();
ModuleTypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
context.put(TypeRegistry.class, typeRegistry);
context.put(ModuleTypeRegistry.class, typeRegistry);
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
serviceRegistry.with(ModuleTypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
moduleManager.resolveAndLoadEnvironment(moduleNames);
moduleManager.resolveAndLoadEnvironment(context, moduleNames);
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
return moduleManager;
}
@Override
@ -287,29 +306,31 @@ protected void setupPathManager() throws IOException {
}
@Override
protected void setupComponentManager() {
ComponentSystemManager componentSystemManager = new ComponentSystemManager(context);
componentSystemManager.initialise();
context.put(ComponentSystemManager.class, componentSystemManager);
protected void setupComponentManager(ServiceRegistry serviceRegistry) {
serviceRegistry.with(ComponentSystemManager.class).lifetime(Lifetime.Singleton).use(ComponentSystemManager.class);
}
@Override
protected void setupWorldProvider() {
protected void initComponentManager(Context context) {
context.get(ComponentSystemManager.class).initialise();
}
@Override
protected void setupWorldProvider(ServiceRegistry serviceRegistry) {
WorldProvider worldProvider = mock(WorldProvider.class);
when(worldProvider.getWorldInfo()).thenReturn(new WorldInfo());
when(worldProvider.getTime()).thenReturn(WORLD_TIME);
context.put(WorldProvider.class, worldProvider);
serviceRegistry.with(WorldProvider.class).lifetime(Lifetime.Singleton).use(() -> worldProvider);
}
@Override
protected void setupCelestialSystem() {
DefaultCelestialSystem celestialSystem = new DefaultCelestialSystem(new BasicCelestialModel(), context);
context.put(CelestialSystem.class, celestialSystem);
protected void setupCelestialSystem(ServiceRegistry serviceRegistry) {
serviceRegistry.with(CelestialModel.class).lifetime(Lifetime.Singleton).use(BasicCelestialModel.class);
serviceRegistry.with(CelestialSystem.class).lifetime(Lifetime.Singleton).use(DefaultCelestialSystem.class);
}
@Override
protected void loadPrefabs() {
LoadPrefabs prefabLoadStep = new LoadPrefabs(context);
boolean complete = false;
@ -322,6 +343,7 @@ protected void loadPrefabs() {
@Override
public void close() throws RuntimeException {
// it would be nice, if elements in the context implemented (Auto)Closeable
// TODO: It appears that Gestalt-8 DI does close AutoClosable objects in the context on exit?
// The StorageManager creates a thread pool (through TaskMaster)
// which isn't closed automatically
@ -330,7 +352,6 @@ public void close() throws RuntimeException {
storageManager.finishSavingAndShutdown();
}
super.close();
}

View file

@ -10,6 +10,7 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.PathManagerProvider;
@ -107,7 +108,9 @@ public void setup() {
}
ScreenGrabber grabber = Mockito.mock(ScreenGrabber.class);
hostContext.put(ScreenGrabber.class, grabber);
CoreRegistry.put(GameEngine.class, host);
Context coreContextOverride = new ContextImpl(CoreRegistry.get(Context.class));
coreContextOverride.put(GameEngine.class, host);
CoreRegistry.setContext(coreContextOverride);
}
/**
@ -295,16 +298,18 @@ TerasologyEngine createHost(NetworkMode hostNetworkMode) throws IOException {
* return true if the connection to the host was successful and the client is in state <i>in-game</i>.
*/
boolean connectToHost(TerasologyEngine client, MainLoop mainLoop) {
CoreRegistry.put(Config.class, client.getFromEngineContext(Config.class));
Context coreContextOverride = client.createChildContext();
CoreRegistry.setContext(coreContextOverride);
coreContextOverride.put(Config.class, client.getFromEngineContext(Config.class));
JoinStatus joinStatus = null;
try {
joinStatus = client.getFromEngineContext(NetworkSystem.class).join("localhost", 25777);
joinStatus = coreContextOverride.get(NetworkSystem.class).join("localhost", 25777);
} catch (InterruptedException e) {
logger.warn("Interrupted while joining: ", e);
}
client.changeState(new StateLoading(joinStatus));
CoreRegistry.put(GameEngine.class, client);
coreContextOverride.put(GameEngine.class, client);
// TODO: subscribe to state change and return an asynchronous result
// so that we don't need to pass mainLoop to here.

View file

@ -7,7 +7,6 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.TerasologyConstants;
@ -16,27 +15,39 @@
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.rendering.world.viewDistance.ViewDistance;
import org.terasology.engine.testUtil.WithUnittestModule;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleMetadataJsonAdapter;
import org.terasology.gestalt.module.ModuleRegistry;
import javax.inject.Inject;
import java.io.IOException;
import java.nio.file.Path;
final class IntegrationEnvironmentSubsystem implements EngineSubsystem {
private static final Logger logger = LoggerFactory.getLogger(IntegrationEnvironmentSubsystem.class);
@Inject
protected ModuleManager moduleManager;
@Inject
protected Config config;
@Inject
protected SystemConfig systemConfig;
@Inject
public IntegrationEnvironmentSubsystem() {
}
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
ModuleManager moduleManager = rootContext.getValue(ModuleManager.class);
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
WithUnittestModule.registerUnittestModule(moduleManager);
registerCurrentDirectoryIfModule(moduleManager);
configure(rootContext);
configure(serviceRegistry);
}
/**
@ -45,12 +56,9 @@ public void initialise(GameEngine engine, Context rootContext) {
* You can override this by defining your own EngineSubsystem and passing it to
* {@link IntegrationEnvironment#subsystem()}; it will run after this does.
*/
static void configure(Context context) {
Config config = context.getValue(Config.class);
private void configure(ServiceRegistry serviceRegistry) {
config.getRendering().setViewDistance(ViewDistance.LEGALLY_BLIND);
SystemConfig sys = context.getValue(SystemConfig.class);
sys.writeSaveGamesEnabled.set(false);
systemConfig.writeSaveGamesEnabled.set(false);
}
/**

View file

@ -3,6 +3,7 @@
package org.terasology.engine.testUtil;
import com.google.common.collect.ImmutableList;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.gestalt.module.Module;
import org.terasology.nui.UIWidget;
@ -16,7 +17,7 @@ public static ModuleManager create() {
// Loading screens, among other things, break when NUI classes are not added to engine.
ModuleManager moduleManager = new ModuleManager("", ImmutableList.of(UIWidget.class));
Module unittestModule = moduleManager.registerPackageModule("org.terasology.unittest");
moduleManager.resolveAndLoadEnvironment(unittestModule.getId());
moduleManager.resolveAndLoadEnvironment(new ContextImpl(), unittestModule.getId());
return moduleManager;
}
}

View file

@ -3,11 +3,17 @@
package org.terasology.engine.testUtil;
import org.terasology.engine.config.Config;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.naming.Name;
import javax.inject.Inject;
/**
* This subsystem registers the {@code unittest} module containing stub component classes with the {@link ModuleManager} before the engine
@ -21,20 +27,32 @@
* in the environment and then things might break with an unclear error again.
*/
public class WithUnittestModule implements EngineSubsystem {
@Inject
protected ModuleManager moduleManager;
@Inject
public WithUnittestModule() {
}
@Override
public String getName() {
return "Unittest";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
EngineSubsystem.super.initialise(engine, rootContext);
ModuleManager manager = rootContext.get(ModuleManager.class);
registerUnittestModule(manager);
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
EngineSubsystem.super.initialise(engine, serviceRegistry);
registerUnittestModule(moduleManager);
}
public static void registerUnittestModule(ModuleManager manager) {
Module unittestModule = manager.registerPackageModule("org.terasology.unittest");
manager.resolveAndLoadEnvironment(unittestModule.getId());
manager.resolveAndLoadEnvironment(new ContextImpl(), unittestModule.getId());
}
@Override
public void postInitialise(Context context) {
EngineSubsystem.super.postInitialise(context);
context.get(Config.class).getDefaultModSelection().addModule(new Name("unittest"));
}
}

View file

@ -5,10 +5,13 @@
import org.terasology.engine.core.subsystem.EngineSubsystem;
import javax.inject.Inject;
public class StubSubsystem implements EngineSubsystem {
final String name;
StubSubsystem(String name) {
@Inject
public StubSubsystem(String name) {
this.name = name;
}

View file

@ -10,7 +10,9 @@
import org.junit.jupiter.api.io.TempDir;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.PathManager;
@ -19,7 +21,9 @@
import org.terasology.engine.core.modes.loadProcesses.LoadPrefabs;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.game.Game;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.logic.console.Console;
import org.terasology.engine.logic.console.ConsoleImpl;
import org.terasology.engine.network.NetworkSystem;
@ -28,14 +32,11 @@
import org.terasology.engine.persistence.internal.ReadWriteStorageManager;
import org.terasology.engine.recording.CharacterStateEventPositionMap;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.RecordAndReplaySerializer;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.recording.RecordedEventStore;
import org.terasology.engine.world.block.BlockManager;
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.naming.Name;
import org.terasology.reflection.TypeRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import java.nio.file.Path;
@ -68,45 +69,42 @@ public static void setupEnvironment(@TempDir Path tempHome) throws Exception {
*/
env = new HeadlessEnvironment(new Name("engine"), new Name("unittest"));
context = env.getContext();
CoreRegistry.setContext(context);
moduleManager = context.get(ModuleManager.class);
}
@BeforeEach
public void setup() throws Exception {
context.put(ModuleManager.class, moduleManager);
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = context.get(RecordAndReplayCurrentStatus.class);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
mockTime = mock(EngineTime.class);
context.put(Time.class, mockTime);
serviceRegistry.with(Time.class).lifetime(Lifetime.Singleton).use(() -> mockTime);
NetworkSystemImpl networkSystem = new NetworkSystemImpl(mockTime, context);
context.put(Game.class, new Game());
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
engineEntityManager = context.get(EngineEntityManager.class);
BlockManager mockBlockManager = context.get(BlockManager.class); // 'mock' added to avoid hiding a field
ExtraBlockDataManager extraDataManager = context.get(ExtraBlockDataManager.class);
RecordedEventStore recordedEventStore = new RecordedEventStore();
serviceRegistry.with(Game.class).lifetime(Lifetime.Singleton).use(Game::new);
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
RecordAndReplayUtils recordAndReplayUtils = new RecordAndReplayUtils();
context.put(RecordAndReplayUtils.class, recordAndReplayUtils);
serviceRegistry.with(RecordAndReplayUtils.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayUtils);
CharacterStateEventPositionMap characterStateEventPositionMap = new CharacterStateEventPositionMap();
context.put(CharacterStateEventPositionMap.class, characterStateEventPositionMap);
serviceRegistry.with(CharacterStateEventPositionMap.class).lifetime(Lifetime.Singleton).use(() -> characterStateEventPositionMap);
DirectionAndOriginPosRecorderList directionAndOriginPosRecorderList = new DirectionAndOriginPosRecorderList();
context.put(DirectionAndOriginPosRecorderList.class, directionAndOriginPosRecorderList);
RecordAndReplaySerializer recordAndReplaySerializer = new RecordAndReplaySerializer(engineEntityManager,
recordedEventStore, recordAndReplayUtils, characterStateEventPositionMap,
directionAndOriginPosRecorderList, moduleManager, context.get(TypeRegistry.class));
context.put(RecordAndReplaySerializer.class, recordAndReplaySerializer);
serviceRegistry.with(DirectionAndOriginPosRecorderList.class).lifetime(Lifetime.Singleton).use(() -> directionAndOriginPosRecorderList);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Path savePath = PathManager.getInstance().getSavePath("world1");
context.put(StorageManager.class, new ReadWriteStorageManager(savePath, moduleManager.getEnvironment(),
engineEntityManager, mockBlockManager, extraDataManager, recordAndReplaySerializer,
recordAndReplayUtils, recordAndReplayCurrentStatus));
Game game = new Game();
game.load(new GameManifest("world1", "world1", 0));
serviceRegistry.with(StorageManager.class).lifetime(Lifetime.Singleton).use(ReadWriteStorageManager.class);
serviceRegistry.with(ComponentSystemManager.class).lifetime(Lifetime.Singleton).use(ComponentSystemManager.class);
serviceRegistry.with(Console.class).lifetime(Lifetime.Singleton).use(ConsoleImpl.class);
context = new ContextImpl(context, serviceRegistry);
engineEntityManager = context.get(EngineEntityManager.class);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), moduleManager.getEnvironment(), engineEntityManager);
ComponentSystemManager componentSystemManager = new ComponentSystemManager(context);
context.put(ComponentSystemManager.class, componentSystemManager);
LoadPrefabs prefabLoadStep = new LoadPrefabs(context);
boolean complete = false;
@ -115,7 +113,7 @@ public void setup() throws Exception {
complete = prefabLoadStep.step();
}
context.get(ComponentSystemManager.class).initialise();
context.put(Console.class, new ConsoleImpl(context));
CoreRegistry.setContext(context);
}
@AfterAll

View file

@ -6,14 +6,15 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.ArgumentCaptor;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataReader;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataSerializer;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataWriter;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.naming.Name;
import org.terasology.persistence.serializers.Serializer;
@ -26,7 +27,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class AutoConfigManagerTest {
@ -59,12 +59,10 @@ public void setUp(@TempDir Path tempHome) throws Exception {
@Test
public void testLoad() {
autoConfigManager.loadConfigsIn(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
autoConfigManager.loadConfigsIn(environment, serviceRegistry);
ArgumentCaptor<TestAutoConfig> argumentCaptor = ArgumentCaptor.forClass(TestAutoConfig.class);
verify(context).put(eq(TestAutoConfig.class), argumentCaptor.capture());
TestAutoConfig value = argumentCaptor.getValue();
TestAutoConfig value = new ContextImpl(serviceRegistry).get(TestAutoConfig.class);
assertEquals(new SimpleUri(PROVIDING_MODULE, TestAutoConfig.class.getName()), value.getId());
}
}

View file

@ -5,6 +5,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.BindsConfig;
import org.terasology.engine.config.facade.BindsConfiguration;
import org.terasology.engine.context.Context;
@ -17,6 +18,7 @@
import org.terasology.engine.input.DefaultBinding;
import org.terasology.engine.input.RegisterBindAxis;
import org.terasology.engine.input.RegisterBindButton;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.ModuleMetadata;
@ -55,13 +57,15 @@ public class BindsSubsystemTest {
public void setUp() {
bindsSubsystem = new BindsSubsystem();
bindsConfiguration = new BindsConfigAdapter(new BindsConfig());
context = new ContextImpl();
context.put(BindsConfiguration.class, bindsConfiguration);
bindsSubsystem.preInitialise(context);
setUpMockModuleEnvironment();
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(BindsConfiguration.class).lifetime(Lifetime.Singleton).use(() -> bindsConfiguration);
bindsSubsystem.preInitialise(serviceRegistry);
setUpMockModuleEnvironment(serviceRegistry);
context = new ContextImpl(serviceRegistry);
((ContextImpl) context).inject(bindsSubsystem);
}
private void setUpMockModuleEnvironment() {
private void setUpMockModuleEnvironment(ServiceRegistry serviceRegistry) {
ModuleManager moduleManager = mock(ModuleManager.class);
ModuleRegistry moduleRegistry = new TableModuleRegistry();
@ -81,7 +85,7 @@ private void setUpMockModuleEnvironment() {
when(environment.getTypesAnnotatedWith(eq(RegisterBindAxis.class))).thenReturn(registerRealBindAxisClasses);
when(environment.getTypesAnnotatedWith(eq(RegisterBindAxis.class), any())).thenReturn(registerRealBindAxisClasses);
when(environment.getModuleProviding(any())).thenReturn(new Name(TEST_MODULE));
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
}
@Test

View file

@ -6,15 +6,18 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.EntityInfoComponent;
import org.terasology.engine.entitySystem.entity.internal.EntityScope;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.network.NetworkMode;
@ -25,6 +28,10 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@ -45,14 +52,17 @@ public class BaseEntityRefTest {
@BeforeAll
public static void setupClass() throws Exception {
context = new ContextImpl();
ServiceRegistry serviceRegistry = new ServiceRegistry();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
assetTypeManager.createAssetType(Prefab.class, PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> new RecordAndReplayCurrentStatus());
context = new ContextImpl(serviceRegistry);
CoreRegistry.setContext(context);
}
@ -60,9 +70,14 @@ public static void setupClass() throws Exception {
public void setup() {
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
entityManager = (PojoEntityManager) context.get(EntityManager.class);
ref = entityManager.create();

View file

@ -6,12 +6,20 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.OwnershipHelper;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import org.terasology.unittest.stubs.OwnerComponent;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.network.NetworkSystem;
@ -38,15 +46,24 @@ public static void setupClass() throws Exception {
@BeforeEach
public void setup() {
ContextImpl context = new ContextImpl();
context.put(ModuleManager.class, moduleManager);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
AssetManager assetManager = mock(AssetManager.class);
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetManager);
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = new RecordAndReplayCurrentStatus();
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayCurrentStatus);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Context context = new ContextImpl(serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
CoreRegistry.setContext(context);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
entityManager = context.get(EngineEntityManager.class);
}

View file

@ -6,12 +6,14 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityPool;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.BeforeDeactivateComponent;
@ -20,8 +22,10 @@
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnAddedComponent;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnChangedComponent;
import org.terasology.engine.entitySystem.event.internal.EventSystem;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.PrefabData;
import org.terasology.engine.entitySystem.prefab.PrefabManager;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.network.NetworkSystem;
@ -33,6 +37,10 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import org.terasology.unittest.stubs.EntityRefComponent;
import org.terasology.unittest.stubs.IntegerComponent;
import org.terasology.unittest.stubs.StringComponent;
@ -60,14 +68,16 @@ public class PojoEntityManagerTest {
@BeforeAll
public static void setupClass() throws Exception {
context = new ContextImpl();
ServiceRegistry serviceRegistry = new ServiceRegistry();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
assetTypeManager.createAssetType(Prefab.class, PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = new RecordAndReplayCurrentStatus();
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayCurrentStatus);
context = new ContextImpl(serviceRegistry);
CoreRegistry.setContext(context);
}
@ -75,10 +85,18 @@ public static void setupClass() throws Exception {
public void setup() {
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
TypeRegistry typeRegistry = new ModuleTypeRegistry(context.get(ModuleManager.class).getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
entityManager = (PojoEntityManager) context.get(EntityManager.class);
entityManager.setPrefabManager(context.get(PrefabManager.class));
PrefabData protoPrefab = new PrefabData();
protoPrefab.addComponent(new StringComponent("Test"));

View file

@ -5,14 +5,17 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityPool;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.network.NetworkMode;
@ -23,6 +26,10 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ -37,15 +44,18 @@ public class PojoEntityPoolTest {
@BeforeAll
public static void setupClass() throws Exception {
context = new ContextImpl();
ServiceRegistry serviceRegistry = new ServiceRegistry();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
assetTypeManager.createAssetType(Prefab.class,
PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> new RecordAndReplayCurrentStatus());
context = new ContextImpl(serviceRegistry);
CoreRegistry.setContext(context);
}
@ -53,9 +63,14 @@ public static void setupClass() throws Exception {
public void setup() {
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context, serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
entityManager = (PojoEntityManager) context.get(EntityManager.class);
pool = new PojoEntityPool(entityManager);

View file

@ -4,7 +4,10 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.gestalt.assets.AssetType;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
@ -17,6 +20,9 @@
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefabManager;
import org.terasology.engine.entitySystem.prefab.internal.PrefabFormat;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import org.terasology.unittest.stubs.ListOfEnumsComponent;
import org.terasology.unittest.stubs.ListOfObjectComponent;
import org.terasology.unittest.stubs.MappedContainerComponent;
@ -47,13 +53,19 @@ public class PrefabTest {
@BeforeEach
public void setup() throws Exception {
ContextImpl context = new ContextImpl();
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
CoreRegistry.setContext(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(RecordAndReplayCurrentStatus::new);
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
ContextImpl context = new ContextImpl(serviceRegistry);
CoreRegistry.setContext(context);
serviceRegistry = new ServiceRegistry();
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
AssetType<Prefab, PrefabData> prefabDataAssetType = assetTypeManager.createAssetType(Prefab.class, PojoPrefab::new, "prefabs");
@ -62,12 +74,18 @@ public void setup() throws Exception {
PrefabFormat prefabFormat = new PrefabFormat(componentLibrary, typeHandlerLibrary);
assetTypeManager.getAssetFileDataProducer(prefabDataAssetType).addAssetFormat(prefabFormat);
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
CoreRegistry.setContext(context);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(typeHandlerLibrary,
context.get(EntitySystemLibrary.class), moduleManager.getEnvironment(),
context.get(EngineEntityManager.class));
prefabManager = new PojoPrefabManager(context);
}

View file

@ -11,6 +11,8 @@
import org.terasology.engine.core.subsystem.NonPlayerVisibleSubsystem;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import javax.inject.Inject;
import static com.google.common.truth.Truth.assertThat;
import static org.terasology.engine.testUtil.Correspondences.instanceOfExpected;
@ -38,11 +40,17 @@ void testConfigurationBySubsystemInitialisation(PlayerConfig config) {
* it's a convenient way to keep it close to the test code and still be something we can give
* to an annotation.
*/
static class MySubsystem extends NonPlayerVisibleSubsystem {
public static class MySubsystem extends NonPlayerVisibleSubsystem {
@Inject
protected PlayerConfig playerConfig;
@Inject
public MySubsystem() {
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
var config = rootContext.getValue(PlayerConfig.class);
config.playerName.set(PLAYER_NAME);
public void postInitialise(Context context) {
playerConfig.playerName.set(PLAYER_NAME);
}
}
}

View file

@ -6,7 +6,9 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.TerasologyTestingEnvironment;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
@ -16,12 +18,14 @@
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.metadata.EventLibrary;
import org.terasology.engine.network.NetworkComponent;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.testUtil.ModuleManagerFactory;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@ -41,14 +45,19 @@ public class NetworkOwnershipTest extends TerasologyTestingEnvironment {
public void setup() throws Exception {
super.setup();
ModuleManager moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(ServerConnectListManager.class).lifetime(Lifetime.Singleton).use(ServerConnectListManager.class);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context, serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class), context.get(EntitySystemLibrary.class), moduleManager.getEnvironment(), (EngineEntityManager) context.get(EntityManager.class));
EngineTime mockTime = mock(EngineTime.class);
networkSystem = new NetworkSystemImpl(mockTime, context);
networkSystem.setContext(context);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
entityManager = (PojoEntityManager) context.get(EntityManager.class);
context.put(ComponentSystemManager.class, new ComponentSystemManager(context));
entityManager.clear();
@ -61,7 +70,6 @@ public void setup() throws Exception {
networkSystem.mockHost();
networkSystem.connectToEntitySystem(entityManager, context.get(EventLibrary.class), mock(BlockEntityRegistry.class));
networkSystem.registerNetworkEntity(clientEntity);
context.put(ServerConnectListManager.class, new ServerConnectListManager(context));
}
private void connectClient() {

View file

@ -9,12 +9,14 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.reflections.Reflections;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.metadata.ComponentLibrary;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.persistence.serializers.ComponentSerializer;
@ -25,9 +27,13 @@
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.testUtil.ModuleManagerFactory;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.protobuf.EntityData;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import org.terasology.unittest.stubs.GetterSetterComponent;
import org.terasology.unittest.stubs.IntegerComponent;
import org.terasology.unittest.stubs.StringComponent;
@ -50,10 +56,9 @@ public static void setupClass() throws Exception {
@BeforeEach
public void setup() {
context = new ContextImpl();
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
context.put(ModuleManager.class, moduleManager);
CoreRegistry.setContext(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> new RecordAndReplayCurrentStatus());
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
Reflections reflections = new Reflections(getClass().getClassLoader());
TypeHandlerLibrary serializationLibrary = new TypeHandlerLibraryImpl(reflections);
@ -63,9 +68,18 @@ public void setup() {
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
AssetManager assetManager = mock(AssetManager.class);
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetManager);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
CoreRegistry.setContext(context);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
EngineEntityManager entityManager = context.get(EngineEntityManager.class);
entityManager.getComponentLibrary().register(new ResourceUrn("test", "gettersetter"), GetterSetterComponent.class);
entityManager.getComponentLibrary().register(new ResourceUrn("test", "string"), StringComponent.class);

View file

@ -6,6 +6,7 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
@ -15,9 +16,12 @@
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.EntityInfoComponent;
import org.terasology.engine.entitySystem.entity.internal.EntityScope;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.metadata.ComponentLibrary;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.PrefabData;
import org.terasology.engine.entitySystem.prefab.PrefabManager;
import org.terasology.engine.entitySystem.prefab.internal.PojoPrefab;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.network.NetworkSystem;
@ -31,8 +35,12 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManagerImpl;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.entitysystem.component.EmptyComponent;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.protobuf.EntityData;
import org.terasology.reflection.ModuleTypeRegistry;
import org.terasology.reflection.TypeRegistry;
import org.terasology.unittest.stubs.GetterSetterComponent;
import org.terasology.unittest.stubs.IntegerComponent;
import org.terasology.unittest.stubs.MappedTypeComponent;
@ -58,27 +66,38 @@ public class EntitySerializerTest {
@BeforeAll
public static void setupClass() throws Exception {
context = new ContextImpl();
CoreRegistry.setContext(context);
context.put(RecordAndReplayCurrentStatus.class, new RecordAndReplayCurrentStatus());
ServiceRegistry serviceRegistry = new ServiceRegistry();
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = new RecordAndReplayCurrentStatus();
serviceRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayCurrentStatus);
moduleManager = ModuleManagerFactory.create();
context.put(ModuleManager.class, moduleManager);
serviceRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
ModuleAwareAssetTypeManager assetTypeManager = new ModuleAwareAssetTypeManagerImpl();
assetTypeManager.createAssetType(Prefab.class, PojoPrefab::new, "prefabs");
assetTypeManager.switchEnvironment(moduleManager.getEnvironment());
context.put(AssetManager.class, assetTypeManager.getAssetManager());
serviceRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
context = new ContextImpl(serviceRegistry);
CoreRegistry.setContext(context);
}
@BeforeEach
public void setup() {
NetworkSystem networkSystem = mock(NetworkSystem.class);
when(networkSystem.getMode()).thenReturn(NetworkMode.NONE);
context.put(NetworkSystem.class, networkSystem);
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
ServiceRegistry serviceRegistry = new ServiceRegistry();
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(() -> networkSystem);
TypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
serviceRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
context = new ContextImpl(context, serviceRegistry);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class), context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class));
entityManager = context.get(EngineEntityManager.class);
((PojoEntityManager) entityManager).setPrefabManager(context.get(PrefabManager.class));
entityManager.getComponentLibrary().register(new ResourceUrn("test", "gettersetter"), GetterSetterComponent.class);
entityManager.getComponentLibrary().register(new ResourceUrn("test", "string"), StringComponent.class);
entityManager.getComponentLibrary().register(new ResourceUrn("test", "integer"), IntegerComponent.class);

View file

@ -18,13 +18,16 @@
import org.terasology.engine.config.Config;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.NonPlayerVisibleSubsystem;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.game.Game;
import org.terasology.engine.integrationenvironment.jupiter.IntegrationEnvironment;
import org.terasology.engine.integrationenvironment.jupiter.MTEExtension;
import org.terasology.engine.logic.location.LocationComponent;
@ -37,7 +40,6 @@
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.RecordAndReplaySerializer;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.registry.In;
import org.terasology.engine.world.block.Block;
import org.terasology.engine.world.block.BlockManager;
@ -45,11 +47,14 @@
import org.terasology.engine.world.chunks.ChunkProvider;
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.engine.world.chunks.internal.ChunkImpl;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.joml.geom.AABBfc;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.unittest.stubs.EntityRefComponent;
import org.terasology.unittest.stubs.StringComponent;
import javax.inject.Inject;
import java.nio.file.Path;
import java.util.List;
@ -175,12 +180,17 @@ public void testGlobalEntitiesStoredAndRestored(
esm.waitForCompletionOfPreviousSaveAndStartSaving();
esm.finishSavingAndShutdown();
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
EngineEntityManager newEntityManager = context.get(EngineEntityManager.class);
ServiceRegistry serviceRegistry = new ServiceRegistry();
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Context newContext = new ContextImpl(context, serviceRegistry);
EngineEntityManager newEntityManager = newContext.get(EngineEntityManager.class);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(newContext.get(TypeHandlerLibrary.class),
newContext.get(EntitySystemLibrary.class), moduleEnvironment, newEntityManager);
StorageManager newSM = new ReadWriteStorageManager(savePath, moduleEnvironment, newEntityManager, blockManager,
extraDataManager, esm.isStoreChunksInZips(), recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
extraDataManager, esm.isStoreChunksInZips(), recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus,
null, null, null, null);
newSM.loadGlobalStore();
List<EntityRef> entities = Lists.newArrayList(newEntityManager.getEntitiesWith(StringComponent.class));
@ -198,11 +208,17 @@ public void testReferenceRemainsValidOverStorageRestoral(
esm.waitForCompletionOfPreviousSaveAndStartSaving();
esm.finishSavingAndShutdown();
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
EngineEntityManager newEntityManager = context.get(EngineEntityManager.class);
ServiceRegistry serviceRegistry = new ServiceRegistry();
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Context newContext = new ContextImpl(context, serviceRegistry);
EngineEntityManager newEntityManager = newContext.get(EngineEntityManager.class);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(newContext.get(TypeHandlerLibrary.class),
newContext.get(EntitySystemLibrary.class), moduleEnvironment, newEntityManager);
StorageManager newSM = new ReadWriteStorageManager(savePath, moduleEnvironment, newEntityManager, blockManager,
extraDataManager, false, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
extraDataManager, false, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus,
null, null, null, null);
newSM.loadGlobalStore();
PlayerStore restored = newSM.loadPlayerStore(playerId);
@ -217,13 +233,13 @@ public void testGetUnstoredChunkReturnsNothing(StorageManager esm) {
@Test
public void testStoreAndRestoreChunkStore(
StorageManager esm, BlockManager blockManager, ExtraBlockDataManager extraDataManager) {
ReadWriteStorageManager esm, BlockManager blockManager, ExtraBlockDataManager extraDataManager) {
Chunk chunk = new ChunkImpl(CHUNK_POS, blockManager, extraDataManager);
chunk.setBlock(0, 0, 0, testBlock);
chunk.markReady();
ChunkProvider chunkProvider = mock(ChunkProvider.class);
when(chunkProvider.getAllChunks()).thenReturn(List.of(chunk));
CoreRegistry.put(ChunkProvider.class, chunkProvider);
esm.testSetChunkProvider(chunkProvider);
esm.waitForCompletionOfPreviousSaveAndStartSaving();
esm.finishSavingAndShutdown();
@ -245,17 +261,23 @@ public void testChunkSurvivesStorageSaveAndRestore(
chunk.markReady();
ChunkProvider chunkProvider = mock(ChunkProvider.class);
when(chunkProvider.getAllChunks()).thenReturn(List.of(chunk));
CoreRegistry.put(ChunkProvider.class, chunkProvider);
esm.testSetChunkProvider(chunkProvider);
esm.waitForCompletionOfPreviousSaveAndStartSaving();
esm.finishSavingAndShutdown();
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
EngineEntityManager newEntityManager = context.get(EngineEntityManager.class);
ServiceRegistry serviceRegistry = new ServiceRegistry();
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Context newContext = new ContextImpl(context, serviceRegistry);
EngineEntityManager newEntityManager = newContext.get(EngineEntityManager.class);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(newContext.get(TypeHandlerLibrary.class),
newContext.get(EntitySystemLibrary.class), moduleEnvironment, newEntityManager);
StorageManager newSM = new ReadWriteStorageManager(savePath, moduleEnvironment, newEntityManager, blockManager,
extraDataManager, esm.isStoreChunksInZips(), recordAndReplaySerializer, recordAndReplayUtils,
recordAndReplayCurrentStatus);
recordAndReplayCurrentStatus, () -> chunkProvider, () -> newContext.get(NetworkSystem.class), newContext.get(Time.class),
newContext.get(Game.class));
newSM.loadGlobalStore();
ChunkStore restored = newSM.loadChunkStore(CHUNK_POS);
@ -275,7 +297,7 @@ public void testEntitySurvivesStorageInChunkStore(
chunk.markReady();
ChunkProvider chunkProvider = mock(ChunkProvider.class);
when(chunkProvider.getAllChunks()).thenReturn(List.of(chunk));
CoreRegistry.put(ChunkProvider.class, chunkProvider);
esm.testSetChunkProvider(chunkProvider);
EntityRef entity = entityManager.create();
long id = entity.getId();
LocationComponent locationComponent = new LocationComponent();
@ -289,11 +311,18 @@ public void testEntitySurvivesStorageInChunkStore(
esm.waitForCompletionOfPreviousSaveAndStartSaving();
esm.finishSavingAndShutdown();
EntitySystemSetupUtil.addReflectionBasedLibraries(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
EngineEntityManager newEntityManager = context.get(EngineEntityManager.class);
ServiceRegistry serviceRegistry = new ServiceRegistry();
EntitySystemSetupUtil.addReflectionBasedLibraries(serviceRegistry);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(serviceRegistry);
Context newContext = new ContextImpl(context, serviceRegistry);
EngineEntityManager newEntityManager = newContext.get(EngineEntityManager.class);
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(newContext.get(TypeHandlerLibrary.class),
newContext.get(EntitySystemLibrary.class), moduleEnvironment, newEntityManager);
StorageManager newSM = new ReadWriteStorageManager(savePath, moduleEnvironment, newEntityManager, blockManager,
extraDataManager, esm.isStoreChunksInZips(), recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
extraDataManager, esm.isStoreChunksInZips(), recordAndReplaySerializer, recordAndReplayUtils,
recordAndReplayCurrentStatus, () -> chunkProvider, () -> newContext.get(NetworkSystem.class), newContext.get(Time.class),
newContext.get(Game.class));
newSM.loadGlobalStore();
ChunkStore restored = newSM.loadChunkStore(CHUNK_POS);
@ -313,9 +342,13 @@ public void testCanSavePlayerWithoutUnloading(StorageManager esm) {
}
static class EnableWritingSaveGames extends NonPlayerVisibleSubsystem {
@Inject
public EnableWritingSaveGames() {
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.getValue(SystemConfig.class).writeSaveGamesEnabled.set(true);
public void postInitialise(Context context) {
context.getValue(SystemConfig.class).writeSaveGamesEnabled.set(true);
}
}
}

View file

@ -9,6 +9,7 @@
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.terasology.engine.TerasologyTestingEnvironment;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.core.subsystem.headless.renderer.HeadlessCanvasRenderer;
import org.terasology.engine.i18n.TranslationSystem;
import org.terasology.engine.i18n.TranslationSystemImpl;
@ -18,6 +19,7 @@
import org.terasology.engine.rendering.nui.editor.utils.NUIEditorNodeUtils;
import org.terasology.engine.rendering.nui.internal.NUIManagerInternal;
import org.terasology.engine.rendering.nui.internal.TerasologyCanvasRenderer;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.nui.canvas.CanvasRenderer;
import org.terasology.nui.layouts.RowLayout;
import org.terasology.nui.layouts.RowLayoutHint;
@ -32,6 +34,7 @@
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@ -43,11 +46,12 @@ public class ContextMenuUtilsTest extends TerasologyTestingEnvironment {
@BeforeAll
public static void setupInput() {
context.put(InputSystem.class, new InputSystem());
context.put(TranslationSystem.class, new TranslationSystemImpl(context));
context.put(TranslationSystem.class, new TranslationSystemImpl(context.get(SystemConfig.class), context.get(AssetManager.class)));
context.put(CanvasRenderer.class, new HeadlessCanvasRenderer());
context.put(NUIManager.class, new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context));
File file = new File(ContextMenuUtilsTest.class.getClassLoader().getResource("contextMenuBuilderInput.ui").getFile());
File file = new File(URLDecoder.decode(
ContextMenuUtilsTest.class.getClassLoader().getResource("contextMenuBuilderInput.ui").getFile(), Charsets.UTF_8));
String content = null;
try {
content = Files.asCharSource(file, Charsets.UTF_8).read();

View file

@ -20,6 +20,8 @@
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -63,7 +65,8 @@ public static void init()
Files.createDirectories(TMP_SAVES_FOLDER_PATH);
Files.createDirectories(TMP_RECORDS_FOLDER_PATH);
final File file = new File(GameProviderTest.class.getClassLoader().getResource(GAME_MANIFEST_JSON).getFile());
final File file = new File(URLDecoder.decode(
GameProviderTest.class.getClassLoader().getResource(GAME_MANIFEST_JSON).getFile(), Charset.defaultCharset()));
try {
manifestExample = com.google.common.io.Files.asCharSource(file, Charsets.UTF_8).read();
} catch (IOException e) {

View file

@ -11,6 +11,8 @@
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
@ -18,7 +20,8 @@
public class JsonTreeConverterTest {
@Test
public void testTreeAdapter() {
File file = new File(getClass().getClassLoader().getResource("jsonTreeConverterInput.json").getFile());
File file = new File(URLDecoder.decode(
getClass().getClassLoader().getResource("jsonTreeConverterInput.json").getFile(), Charset.defaultCharset()));
String content = null;
try {
content = Files.toString(file, Charsets.UTF_8);

View file

@ -27,7 +27,7 @@ void provideContext() throws Exception {
@Test
void hasUnittestWorldGenerator() {
manager = new WorldGeneratorManager(context);
manager = new WorldGeneratorManager(context.get(ModuleManager.class));
assertThat(manager.getWorldGenerators())
.comparingElementsUsing(
Correspondence.transforming(WorldGeneratorInfo::getUri, "info"))

View file

@ -11,7 +11,6 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.context.internal.MockContext;
import org.terasology.engine.registry.CoreRegistry;
import java.util.ArrayList;
@ -27,7 +26,7 @@ public IntMathTest() {
@BeforeAll
public static void setUpClass() throws Exception {
Config config = new Config(new MockContext());
Config config = new Config();
CoreRegistry.setContext(new ContextImpl());
CoreRegistry.put(Config.class, config);
}

View file

@ -12,7 +12,6 @@
import com.google.gson.JsonParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.core.TerasologyConstants;
@ -54,10 +53,7 @@ public final class Config {
private RootConfig config;
private Context context;
public Config(Context context) {
this.context = context;
public Config() {
}
public PermissionConfig getPermission() {

View file

@ -2,8 +2,6 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.config;
import org.terasology.engine.context.internal.MockContext;
public class InputConfig {
private ControllerConfig controllers = new ControllerConfig();
@ -23,7 +21,7 @@ public void setMouseSensitivity(float mouseSensitivity) {
}
public void reset() {
Config defaultConfig = new Config(new MockContext());
Config defaultConfig = new Config();
defaultConfig.loadDefaults();
InputConfig defaultInputConfig = defaultConfig.getInput();

View file

@ -5,12 +5,13 @@
import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.registry.InjectionHelper;
import org.terasology.engine.utilities.ReflectionUtil;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.persistence.serializers.Serializer;
import org.terasology.reflection.TypeInfo;
@ -19,6 +20,7 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
@ -41,19 +43,40 @@ public AutoConfigManager(Serializer<?> serializer) {
this.serializer = serializer;
}
public void loadConfigsIn(Context context) {
ModuleEnvironment environment = context.get(ModuleManager.class).getEnvironment();
@SuppressWarnings("unchecked")
public void loadConfigsIn(ModuleEnvironment environment, ServiceRegistry serviceRegistry) {
for (Class<? extends AutoConfig> configClass : environment.getSubtypesOf(AutoConfig.class)) {
if (context.get(configClass) != null) {
// We've already initialized this config before
continue;
}
SimpleUri configId = verifyNotNull(ReflectionUtil.getFullyQualifiedSimpleUriFor(configClass, environment),
"Could not find ID for %s", configClass.getSimpleName()
);
loadConfig(configClass, configId, context);
serviceRegistry.with((Class) configClass).lifetime(Lifetime.Singleton).use(() -> {
try {
AutoConfig config = configClass.getDeclaredConstructor().newInstance();
config.setId(configId);
loadedConfigs.add(config);
Path configPath = getConfigPath(config.getId());
if (!Files.exists(configPath)) {
return config;
}
try (InputStream inputStream = Files.newInputStream(configPath, StandardOpenOption.READ)) {
AutoConfig loadedConfig = serializer.deserialize(TypeInfo.of(configClass), inputStream).get();
Set<Field> fields = AutoConfig.getSettingFieldsIn(configClass);
for (Field field : fields) {
try {
Object value = ((Setting) field.get(loadedConfig)).get();
((Setting) field.get(config)).set(value);
} catch (IllegalAccessException e) {
// ignore `AutoConfig.getSettingFieldIn` returns PUBLIC fields
}
}
} catch (Exception e) {
logger.error("Error while loading config {} from disk", config.getId(), e); //NOPMD
}
return configClass.cast(config);
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException ignore) {
return null;
}
});
}
}

View file

@ -4,7 +4,13 @@
import com.google.common.base.MoreObjects;
import com.google.common.collect.Maps;
import org.terasology.context.Lifetime;
import org.terasology.context.exception.BeanNotFoundException;
import org.terasology.engine.context.Context;
import org.terasology.gestalt.di.BeanContext;
import org.terasology.gestalt.di.DefaultBeanContext;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.di.exceptions.BeanResolutionException;
import java.util.Map;
@ -12,10 +18,52 @@
* Implements the {@link Context} interface.
*/
public class ContextImpl implements Context {
private final DefaultBeanContext beanContext;
private final Context parent;
private final Map<Class<?>, Object> map = Maps.newConcurrentMap();
public ContextImpl(Context parent, ServiceRegistry... registries) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
for (ServiceRegistry registry : registries) {
thisServiceRegistry.includeRegistry(registry);
}
this.beanContext = new DefaultBeanContext(
parent instanceof ContextImpl ? ((ContextImpl) parent).beanContext : null, thisServiceRegistry);
this.parent = parent;
}
public ContextImpl(ContextImpl parent, ServiceRegistry... registries) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
for (ServiceRegistry registry : registries) {
thisServiceRegistry.includeRegistry(registry);
}
this.beanContext = new DefaultBeanContext(parent.beanContext, thisServiceRegistry);
this.parent = parent;
}
public ContextImpl(Context parent, BeanContext parentBeanContext) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
this.beanContext = new DefaultBeanContext(parentBeanContext, thisServiceRegistry);
this.parent = parent;
}
public ContextImpl(ServiceRegistry... registries) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
for (ServiceRegistry registry : registries) {
thisServiceRegistry.includeRegistry(registry);
}
this.beanContext = new DefaultBeanContext(thisServiceRegistry);
this.parent = null;
}
/**
*
@ -23,10 +71,31 @@ public class ContextImpl implements Context {
* requested object.
*/
public ContextImpl(Context parent) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
this.beanContext = new DefaultBeanContext(thisServiceRegistry);
this.parent = parent;
}
/**
*
* @param parent can be null. If not null it will be used as a fallback if this context does not contain a
* requested object.
*/
public ContextImpl(ContextImpl parent) {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
this.beanContext = new DefaultBeanContext(parent.beanContext, thisServiceRegistry);
this.parent = parent;
}
public ContextImpl() {
ServiceRegistry thisServiceRegistry = new ServiceRegistry();
thisServiceRegistry.with(Context.class).lifetime(Lifetime.Singleton).use(() -> this);
thisServiceRegistry.with(ContextImpl.class).lifetime(Lifetime.Singleton).use(() -> this);
this.beanContext = new DefaultBeanContext(thisServiceRegistry);
this.parent = null;
}
@ -39,10 +108,16 @@ public <T> T get(Class<T> type) {
if (result != null) {
return result;
}
if (parent != null) {
return parent.get(type);
try {
return beanContext.getBean(type);
} catch (BeanResolutionException | BeanNotFoundException ignore) {
// Ignored - fallback to parent if present.
if (parent != null) {
return parent.get(type);
} else {
return null;
}
}
return null;
}
@Override
@ -50,10 +125,18 @@ public <T, U extends T> void put(Class<T> type, U object) {
map.put(type, object);
}
public <T> T inject(T instance) {
return beanContext.inject(instance);
}
public boolean isDirectDescendantOf(Context other) {
return parent == other;
}
public DefaultBeanContext getBeanContext() {
return beanContext;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)

View file

@ -0,0 +1,34 @@
// Copyright 2024 The Terasology Foundation
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.context.internal;
import org.terasology.engine.context.Context;
import org.terasology.gestalt.di.ServiceRegistry;
/**
* The intent of this class is purely to act as a forwarder to the underlying {@link org.terasology.gestalt.di.BeanContext}.
*/
public class ImmutableContextImpl extends ContextImpl {
public ImmutableContextImpl(Context parent, ServiceRegistry... registries) {
super(parent, registries);
}
public ImmutableContextImpl(ContextImpl parent, ServiceRegistry... registries) {
super(parent, registries);
}
public ImmutableContextImpl(ServiceRegistry... registries) {
super(registries);
}
public ImmutableContextImpl(Context parent) {
super(parent);
}
@Override
public <T, U extends T> void put(Class<T> type, U object) {
throw new UnsupportedOperationException("The current context is immutable.");
}
}

View file

@ -24,6 +24,7 @@
import org.terasology.context.annotation.API;
import org.terasology.gestalt.naming.Name;
import javax.inject.Inject;
import java.util.List;
import java.util.Map;
@ -57,6 +58,7 @@ public class ComponentSystemManager {
private boolean initialised;
@Inject
public ComponentSystemManager(Context context) {
this.context = context;
}

View file

@ -5,6 +5,7 @@
import org.terasology.engine.context.Context;
import org.terasology.engine.core.modes.GameState;
import org.terasology.gestalt.di.ServiceRegistry;
/**
* The game engine is the core of Terasology. It maintains a stack of game states, that drive the behaviour of
@ -81,7 +82,23 @@ public interface GameEngine {
/**
* Creates a context that provides read access to the objects of the engine context and can
* be populated with it's own private objects.
* be populated with its own private objects.
*/
Context createChildContext();
/**
* Creates a context that provides read access to the objects of the engine context and can
* be populated with its own private objects.
*
* @param serviceRegistry a registry of services to populate the context with.
*/
Context createChildContext(ServiceRegistry serviceRegistry);
/**
* Creates an immutable context that provides read access to the objects of the engine context and can
* be pre-populated with its own private objects (derived from those provided).
*
* @param serviceRegistry a registry of services to populate the context with.
*/
Context createImmutableChildContext(ServiceRegistry serviceRegistry);
}

View file

@ -7,11 +7,16 @@
import com.google.common.base.Stopwatch;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.flexible.AutoConfigManager;
import org.terasology.engine.config.flexible.AutoConfigTypeHandlerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.context.internal.ImmutableContextImpl;
import org.terasology.engine.core.bootstrap.EnvironmentSwitchHandler;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.module.ExternalApiWhitelist;
@ -37,11 +42,16 @@
import org.terasology.engine.monitoring.PerformanceMonitor;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.persistence.typeHandling.TypeHandlerLibraryImpl;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedData;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataReader;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataSerializer;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataWriter;
import org.terasology.engine.recording.CharacterStateEventPositionMap;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.registry.InjectionHelper;
import org.terasology.engine.rendering.gltf.ByteBufferAsset;
import org.terasology.engine.version.TerasologyVersion;
import org.terasology.engine.world.block.loader.BlockFamilyDefinition;
@ -56,9 +66,11 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.assets.module.autoreload.AutoReloadAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.nui.UIWidget;
import org.terasology.nui.asset.UIElement;
import org.terasology.nui.skin.UISkinAsset;
import org.terasology.persistence.serializers.Serializer;
import org.terasology.persistence.typeHandling.TypeHandler;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.ModuleTypeRegistry;
@ -127,14 +139,22 @@ public class TerasologyEngine implements GameEngine {
private volatile boolean running;
private TimeSubsystem timeSubsystem;
private ConfigurationSubsystem configurationSubsystem;
private Deque<EngineSubsystem> allSubsystems;
private ModuleAwareAssetTypeManager assetTypeManager;
private boolean initialisedAlready;
/**
* Contains objects that live for the duration of this engine.
* Contains objects that live for the duration of this application.
*/
private Context rootContext;
private ImmutableContextImpl rootContext;
/**
* Contains objects that live for the duration of this game instance.
*/
private ContextImpl gameContext;
private ServiceRegistry rootContextRegistry;
private ServiceRegistry gameContextRegistry;
/**
* This constructor initializes the engine by initializing its systems, subsystems and managers. It also verifies
@ -148,19 +168,20 @@ public TerasologyEngine(TimeSubsystem timeSubsystem, Collection<EngineSubsystem>
PathManager.getInstance();
Bullet.init(true, false);
this.rootContext = new ContextImpl();
rootContext.put(GameEngine.class, this);
this.rootContextRegistry = new ServiceRegistry();
rootContextRegistry.with(GameEngine.class).lifetime(Lifetime.Singleton).use(() -> this);
this.gameContextRegistry = new ServiceRegistry();
this.timeSubsystem = timeSubsystem;
//Record and Replay classes
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = new RecordAndReplayCurrentStatus();
rootContext.put(RecordAndReplayCurrentStatus.class, recordAndReplayCurrentStatus);
rootContextRegistry.with(RecordAndReplayCurrentStatus.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayCurrentStatus);
RecordAndReplayUtils recordAndReplayUtils = new RecordAndReplayUtils();
rootContext.put(RecordAndReplayUtils.class, recordAndReplayUtils);
rootContextRegistry.with(RecordAndReplayUtils.class).lifetime(Lifetime.Singleton).use(() -> recordAndReplayUtils);
CharacterStateEventPositionMap characterStateEventPositionMap = new CharacterStateEventPositionMap();
rootContext.put(CharacterStateEventPositionMap.class, characterStateEventPositionMap);
rootContextRegistry.with(CharacterStateEventPositionMap.class).lifetime(Lifetime.Singleton).use(() -> characterStateEventPositionMap);
DirectionAndOriginPosRecorderList directionAndOriginPosRecorderList = new DirectionAndOriginPosRecorderList();
rootContext.put(DirectionAndOriginPosRecorderList.class, directionAndOriginPosRecorderList);
rootContextRegistry.with(DirectionAndOriginPosRecorderList.class).lifetime(Lifetime.Singleton).use(() -> directionAndOriginPosRecorderList);
/*
* We can't load the engine without core registry yet.
* e.g. the statically created MaterialLoader needs the CoreRegistry to get the AssetManager.
@ -170,7 +191,9 @@ public TerasologyEngine(TimeSubsystem timeSubsystem, Collection<EngineSubsystem>
CoreRegistry.setContext(rootContext);
this.allSubsystems = Queues.newArrayDeque();
this.allSubsystems.add(new ConfigurationSubsystem());
configurationSubsystem = new ConfigurationSubsystem();
this.allSubsystems.add(new I18nSubsystem());
this.allSubsystems.add(configurationSubsystem);
this.allSubsystems.add(timeSubsystem);
this.allSubsystems.addAll(subsystems);
this.allSubsystems.add(new MonitoringSubsystem());
@ -179,7 +202,6 @@ public TerasologyEngine(TimeSubsystem timeSubsystem, Collection<EngineSubsystem>
this.allSubsystems.add(new NetworkSubsystem());
this.allSubsystems.add(new WorldGenerationSubsystem());
this.allSubsystems.add(new GameSubsystem());
this.allSubsystems.add(new I18nSubsystem());
this.allSubsystems.add(new TelemetrySubSystem());
for (EngineSubsystem subsystem : allSubsystems) {
@ -217,6 +239,9 @@ public void initialize() {
logger.info("Initializing Terasology...");
logEnvironmentInfo();
EnvironmentSwitchHandler environmentSwitcher = new EnvironmentSwitchHandler();
rootContextRegistry.with(EnvironmentSwitchHandler.class).lifetime(Lifetime.Singleton).use(() -> environmentSwitcher);
// TODO: Need to get everything thread safe and get rid of the concept of "GameThread" as much as
// possible.
GameThread.setToCurrentThread();
@ -225,15 +250,32 @@ public void initialize() {
initManagers();
// Register the context with the context before creating the context.
// If this seems confusing, it is. We are taking advantage of the fact that context registrations use a callback that
// is invoked when a class is first requested,
// so that the requested instance does not need to exist at the time of registration.
rootContextRegistry.with(Context.class).use(() -> rootContext);
rootContextRegistry.with(ContextImpl.class).use(() -> rootContext);
rootContextRegistry.with(GameEngine.class).lifetime(Lifetime.Singleton).use(() -> this);
rootContext = new ImmutableContextImpl(rootContextRegistry);
// TODO: Remove CoreRegistry altogether.
CoreRegistry.setContext(rootContext);
initSubsystems();
changeStatus(TerasologyEngineStatus.INITIALIZING_ASSET_MANAGEMENT);
initAssets();
EnvironmentSwitchHandler environmentSwitcher = new EnvironmentSwitchHandler();
rootContext.put(EnvironmentSwitchHandler.class, environmentSwitcher);
environmentSwitcher.handleSwitchToGameEnvironment(rootContext);
environmentSwitcher.handleSwitchToGameEnvironment(rootContext, gameContextRegistry);
// Register the context with the context before creating the context.
// If this seems confusing, it is. We are taking advantage of the fact that context registrations use a callback that
// is invoked when a class is first requested,
// so that the requested instance does not need to exist at the time of registration.
gameContextRegistry.with(Context.class).use(() -> gameContext);
gameContextRegistry.with(ContextImpl.class).use(() -> gameContext);
gameContext = new ContextImpl(rootContext, gameContextRegistry);
// TODO: Remove CoreRegistry altogether.
CoreRegistry.setContext(gameContext);
postInitSubsystems();
@ -289,7 +331,7 @@ private void preInitSubsystems() {
changeStatus(TerasologyEngineStatus.PREPARING_SUBSYSTEMS);
for (EngineSubsystem subsystem : getSubsystems()) {
changeStatus(() -> "Pre-initialising " + subsystem.getName() + " subsystem");
subsystem.preInitialise(rootContext);
subsystem.preInitialise(rootContextRegistry);
}
}
@ -297,7 +339,8 @@ private void initSubsystems() {
changeStatus(TerasologyEngineStatus.INITIALIZING_SUBSYSTEMS);
for (EngineSubsystem subsystem : getSubsystems()) {
changeStatus(() -> "Initialising " + subsystem.getName() + " subsystem");
subsystem.initialise(this, rootContext);
rootContext.inject(subsystem);
subsystem.initialise(this, gameContextRegistry);
}
}
@ -307,7 +350,8 @@ private void initSubsystems() {
private void postInitSubsystems() {
for (EngineSubsystem subsystem : getSubsystems()) {
changeStatus(() -> "Post-Initialising " + subsystem.getName() + " subsystem");
subsystem.postInitialise(rootContext);
gameContext.inject(subsystem);
subsystem.postInitialise(gameContext);
}
}
@ -318,7 +362,7 @@ private void postInitSubsystems() {
* @throws IllegalStateException Details the required system that has not been registered.
*/
private void verifyRequiredSystemIsRegistered(Class<?> clazz) {
if (rootContext.get(clazz) == null) {
if (gameContext.get(clazz) == null) {
throw new IllegalStateException(clazz.getSimpleName() + " not registered as a core system.");
}
}
@ -330,28 +374,40 @@ private void initManagers() {
ExternalApiWhitelist.CLASSES.stream().map(Class::getName).collect(Collectors.toSet());
TypeRegistry.WHITELISTED_PACKAGES = ExternalApiWhitelist.PACKAGES;
ModuleManager moduleManager = new ModuleManager(rootContext.get(Config.class),
classesOnClasspathsToAddToEngine);
ModuleManager moduleManager = new ModuleManager(configurationSubsystem.getConfig(), classesOnClasspathsToAddToEngine);
ModuleTypeRegistry typeRegistry = new ModuleTypeRegistry(moduleManager.getEnvironment());
rootContext.put(ModuleTypeRegistry.class, typeRegistry);
rootContext.put(TypeRegistry.class, typeRegistry);
rootContext.put(ModuleManager.class, moduleManager);
rootContextRegistry.with(ModuleTypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
rootContextRegistry.with(TypeRegistry.class).lifetime(Lifetime.Singleton).use(() -> typeRegistry);
rootContextRegistry.with(ModuleManager.class).lifetime(Lifetime.Singleton).use(() -> moduleManager);
changeStatus(TerasologyEngineStatus.INITIALIZING_LOWLEVEL_OBJECT_MANIPULATION);
ReflectFactory reflectFactory = new ReflectionReflectFactory();
rootContext.put(ReflectFactory.class, reflectFactory);
rootContextRegistry.with(ReflectFactory.class).lifetime(Lifetime.Singleton).use(() -> reflectFactory);
CopyStrategyLibrary copyStrategyLibrary = new CopyStrategyLibrary(reflectFactory);
rootContext.put(CopyStrategyLibrary.class, copyStrategyLibrary);
rootContextRegistry.with(CopyStrategyLibrary.class).lifetime(Lifetime.Singleton).use(() -> copyStrategyLibrary);
rootContext.put(TypeHandlerLibrary.class, TypeHandlerLibraryImpl.forModuleEnvironment(moduleManager,
typeRegistry));
TypeHandlerLibrary typeHandlerLibrary = TypeHandlerLibraryImpl.forModuleEnvironment(moduleManager, typeRegistry);
rootContextRegistry.with(TypeHandlerLibrary.class).lifetime(Lifetime.Singleton).use(() -> typeHandlerLibrary);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Serializer<GsonPersistedData> serializer = new Serializer<>(
typeHandlerLibrary,
new GsonPersistedDataSerializer(),
new GsonPersistedDataWriter(gson),
new GsonPersistedDataReader(gson)
);
AutoConfigManager autoConfigManager = new AutoConfigManager(serializer);
typeHandlerLibrary.addTypeHandlerFactory(new AutoConfigTypeHandlerFactory(typeHandlerLibrary));
rootContextRegistry.with(AutoConfigManager.class).lifetime(Lifetime.Singleton).use(() -> autoConfigManager);
autoConfigManager.loadConfigsIn(moduleManager.getEnvironment(), rootContextRegistry);
changeStatus(TerasologyEngineStatus.INITIALIZING_ASSET_TYPES);
assetTypeManager = new AutoReloadAssetTypeManager();
rootContext.put(ModuleAwareAssetTypeManager.class, assetTypeManager);
rootContext.put(AssetManager.class, assetTypeManager.getAssetManager());
rootContextRegistry.with(ModuleAwareAssetTypeManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager);
rootContextRegistry.with(AssetManager.class).lifetime(Lifetime.Singleton).use(() -> assetTypeManager.getAssetManager());
}
private void initAssets() {
@ -423,7 +479,6 @@ public synchronized void initializeRun(GameState initialState) {
initialize();
try {
rootContext.put(GameEngine.class, this);
changeState(initialState);
} catch (Throwable e) {
logger.error("Uncaught exception, attempting clean game shutdown", e);
@ -504,7 +559,7 @@ public boolean tick() {
Iterator<Float> updateCycles = timeSubsystem.getEngineTime().tick();
CoreRegistry.setContext(currentState.getContext());
rootContext.get(NetworkSystem.class).setContext(currentState.getContext());
gameContext.get(NetworkSystem.class).setContext(currentState.getContext());
for (EngineSubsystem subsystem : allSubsystems) {
try (Activity ignored = PerformanceMonitor.startActivity(subsystem.getName() + " PreUpdate")) {
@ -600,12 +655,22 @@ private void switchState(GameState newState) {
if (currentState != null) {
currentState.dispose();
}
CoreRegistry.setContext(newState.getContext());
currentState = newState;
LoggingContext.setGameState(newState);
newState.init(this);
Context stateContext = newState.getContext();
CoreRegistry.setContext(newState.getContext());
for (EngineSubsystem subsystem : getSubsystems()) {
if (stateContext != null) {
((ContextImpl) stateContext).inject(subsystem);
InjectionHelper.inject(subsystem, stateContext);
}
}
stateChangeSubscribers.forEach(StateChangeSubscriber::onStateChange);
InputSystem inputSystem = rootContext.get(InputSystem.class);
InputSystem inputSystem = gameContext.get(InputSystem.class);
if (inputSystem != null) {
inputSystem.drainQueues();
}
@ -642,7 +707,17 @@ public void unsubscribeToStateChange(StateChangeSubscriber subscriber) {
@Override
public Context createChildContext() {
return new ContextImpl(rootContext);
return new ContextImpl(gameContext);
}
@Override
public Context createChildContext(ServiceRegistry serviceRegistry) {
return new ContextImpl(gameContext, serviceRegistry);
}
@Override
public Context createImmutableChildContext(ServiceRegistry serviceRegistry) {
return new ImmutableContextImpl(gameContext, serviceRegistry);
}
/**

View file

@ -3,7 +3,6 @@
package org.terasology.engine.core.bootstrap;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.gestalt.naming.Name;
@ -14,10 +13,10 @@ public class ClassMetaLibraryImpl implements ClassMetaLibrary {
private final ModuleManager moduleManager;
/**
* @param context the context that provides a {@link ModuleManager}.
* @param moduleManager the {@link ModuleManager} to use.
*/
public ClassMetaLibraryImpl(Context context) {
moduleManager = context.get(ModuleManager.class);
public ClassMetaLibraryImpl(ModuleManager moduleManager) {
this.moduleManager = moduleManager;
}
@Override

View file

@ -3,10 +3,9 @@
package org.terasology.engine.core.bootstrap;
import org.terasology.context.Lifetime;
import org.terasology.engine.audio.events.PlaySoundEvent;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
@ -26,28 +25,27 @@
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.persistence.typeHandling.TypeHandlerLibraryImpl;
import org.terasology.engine.persistence.typeHandling.extensionTypes.EntityRefTypeHandler;
import org.terasology.engine.recording.CharacterStateEventPositionMap;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.EventCatcher;
import org.terasology.engine.recording.EventSystemReplayImpl;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.RecordAndReplaySerializer;
import org.terasology.engine.recording.RecordAndReplayStatus;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.recording.RecordedEventStore;
import org.terasology.engine.recording.RecordingClasses;
import org.terasology.engine.recording.RecordingEventSystemDecorator;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.entitysystem.event.Event;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.naming.Name;
import org.terasology.nui.properties.OneOfProviderFactory;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.TypeRegistry;
import org.terasology.reflection.copy.CopyStrategyLibrary;
import org.terasology.reflection.reflect.ReflectFactory;
import org.terasology.reflection.reflect.ReflectionReflectFactory;
import javax.inject.Inject;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
@ -63,23 +61,45 @@ private EntitySystemSetupUtil() {
// static utility class, no instance needed
}
public static void addReflectionBasedLibraries(Context context) {
public static void addReflectionBasedLibraries(ServiceRegistry serviceRegistry) {
ReflectionReflectFactory reflectFactory = new ReflectionReflectFactory();
context.put(ReflectFactory.class, reflectFactory);
CopyStrategyLibrary copyStrategyLibrary = new CopyStrategyLibrary(reflectFactory);
context.put(CopyStrategyLibrary.class, copyStrategyLibrary);
ModuleManager moduleManager = context.get(ModuleManager.class);
TypeRegistry typeRegistry = context.get(TypeRegistry.class);
TypeHandlerLibrary typeHandlerLibrary = TypeHandlerLibraryImpl.forModuleEnvironment(moduleManager, typeRegistry);
context.put(TypeHandlerLibrary.class, typeHandlerLibrary);
EntitySystemLibrary library = new EntitySystemLibrary(context, typeHandlerLibrary);
context.put(EntitySystemLibrary.class, library);
context.put(ComponentLibrary.class, library.getComponentLibrary());
context.put(EventLibrary.class, library.getEventLibrary());
serviceRegistry.with(ReflectFactory.class).lifetime(Lifetime.Singleton).use(() -> reflectFactory);
serviceRegistry.with(CopyStrategyLibrary.class).lifetime(Lifetime.Singleton).use(CopyStrategyLibrary.class);
serviceRegistry.with(TypeHandlerLibrary.class).lifetime(Lifetime.Singleton).use(TypeHandlerLibraryImpl.class);
serviceRegistry.with(ComponentLibrary.class).lifetime(Lifetime.Singleton).use(ComponentLibrary.class);
serviceRegistry.with(EventLibrary.class).lifetime(Lifetime.Singleton).use(EventLibrary.class);
serviceRegistry.with(EntitySystemLibrary.class).lifetime(Lifetime.Singleton).use(EntitySystemLibrary.class);
}
public static void addEntityManagementRelatedClasses(ServiceRegistry serviceRegistry) {
// Prefab Manager
serviceRegistry.with(PrefabManager.class).lifetime(Lifetime.Singleton).use(PojoPrefabManager.class);
// Entity Manager
serviceRegistry.with(PojoEntityManager.class).lifetime(Lifetime.Singleton);
//Record and Replay
RecordedEventStore recordedEventStore = new RecordedEventStore();
serviceRegistry.with(RecordedEventStore.class).lifetime(Lifetime.Singleton).use(() -> recordedEventStore);
serviceRegistry.with(RecordAndReplaySerializer.class).lifetime(Lifetime.Singleton).use(RecordAndReplaySerializer.class);
// Event System
// TODO: Provide RecordAndReplayCurrentStatus
registerEventSystem(new RecordAndReplayCurrentStatus(), serviceRegistry);
// TODO: Review - NodeClassLibrary related to the UI for behaviours. Should not be here and probably not even in the CoreRegistry
OneOfProviderFactory oneOfProviderFactory = new OneOfProviderFactory();
serviceRegistry.with(OneOfProviderFactory.class).lifetime(Lifetime.Singleton).use(() -> oneOfProviderFactory);
}
public static void configureEntityManagementRelatedClasses(TypeHandlerLibrary typeHandlerLibrary,
EntitySystemLibrary entitySystemLibrary,
ModuleEnvironment environment, EngineEntityManager entityManager) {
// Standard serialization library
typeHandlerLibrary.addTypeHandler(EntityRef.class, new EntityRefTypeHandler(entityManager));
registerComponents(entitySystemLibrary.getComponentLibrary(), environment);
registerEvents(entityManager.getEventSystem(), environment);
}
/**
* Objects for the following classes must be available in the context:
@ -100,75 +120,24 @@ public static void addReflectionBasedLibraries(Context context) {
* <li>{@link EventSystem}</li>
* </ul>
*/
public static void addEntityManagementRelatedClasses(Context context) {
ModuleManager moduleManager = context.get(ModuleManager.class);
ModuleEnvironment environment = moduleManager.getEnvironment();
NetworkSystem networkSystem = context.get(NetworkSystem.class);
// Entity Manager
PojoEntityManager entityManager = new PojoEntityManager();
context.put(EntityManager.class, entityManager);
context.put(EngineEntityManager.class, entityManager);
// Standard serialization library
TypeHandlerLibrary typeHandlerLibrary = context.get(TypeHandlerLibrary.class);
typeHandlerLibrary.addTypeHandler(EntityRef.class, new EntityRefTypeHandler(entityManager));
entityManager.setTypeSerializerLibrary(typeHandlerLibrary);
// Prefab Manager
PrefabManager prefabManager = new PojoPrefabManager(context);
entityManager.setPrefabManager(prefabManager);
context.put(PrefabManager.class, prefabManager);
EntitySystemLibrary library = context.get(EntitySystemLibrary.class);
entityManager.setComponentLibrary(library.getComponentLibrary());
//Record and Replay
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = context.get(RecordAndReplayCurrentStatus.class);
RecordAndReplayUtils recordAndReplayUtils = context.get(RecordAndReplayUtils.class);
CharacterStateEventPositionMap characterStateEventPositionMap = context.get(CharacterStateEventPositionMap.class);
DirectionAndOriginPosRecorderList directionAndOriginPosRecorderList = context.get(DirectionAndOriginPosRecorderList.class);
RecordedEventStore recordedEventStore = new RecordedEventStore();
RecordAndReplaySerializer recordAndReplaySerializer =
new RecordAndReplaySerializer(entityManager, recordedEventStore, recordAndReplayUtils, characterStateEventPositionMap,
directionAndOriginPosRecorderList, moduleManager, context.get(TypeRegistry.class));
context.put(RecordAndReplaySerializer.class, recordAndReplaySerializer);
// Event System
EventSystem eventSystem = createEventSystem(networkSystem, entityManager, library, recordedEventStore,
recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
entityManager.setEventSystem(eventSystem);
context.put(EventSystem.class, eventSystem);
// TODO: Review - NodeClassLibrary related to the UI for behaviours. Should not be here and probably not even in the CoreRegistry
context.put(OneOfProviderFactory.class, new OneOfProviderFactory());
registerComponents(library.getComponentLibrary(), environment);
registerEvents(entityManager.getEventSystem(), environment);
@Deprecated
public static void addEntityManagementRelatedClasses(Context context, ServiceRegistry serviceRegistry) {
addEntityManagementRelatedClasses(serviceRegistry);
}
private static EventSystem createEventSystem(NetworkSystem networkSystem,
PojoEntityManager entityManager,
EntitySystemLibrary library,
RecordedEventStore recordedEventStore,
RecordAndReplaySerializer recordAndReplaySerializer,
RecordAndReplayUtils recordAndReplayUtils,
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus) {
EventSystem eventSystem;
List<Class<?>> selectedClassesToRecord = createSelectedClassesToRecordList();
if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.PREPARING_REPLAY) {
eventSystem = new EventSystemReplayImpl(library.getEventLibrary(), networkSystem, entityManager, recordedEventStore,
recordAndReplaySerializer, recordAndReplayUtils, selectedClassesToRecord, recordAndReplayCurrentStatus);
private static void registerEventSystem(RecordAndReplayCurrentStatus recordAndReplayCurrentStatus, ServiceRegistry serviceRegistry) {
RecordingClasses recordingClasses = new RecordingClasses(createSelectedClassesToRecordList());
serviceRegistry.with(RecordingClasses.class).lifetime(Lifetime.Singleton).use(() -> recordingClasses);
if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.NOT_ACTIVATED) {
serviceRegistry.with(EventSystem.class).lifetime(Lifetime.Singleton).use(EventSystemImpl.class);
} else if (recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.PREPARING_REPLAY) {
serviceRegistry.with(EventSystem.class).lifetime(Lifetime.Singleton).use(EventSystemReplayImpl.class);
} else {
EventCatcher eventCatcher = new EventCatcher(selectedClassesToRecord, recordedEventStore);
eventSystem = new EventSystemImpl(networkSystem.getMode().isAuthority());
eventSystem = new NetworkEventSystemDecorator(eventSystem, networkSystem, library.getEventLibrary());
eventSystem = new RecordingEventSystemDecorator(eventSystem, eventCatcher, recordAndReplayCurrentStatus);
serviceRegistry.with(EventSystem.class).lifetime(Lifetime.Singleton).use(RecordingEventSystemWrapped.class);
}
return eventSystem;
}
static void registerComponents(ComponentLibrary library, ModuleEnvironment environment) {
public static void registerComponents(ComponentLibrary library, ModuleEnvironment environment) {
for (Class<? extends Component> componentType : environment.getSubtypesOf(Component.class)) {
if (componentType.getAnnotation(DoNotAutoRegister.class) == null
&& !componentType.isInterface()
@ -181,7 +150,7 @@ static void registerComponents(ComponentLibrary library, ModuleEnvironment envir
}
}
private static void registerEvents(EventSystem eventSystem, ModuleEnvironment environment) {
public static void registerEvents(EventSystem eventSystem, ModuleEnvironment environment) {
for (Class<? extends Event> type : environment.getSubtypesOf(Event.class)) {
if (type.getAnnotation(DoNotAutoRegister.class) == null) {
Name module = verifyNotNull(environment.getModuleProviding(type),
@ -202,4 +171,15 @@ private static List<Class<?>> createSelectedClassesToRecordList() {
return selectedClassesToRecord;
}
public static final class RecordingEventSystemWrapped extends RecordingEventSystemDecorator {
@Inject
public RecordingEventSystemWrapped(RecordingClasses recordingClasses, NetworkSystem networkSystem,
EntitySystemLibrary entitySystemLibrary,
RecordedEventStore recordedEventStore,
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus) {
super(new NetworkEventSystemDecorator(new EventSystemImpl(networkSystem.getMode().isAuthority()),
networkSystem, entitySystemLibrary.getEventLibrary()), new EventCatcher(recordingClasses, recordedEventStore),
recordAndReplayCurrentStatus);
}
}
}

View file

@ -12,6 +12,7 @@
import org.joml.Vector4i;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.flexible.AutoConfigManager;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.module.ModuleManager;
@ -25,13 +26,13 @@
import org.terasology.engine.entitySystem.systems.internal.DoNotAutoRegister;
import org.terasology.engine.persistence.typeHandling.RegisterTypeHandler;
import org.terasology.engine.persistence.typeHandling.RegisterTypeHandlerFactory;
import org.terasology.engine.persistence.typeHandling.TypeHandlerLibraryImpl;
import org.terasology.engine.persistence.typeHandling.extensionTypes.CollisionGroupTypeHandler;
import org.terasology.engine.physics.CollisionGroup;
import org.terasology.engine.physics.CollisionGroupManager;
import org.terasology.engine.registry.InjectionHelper;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.naming.Name;
@ -74,45 +75,40 @@ public final class EnvironmentSwitchHandler {
public EnvironmentSwitchHandler() {
}
public void handleSwitchToGameEnvironment(Context context) {
ModuleManager moduleManager = context.get(ModuleManager.class);
public void handleSwitchToGameEnvironment(Context engineContext, ServiceRegistry gameContextRegistry) {
ModuleManager moduleManager = engineContext.get(ModuleManager.class);
ModuleEnvironment environment = moduleManager.getEnvironment();
ModuleTypeRegistry typeRegistry = context.get(ModuleTypeRegistry.class);
ModuleTypeRegistry typeRegistry = engineContext.get(ModuleTypeRegistry.class);
typeRegistry.reload(environment);
CopyStrategyLibrary copyStrategyLibrary = context.get(CopyStrategyLibrary.class);
CopyStrategyLibrary copyStrategyLibrary = engineContext.get(CopyStrategyLibrary.class);
copyStrategyLibrary.clear();
for (CopyStrategyEntry<?> entry : typesWithCopyConstructors) {
entry.registerWith(copyStrategyLibrary);
}
//TODO: find a permanent fix over just creating a new typehandler
// https://github.com/Terasology/JoshariasSurvival/issues/31
// TypeHandlerLibrary typeHandlerLibrary = context.get(TypeHandlerLibrary.class);
// typeHandlerLibrary.addTypeHandler(CollisionGroup.class, new CollisionGroupTypeHandler(context.get(CollisionGroupManager.class)));
TypeHandlerLibrary typeHandlerLibrary = TypeHandlerLibraryImpl.forModuleEnvironment(moduleManager, typeRegistry);
typeHandlerLibrary.addTypeHandler(CollisionGroup.class, new CollisionGroupTypeHandler(context.get(CollisionGroupManager.class)));
context.put(TypeHandlerLibrary.class, typeHandlerLibrary);
TypeHandlerLibrary typeHandlerLibrary = engineContext.get(TypeHandlerLibrary.class);
typeHandlerLibrary.addTypeHandler(CollisionGroup.class, new CollisionGroupTypeHandler(engineContext.get(CollisionGroupManager.class)));
// Entity System Library
EntitySystemLibrary library = new EntitySystemLibrary(context, typeHandlerLibrary);
context.put(EntitySystemLibrary.class, library);
EntitySystemLibrary library = new EntitySystemLibrary(engineContext, typeHandlerLibrary);
gameContextRegistry.with(EntitySystemLibrary.class).lifetime(Lifetime.Singleton).use(() -> library);
ComponentLibrary componentLibrary = library.getComponentLibrary();
context.put(ComponentLibrary.class, componentLibrary);
context.put(EventLibrary.class, library.getEventLibrary());
context.put(ClassMetaLibrary.class, new ClassMetaLibraryImpl(context));
gameContextRegistry.with(ComponentLibrary.class).lifetime(Lifetime.Singleton).use(() -> componentLibrary);
gameContextRegistry.with(EventLibrary.class).lifetime(Lifetime.Singleton).use(library::getEventLibrary);
ClassMetaLibraryImpl classMetaLibrary = new ClassMetaLibraryImpl(moduleManager);
gameContextRegistry.with(ClassMetaLibrary.class).lifetime(Lifetime.Singleton).use(() -> classMetaLibrary);
registerComponents(componentLibrary, environment);
registerTypeHandlers(context, typeHandlerLibrary, environment);
registerTypeHandlers(engineContext, typeHandlerLibrary, environment);
// Load configs for the new environment
AutoConfigManager autoConfigManager = context.get(AutoConfigManager.class);
autoConfigManager.loadConfigsIn(context);
AutoConfigManager autoConfigManager = engineContext.get(AutoConfigManager.class);
autoConfigManager.loadConfigsIn(environment, gameContextRegistry);
ModuleAwareAssetTypeManager assetTypeManager = context.get(ModuleAwareAssetTypeManager.class);
ModuleAwareAssetTypeManager assetTypeManager = engineContext.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.

View file

@ -3,6 +3,7 @@
package org.terasology.engine.core.modes;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
@ -20,8 +21,7 @@
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.nui.NUIManager;
import org.terasology.engine.rendering.nui.internal.NUIManagerInternal;
import org.terasology.engine.rendering.nui.internal.TerasologyCanvasRenderer;
import org.terasology.nui.canvas.CanvasRenderer;
import org.terasology.gestalt.di.ServiceRegistry;
import static com.google.common.base.Verify.verifyNotNull;
@ -31,36 +31,43 @@ public abstract class AbstractState implements GameState {
protected EventSystem eventSystem;
protected ComponentSystemManager componentSystemManager;
protected void initEntityAndComponentManagers(boolean isHeadless) {
protected void registerEntityAndComponentManagers(boolean isHeadless, ServiceRegistry serviceRegistry) {
verifyNotNull(context);
CoreRegistry.setContext(context);
// let's get the entity event system running
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
entityManager = context.get(EngineEntityManager.class);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context, serviceRegistry);
eventSystem = context.get(EventSystem.class);
context.put(Console.class, new ConsoleImpl(context));
serviceRegistry.with(Console.class).lifetime(Lifetime.Singleton).use(ConsoleImpl.class);
if (!isHeadless) {
NUIManager nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
context.put(NUIManager.class, nuiManager);
serviceRegistry.with(NUIManager.class).lifetime(Lifetime.Singleton).use(NUIManagerInternal.class);
}
componentSystemManager = new ComponentSystemManager(context);
context.put(ComponentSystemManager.class, componentSystemManager);
serviceRegistry.with(ComponentSystemManager.class).lifetime(Lifetime.Singleton).use(ComponentSystemManager.class);
}
protected void initEntityAndComponentManagers() {
verifyNotNull(context);
CoreRegistry.setContext(context);
entityManager = context.get(EngineEntityManager.class);
eventSystem = context.get(EventSystem.class);
componentSystemManager = context.get(ComponentSystemManager.class);
componentSystemManager.register(new ConsoleSystem(), "engine:ConsoleSystem");
componentSystemManager.register(new CoreCommands(), "engine:CoreCommands");
}
protected static void createLocalPlayer(Context context) {
EngineEntityManager entityManager = context.get(EngineEntityManager.class);
EntityRef localPlayerEntity = entityManager.create(new ClientComponent());
protected void registerLocalPlayer(ServiceRegistry serviceRegistry) {
LocalPlayer localPlayer = new LocalPlayer();
localPlayer.setRecordAndReplayClasses(context.get(DirectionAndOriginPosRecorderList.class),
context.get(RecordAndReplayCurrentStatus.class));
context.put(LocalPlayer.class, localPlayer);
localPlayer.setClientEntity(localPlayerEntity);
serviceRegistry.with(LocalPlayer.class).lifetime(Lifetime.Singleton).use(() -> localPlayer);
}
protected void createLocalPlayer() {
EntityRef localPlayerEntity = entityManager.create(new ClientComponent());
context.get(LocalPlayer.class).setClientEntity(localPlayerEntity);
}
@Override

View file

@ -7,6 +7,7 @@
import com.google.common.collect.Queues;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.crashreporter.CrashReporter;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
@ -15,10 +16,12 @@
import org.terasology.engine.core.LoggingContext;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.modes.loadProcesses.AwaitCharacterSpawn;
import org.terasology.engine.core.modes.loadProcesses.ConfigureEntitySystem;
import org.terasology.engine.core.modes.loadProcesses.CreateRemoteWorldEntity;
import org.terasology.engine.core.modes.loadProcesses.CreateWorldEntity;
import org.terasology.engine.core.modes.loadProcesses.EnsureSaveGameConsistency;
import org.terasology.engine.core.modes.loadProcesses.InitialiseBlockTypeEntities;
import org.terasology.engine.core.modes.loadProcesses.InitialiseBlocks;
import org.terasology.engine.core.modes.loadProcesses.InitialiseCommandSystem;
import org.terasology.engine.core.modes.loadProcesses.InitialiseComponentSystemManager;
import org.terasology.engine.core.modes.loadProcesses.InitialiseEntitySystem;
@ -42,7 +45,9 @@
import org.terasology.engine.core.modes.loadProcesses.RegisterBlocks;
import org.terasology.engine.core.modes.loadProcesses.RegisterInputSystem;
import org.terasology.engine.core.modes.loadProcesses.RegisterMods;
import org.terasology.engine.core.modes.loadProcesses.RegisterRemoteWorldSystems;
import org.terasology.engine.core.modes.loadProcesses.RegisterSystems;
import org.terasology.engine.core.modes.loadProcesses.RegisterWorldSystems;
import org.terasology.engine.core.modes.loadProcesses.SetupLocalPlayer;
import org.terasology.engine.core.modes.loadProcesses.SetupRemotePlayer;
import org.terasology.engine.core.modes.loadProcesses.StartServer;
@ -59,6 +64,7 @@
import org.terasology.engine.rendering.nui.internal.TerasologyCanvasRenderer;
import org.terasology.engine.rendering.nui.layers.mainMenu.loadingScreen.LoadingScreen;
import org.terasology.engine.world.chunks.event.OnChunkLoaded;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.nui.canvas.CanvasRenderer;
import java.util.Queue;
@ -70,6 +76,7 @@ public class StateLoading implements GameState {
private final NetworkMode netMode;
private final Queue<LoadProcess> loadProcesses = Queues.newArrayDeque();
private Context context;
private ServiceRegistry serviceRegistry;
private LoadProcess current;
private JoinStatus joinStatus;
@ -108,6 +115,8 @@ public StateLoading(JoinStatus joinStatus) {
@Override
public void init(GameEngine engine) {
this.context = engine.createChildContext();
this.serviceRegistry = new ServiceRegistry();
headless = context.get(DisplayDevice.class).isHeadless();
CoreRegistry.setContext(context);
@ -115,8 +124,11 @@ public void init(GameEngine engine) {
systemConfig = context.get(SystemConfig.class);
if (!headless) {
// Assign a temporary NUIManager instance for showing the loading screen.
this.nuiManager = new NUIManagerInternal((TerasologyCanvasRenderer) context.get(CanvasRenderer.class), context);
context.put(NUIManager.class, nuiManager);
context.put(NUIManager.class, this.nuiManager);
// This temporary instance will be replaced by the one in the context when it is created.
serviceRegistry.with(NUIManager.class).lifetime(Lifetime.Singleton).use(NUIManagerInternal.class);
}
EngineTime time = (EngineTime) context.get(Time.class);
@ -126,10 +138,10 @@ public void init(GameEngine engine) {
context.get(Game.class).load(gameManifest);
switch (netMode) {
case CLIENT:
initClient();
initClient(engine, serviceRegistry);
break;
default:
initHost();
initHost(engine, serviceRegistry);
break;
}
@ -147,84 +159,58 @@ public void init(GameEngine engine) {
chunkGenerationStarted = false;
}
private void initClient() {
private void initClient(GameEngine engine, ServiceRegistry serviceRegistry) {
loadProcesses.add(new JoinServer(context, gameManifest, joinStatus));
if (!headless) {
loadProcesses.add(new InitialiseRendering(context));
loadProcesses.add(new InitialiseRendering(serviceRegistry));
}
loadProcesses.add(new InitialiseEntitySystem(context));
loadProcesses.add(new RegisterBlocks(context, gameManifest));
loadProcesses.add(new InitialiseEntitySystem(context, serviceRegistry));
loadProcesses.add(new RegisterBlocks(context, serviceRegistry));
if (!headless) {
loadProcesses.add(new InitialiseGraphics(context));
}
loadProcesses.add(new LoadPrefabs(context));
loadProcesses.add(new ProcessBlockPrefabs(context));
loadProcesses.add(new LoadExtraBlockData(context));
loadProcesses.add(new InitialiseComponentSystemManager(context));
// loadProcesses.add(new LoadPrefabs(context));
// loadProcesses.add(new ProcessBlockPrefabs(context));
loadProcesses.add(new LoadExtraBlockData(serviceRegistry));
loadProcesses.add(new InitialiseComponentSystemManager(serviceRegistry));
if (!headless) {
loadProcesses.add(new RegisterInputSystem(context));
}
loadProcesses.add(new RegisterSystems(context, netMode));
loadProcesses.add(new InitialiseCommandSystem(context));
loadProcesses.add(new InitialiseRemoteWorld(context, gameManifest));
loadProcesses.add(new InitialisePhysics(context));
loadProcesses.add(new InitialiseSystems(context));
loadProcesses.add(new PreBeginSystems(context));
loadProcesses.add(new CreateRemoteWorldEntity(context));
loadProcesses.add(new PostBeginSystems(context));
loadProcesses.add(new SetupRemotePlayer(context));
loadProcesses.add(new AwaitCharacterSpawn(context));
loadProcesses.add(new RegisterBlockFamilies(context));
loadProcesses.add(new PrepareWorld(context));
// loadProcesses.add(new RegisterSystems(context, netMode));
// loadProcesses.add(new RegisterWorldSystems(gameManifest, context));
loadProcesses.add(new InitialiseCommandSystem(serviceRegistry));
loadProcesses.add(new InitialiseRemoteWorld(context, serviceRegistry, gameManifest));
loadProcesses.add(new InitialisePhysics(context, serviceRegistry));
// loadProcesses.add(new InitialiseSystems(context));
// loadProcesses.add(new PreBeginSystems(context));
// loadProcesses.add(new CreateRemoteWorldEntity(context));
// loadProcesses.add(new PostBeginSystems(context));
// loadProcesses.add(new SetupRemotePlayer(context));
// loadProcesses.add(new AwaitCharacterSpawn(context));
// loadProcesses.add(new RegisterBlockFamilies(context));
// loadProcesses.add(new PrepareWorld(context));
loadProcesses.add(new SwitchToContextStep(engine));
loadProcesses.add(new AddClientPostLoadProcessesStep());
}
private void initHost() {
loadProcesses.add(new RegisterMods(context, gameManifest));
private void initHost(GameEngine engine, ServiceRegistry serviceRegistry) {
loadProcesses.add(new RegisterMods(context, serviceRegistry, gameManifest));
if (!headless) {
loadProcesses.add(new InitialiseRendering(context));
loadProcesses.add(new InitialiseRendering(serviceRegistry));
}
loadProcesses.add(new InitialiseEntitySystem(context));
loadProcesses.add(new RegisterBlocks(context, gameManifest));
loadProcesses.add(new InitialiseEntitySystem(context, serviceRegistry));
loadProcesses.add(new RegisterBlocks(context, serviceRegistry));
if (!headless) {
loadProcesses.add(new InitialiseGraphics(context));
}
loadProcesses.add(new LoadPrefabs(context));
loadProcesses.add(new ProcessBlockPrefabs(context));
loadProcesses.add(new InitialiseComponentSystemManager(context));
if (!headless) {
loadProcesses.add(new RegisterInputSystem(context));
}
loadProcesses.add(new RegisterSystems(context, netMode));
loadProcesses.add(new InitialiseCommandSystem(context));
loadProcesses.add(new LoadExtraBlockData(context));
loadProcesses.add(new InitialiseWorld(gameManifest, context));
loadProcesses.add(new RegisterBlockFamilies(context));
loadProcesses.add(new EnsureSaveGameConsistency(context));
loadProcesses.add(new InitialisePhysics(context));
loadProcesses.add(new InitialiseSystems(context));
loadProcesses.add(new PreBeginSystems(context));
loadProcesses.add(new LoadEntities(context));
loadProcesses.add(new InitialiseBlockTypeEntities(context));
loadProcesses.add(new CreateWorldEntity(context, gameManifest));
loadProcesses.add(new InitialiseWorldGenerator(context));
loadProcesses.add(new InitialiseRecordAndReplay(context));
if (netMode.isServer()) {
boolean dedicated;
if (netMode == NetworkMode.DEDICATED_SERVER) {
dedicated = true;
} else if (netMode == NetworkMode.LISTEN_SERVER) {
dedicated = false;
} else {
throw new IllegalStateException("Invalid server mode: " + netMode);
}
loadProcesses.add(new StartServer(context, dedicated));
}
loadProcesses.add(new PostBeginSystems(context));
if (netMode.hasLocalClient()) {
loadProcesses.add(new SetupLocalPlayer(context));
loadProcesses.add(new AwaitCharacterSpawn(context));
}
loadProcesses.add(new PrepareWorld(context));
loadProcesses.add(new InitialiseComponentSystemManager(serviceRegistry));
loadProcesses.add(new InitialiseCommandSystem(serviceRegistry));
loadProcesses.add(new LoadExtraBlockData(serviceRegistry));
loadProcesses.add(new InitialiseWorld(gameManifest, context, serviceRegistry));
loadProcesses.add(new InitialisePhysics(context, serviceRegistry));
loadProcesses.add(new SwitchToContextStep(engine));
// Post-Init processes
loadProcesses.add(new AddHostPostLoadProcessesStep());
}
private void popStep() {
@ -325,4 +311,155 @@ public void onChunkLoaded(OnChunkLoaded chunkAvailable, EntityRef worldEntity) {
EngineTime time = (EngineTime) context.get(Time.class);
timeLastChunkGenerated = time.getRealTimeInMs();
}
private class SwitchToContextStep implements LoadProcess {
private final GameEngine engine;
SwitchToContextStep(GameEngine engine) {
this.engine = engine;
}
@Override
public String getMessage() {
return "Entering new game context...";
}
@Override
public boolean step() {
context = engine.createChildContext(serviceRegistry);
CoreRegistry.setContext(context);
nuiManager = context.get(NUIManager.class);
return true;
}
@Override
public void begin() {
}
@Override
public float getProgress() {
return 0;
}
@Override
public int getExpectedCost() {
return 0;
}
}
private class AddHostPostLoadProcessesStep implements LoadProcess {
@Override
public String getMessage() {
return "";
}
@Override
public boolean step() {
loadProcesses.add(new ConfigureEntitySystem(context));
loadProcesses.add(new InitialiseBlocks(gameManifest, context));
loadProcesses.add(new LoadPrefabs(context));
loadProcesses.add(new RegisterSystems(context, netMode));
if (!headless) {
loadProcesses.add(new RegisterInputSystem(context));
}
loadProcesses.add(new RegisterWorldSystems(gameManifest, context));
loadProcesses.add(new RegisterBlockFamilies(context));
loadProcesses.add(new ProcessBlockPrefabs(context));
loadProcesses.add(new InitialiseSystems(context));
loadProcesses.add(new PreBeginSystems(context));
loadProcesses.add(new LoadEntities(context));
loadProcesses.add(new InitialiseBlockTypeEntities(context));
loadProcesses.add(new CreateWorldEntity(context, gameManifest));
loadProcesses.add(new InitialiseWorldGenerator(context));
loadProcesses.add(new InitialiseRecordAndReplay(context));
if (netMode.isServer()) {
boolean dedicated;
if (netMode == NetworkMode.DEDICATED_SERVER) {
dedicated = true;
} else if (netMode == NetworkMode.LISTEN_SERVER) {
dedicated = false;
} else {
throw new IllegalStateException("Invalid server mode: " + netMode);
}
loadProcesses.add(new StartServer(context, dedicated));
}
loadProcesses.add(new PostBeginSystems(context));
if (netMode.hasLocalClient()) {
loadProcesses.add(new SetupLocalPlayer(context));
loadProcesses.add(new AwaitCharacterSpawn(context));
}
loadProcesses.add(new PrepareWorld(context));
return true;
}
@Override
public void begin() {
}
@Override
public float getProgress() {
return 0;
}
@Override
public int getExpectedCost() {
return 0;
}
}
private class AddClientPostLoadProcessesStep implements LoadProcess {
@Override
public String getMessage() {
return "";
}
@Override
public boolean step() {
loadProcesses.add(new ConfigureEntitySystem(context));
loadProcesses.add(new InitialiseBlocks(gameManifest, context));
loadProcesses.add(new LoadPrefabs(context));
loadProcesses.add(new RegisterSystems(context, netMode));
if (!headless) {
loadProcesses.add(new RegisterInputSystem(context));
}
loadProcesses.add(new RegisterRemoteWorldSystems(gameManifest, context));
loadProcesses.add(new RegisterBlockFamilies(context));
loadProcesses.add(new ProcessBlockPrefabs(context));
loadProcesses.add(new InitialiseSystems(context));
loadProcesses.add(new PreBeginSystems(context));
loadProcesses.add(new CreateRemoteWorldEntity(context));
loadProcesses.add(new InitialiseBlockTypeEntities(context));
loadProcesses.add(new InitialiseRecordAndReplay(context));
if (netMode.isServer()) {
boolean dedicated;
if (netMode == NetworkMode.DEDICATED_SERVER) {
dedicated = true;
} else if (netMode == NetworkMode.LISTEN_SERVER) {
dedicated = false;
} else {
throw new IllegalStateException("Invalid server mode: " + netMode);
}
loadProcesses.add(new StartServer(context, dedicated));
}
loadProcesses.add(new PostBeginSystems(context));
loadProcesses.add(new SetupRemotePlayer(context));
loadProcesses.add(new AwaitCharacterSpawn(context));
loadProcesses.add(new PrepareWorld(context));
return true;
}
@Override
public void begin() {
}
@Override
public float getProgress() {
return 0;
}
@Override
public int getExpectedCost() {
return 0;
}
}
}

View file

@ -3,20 +3,24 @@
package org.terasology.engine.core.modes;
import com.google.common.base.MoreObjects;
import org.terasology.context.Lifetime;
import org.terasology.engine.audio.AudioManager;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.LoggingContext;
import org.terasology.engine.core.modes.loadProcesses.RegisterInputSystem;
import org.terasology.engine.core.subsystem.DisplayDevice;
import org.terasology.engine.i18n.TranslationSystem;
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker;
import org.terasology.engine.input.InputSystem;
import org.terasology.engine.input.cameraTarget.CameraTargetSystem;
import org.terasology.engine.logic.console.Console;
import org.terasology.engine.logic.players.LocalPlayerSystem;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.nui.NUIManager;
import org.terasology.engine.rendering.nui.editor.systems.NUIEditorSystem;
import org.terasology.engine.rendering.nui.editor.systems.NUISkinEditorSystem;
import org.terasology.engine.rendering.nui.layers.mainMenu.MessagePopup;
import org.terasology.engine.utilities.Assets;
import org.terasology.gestalt.di.ServiceRegistry;
/**
* The class implements the main game menu.
@ -41,27 +45,43 @@ public StateMainMenu(String showMessageOnLoad) {
@Override
public void init(GameEngine gameEngine) {
context = gameEngine.createChildContext();
ServiceRegistry serviceRegistry = new ServiceRegistry();
headless = context.get(DisplayDevice.class).isHeadless();
initEntityAndComponentManagers(headless);
createLocalPlayer(context);
registerEntityAndComponentManagers(headless, serviceRegistry);
registerLocalPlayer(serviceRegistry);
if (!headless) {
// TODO: REMOVE this and handle refreshing of core game state at the engine level - see Issue #1127
new RegisterInputSystem(context).step();
NUIEditorSystem nuiEditorSystem = new NUIEditorSystem();
serviceRegistry.with(NUIEditorSystem.class).lifetime(Lifetime.Singleton).use(() -> nuiEditorSystem);
NUISkinEditorSystem nuiSkinEditorSystem = new NUISkinEditorSystem();
serviceRegistry.with(NUISkinEditorSystem.class).lifetime(Lifetime.Singleton).use(() -> nuiSkinEditorSystem);
LocalPlayerSystem localPlayerSystem = new LocalPlayerSystem();
serviceRegistry.with(LocalPlayerSystem.class).lifetime(Lifetime.Singleton).use(() -> localPlayerSystem);
CameraTargetSystem cameraTargetSystem = new CameraTargetSystem();
serviceRegistry.with(CameraTargetSystem.class).lifetime(Lifetime.Singleton).use(() -> cameraTargetSystem);
}
context = gameEngine.createImmutableChildContext(serviceRegistry);
CoreRegistry.setContext(context);
initEntityAndComponentManagers();
createLocalPlayer();
if (!headless) {
componentSystemManager.register(context.get(LocalPlayerSystem.class), "engine:localPlayerSystem");
componentSystemManager.register(context.get(CameraTargetSystem.class), "engine:CameraTargetSystem");
inputSystem = context.get(InputSystem.class);
componentSystemManager.register(inputSystem, "engine:InputSystem");
nuiManager = context.get(NUIManager.class);
eventSystem.registerEventHandler(nuiManager);
NUIEditorSystem nuiEditorSystem = new NUIEditorSystem();
context.put(NUIEditorSystem.class, nuiEditorSystem);
componentSystemManager.register(nuiEditorSystem, "engine:NUIEditorSystem");
NUISkinEditorSystem nuiSkinEditorSystem = new NUISkinEditorSystem();
context.put(NUISkinEditorSystem.class, nuiSkinEditorSystem);
componentSystemManager.register(nuiSkinEditorSystem, "engine:NUISkinEditorSystem");
inputSystem = context.get(InputSystem.class);
componentSystemManager.register(context.get(NUIEditorSystem.class), "engine:NUIEditorSystem");
componentSystemManager.register(context.get(NUISkinEditorSystem.class), "engine:NUISkinEditorSystem");
}
componentSystemManager.initialise();

View file

@ -0,0 +1,42 @@
// Copyright 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.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
public class ConfigureEntitySystem extends SingleStepLoadProcess {
private final Context context;
public ConfigureEntitySystem(Context context) {
this.context = context;
}
@Override
public String getMessage() {
return "Configuring Entity System...";
}
@Override
public boolean step() {
EntitySystemSetupUtil.configureEntityManagementRelatedClasses(
context.get(TypeHandlerLibrary.class),
context.get(EntitySystemLibrary.class),
context.get(ModuleManager.class).getEnvironment(),
context.get(EngineEntityManager.class)
);
return true;
}
@Override
public int getExpectedCost() {
return 1;
}
}

View file

@ -0,0 +1,36 @@
// Copyright 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.game.GameManifest;
import org.terasology.engine.world.block.BlockManager;
import org.terasology.engine.world.block.internal.BlockManagerImpl;
public class InitialiseBlocks extends SingleStepLoadProcess {
private final Context context;
private final GameManifest gameManifest;
public InitialiseBlocks(GameManifest gameManifest, Context context) {
this.context = context;
this.gameManifest = gameManifest;
}
@Override
public String getMessage() {
return "Initialising Blocks...";
}
@Override
public boolean step() {
((BlockManagerImpl) context.get(BlockManager.class)).initialise(gameManifest.getRegisteredBlockFamilies(), gameManifest.getBlockIdMap());
return true;
}
@Override
public int getExpectedCost() {
return 1;
}
}

View file

@ -3,17 +3,18 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.logic.console.Console;
import org.terasology.engine.logic.console.ConsoleImpl;
import org.terasology.gestalt.di.ServiceRegistry;
public class InitialiseCommandSystem extends SingleStepLoadProcess {
private Context context;
private ServiceRegistry serviceRegistry;
public InitialiseCommandSystem(Context context) {
this.context = context;
public InitialiseCommandSystem(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
@Override
@ -23,7 +24,7 @@ public String getMessage() {
@Override
public boolean step() {
context.put(Console.class, new ConsoleImpl(context));
serviceRegistry.with(Console.class).lifetime(Lifetime.Singleton).use(ConsoleImpl.class);
return true;
}

View file

@ -3,16 +3,17 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.gestalt.di.ServiceRegistry;
public class InitialiseComponentSystemManager extends SingleStepLoadProcess {
private final Context context;
private final ServiceRegistry serviceRegistry;
public InitialiseComponentSystemManager(Context context) {
this.context = context;
public InitialiseComponentSystemManager(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
@Override
@ -22,7 +23,7 @@ public String getMessage() {
@Override
public boolean step() {
context.put(ComponentSystemManager.class, new ComponentSystemManager(context));
serviceRegistry.with(ComponentSystemManager.class).lifetime(Lifetime.Singleton).use(ComponentSystemManager.class);
return true;
}

View file

@ -6,13 +6,16 @@
import org.terasology.engine.context.Context;
import org.terasology.engine.core.bootstrap.EntitySystemSetupUtil;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.gestalt.di.ServiceRegistry;
public class InitialiseEntitySystem extends SingleStepLoadProcess {
private final Context context;
private final ServiceRegistry serviceRegistry;
public InitialiseEntitySystem(Context context) {
public InitialiseEntitySystem(Context context, ServiceRegistry serviceRegistry) {
this.context = context;
this.serviceRegistry = serviceRegistry;
}
@Override
@ -22,7 +25,7 @@ public String getMessage() {
@Override
public boolean step() {
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context);
EntitySystemSetupUtil.addEntityManagementRelatedClasses(context, serviceRegistry);
return true;
}
@ -30,5 +33,4 @@ public boolean step() {
public int getExpectedCost() {
return 1;
}
}

View file

@ -2,17 +2,21 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.physics.Physics;
import org.terasology.engine.physics.engine.PhysicsEngine;
import org.terasology.engine.physics.engine.PhysicsEngineManager;
import org.terasology.gestalt.di.ServiceRegistry;
public class InitialisePhysics extends SingleStepLoadProcess {
private final Context context;
private final ServiceRegistry serviceRegistry;
public InitialisePhysics(Context context) {
public InitialisePhysics(Context context, ServiceRegistry serviceRegistry) {
this.context = context;
this.serviceRegistry = serviceRegistry;
}
@Override
@ -22,9 +26,7 @@ public String getMessage() {
@Override
public boolean step() {
PhysicsEngine physicsEngine = PhysicsEngineManager.getNewPhysicsEngine(context);
context.put(Physics.class, physicsEngine);
context.put(PhysicsEngine.class, physicsEngine);
PhysicsEngineManager.registerPhysicsEngine(serviceRegistry);
return true;
}

View file

@ -3,40 +3,45 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.engine.config.Config;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.ComponentSystemManager;
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.rendering.backdrop.BackdropProvider;
import org.terasology.engine.rendering.backdrop.Skysphere;
import org.terasology.engine.rendering.cameras.Camera;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.engine.world.WorldProvider;
import org.terasology.engine.world.block.BlockManager;
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.engine.world.chunks.ChunkProvider;
import org.terasology.engine.world.chunks.remoteChunkProvider.RemoteChunkProvider;
import org.terasology.engine.world.internal.EntityAwareWorldProvider;
import org.terasology.engine.world.internal.WorldInfo;
import org.terasology.engine.world.internal.WorldProviderCore;
import org.terasology.engine.world.internal.WorldProviderCoreImpl;
import org.terasology.engine.world.internal.WorldProviderWrapper;
import org.terasology.engine.world.sun.BasicCelestialModel;
import org.terasology.engine.world.sun.CelestialModel;
import org.terasology.engine.world.sun.CelestialSystem;
import org.terasology.engine.world.sun.DefaultCelestialSystem;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class InitialiseRemoteWorld extends SingleStepLoadProcess {
private final Context context;
private final ServiceRegistry serviceRegistry;
private final GameManifest gameManifest;
public InitialiseRemoteWorld(Context context, GameManifest gameManifest) {
public InitialiseRemoteWorld(Context context, ServiceRegistry serviceRegistry, GameManifest gameManifest) {
this.context = context;
this.serviceRegistry = serviceRegistry;
this.gameManifest = gameManifest;
}
@ -47,39 +52,28 @@ public String getMessage() {
@Override
public boolean step() {
// TODO: These shouldn't be done here, nor so strongly tied to the world renderer
LocalPlayer localPlayer = new LocalPlayer();
localPlayer.setRecordAndReplayClasses(context.get(DirectionAndOriginPosRecorderList.class), context.get(RecordAndReplayCurrentStatus.class));
context.put(LocalPlayer.class, localPlayer);
BlockManager blockManager = context.get(BlockManager.class);
ExtraBlockDataManager extraDataManager = context.get(ExtraBlockDataManager.class);
RemoteChunkProvider chunkProvider = new RemoteChunkProvider(blockManager, localPlayer, context.get(Config.class));
serviceRegistry.with(LocalPlayer.class).lifetime(Lifetime.Singleton).use(() -> localPlayer);
serviceRegistry.with(ChunkProvider.class).lifetime(Lifetime.Singleton).use(RemoteChunkProvider.class);
WorldProviderCoreImpl worldProviderCore = new WorldProviderCoreImpl(gameManifest.getWorldInfo(TerasologyConstants.MAIN_WORLD), chunkProvider,
blockManager.getBlock(BlockManager.UNLOADED_ID), context);
EntityAwareWorldProvider entityWorldProvider = new EntityAwareWorldProvider(worldProviderCore, context);
WorldProvider worldProvider = new WorldProviderWrapper(entityWorldProvider, extraDataManager);
context.put(WorldProvider.class, worldProvider);
context.put(BlockEntityRegistry.class, entityWorldProvider);
context.get(ComponentSystemManager.class).register(entityWorldProvider, "engine:BlockEntityRegistry");
WorldInfo worldInfo = gameManifest.getWorldInfo(TerasologyConstants.MAIN_WORLD);
serviceRegistry.with(WorldInfo.class).lifetime(Lifetime.Singleton).use(() -> worldInfo);
DefaultCelestialSystem celestialSystem = new DefaultCelestialSystem(new BasicCelestialModel(), context);
context.put(CelestialSystem.class, celestialSystem);
context.get(ComponentSystemManager.class).register(celestialSystem);
// Provides both WorldProviderCore and BlockEntityRegistry
serviceRegistry.with(WorldProviderCoreWorkAround.class).lifetime(Lifetime.Singleton);
serviceRegistry.with(WorldProvider.class).lifetime(Lifetime.Singleton).use(WorldProviderWrapper.class);
serviceRegistry.with(CelestialModel.class).lifetime(Lifetime.Singleton).use(BasicCelestialModel.class);
serviceRegistry.with(CelestialSystem.class).lifetime(Lifetime.Singleton).use(DefaultCelestialSystem.class);
// Init. a new world
context.put(BackdropProvider.class, new Skysphere(context));
serviceRegistry.with(BackdropProvider.class).lifetime(Lifetime.Singleton).use(Skysphere.class);
RenderingSubsystemFactory engineSubsystemFactory = context.get(RenderingSubsystemFactory.class);
WorldRenderer worldRenderer = engineSubsystemFactory.createWorldRenderer(context);
float reflectionHeight = context.get(NetworkSystem.class).getServer().getInfo().getReflectionHeight();
worldRenderer.getActiveCamera().setReflectionHeight(reflectionHeight);
context.put(WorldRenderer.class, worldRenderer);
// TODO: These shouldn't be done here, nor so strongly tied to the world renderer
context.put(Camera.class, worldRenderer.getActiveCamera());
context.get(NetworkSystem.class).setRemoteWorldProvider(chunkProvider);
engineSubsystemFactory.registerWorldRenderer(context, serviceRegistry);
return true;
}
@ -89,4 +83,16 @@ public int getExpectedCost() {
return 1;
}
/**
* This work-around exists because you cannot easily have two instances of {@link WorldProviderCore} in the context at a given time.
* One of these instances exists purely to wrap the other, so we instantiate both at the same time here to leave only one instance.
*/
public static final class WorldProviderCoreWorkAround extends EntityAwareWorldProvider
implements WorldProviderCore, BlockEntityRegistry {
@Inject
public WorldProviderCoreWorkAround(WorldInfo info, ChunkProvider chunkProvider, BlockManager blockManager,
EntityManager entityManager, ComponentSystemManager componentSystemManager) {
super(new WorldProviderCoreImpl(info, chunkProvider, blockManager, entityManager), entityManager, componentSystemManager);
}
}
}

View file

@ -3,24 +3,25 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.module.rendering.RenderingModuleRegistry;
import org.terasology.gestalt.di.ServiceRegistry;
/**
* Add {@link RenderingModuleRegistry} to the game {@link Context}.
* Add {@link RenderingModuleRegistry} to the game {@link ServiceRegistry}.
*
* 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
* correctly when it has previously been constructed, this loading process will populate the {@link ServiceRegistry} 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;
private final ServiceRegistry serviceRegistry;
public InitialiseRendering(Context context) {
this.context = context;
public InitialiseRendering(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
@ -31,7 +32,8 @@ public String getMessage() {
@Override
public boolean step() {
context.put(RenderingModuleRegistry.class, new RenderingModuleRegistry());
RenderingModuleRegistry renderingModuleRegistry = new RenderingModuleRegistry();
serviceRegistry.with(RenderingModuleRegistry.class).lifetime(Lifetime.Singleton).use(() -> renderingModuleRegistry);
return true;
}

View file

@ -3,10 +3,9 @@
package org.terasology.engine.core.modes.loadProcesses;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.ComponentSystemManager;
@ -15,10 +14,8 @@
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.modes.StateMainMenu;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.internal.EngineEntityManager;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.logic.players.LocalPlayer;
import org.terasology.engine.persistence.StorageManager;
@ -26,21 +23,17 @@
import org.terasology.engine.persistence.internal.ReadWriteStorageManager;
import org.terasology.engine.recording.DirectionAndOriginPosRecorderList;
import org.terasology.engine.recording.RecordAndReplayCurrentStatus;
import org.terasology.engine.recording.RecordAndReplaySerializer;
import org.terasology.engine.recording.RecordAndReplayStatus;
import org.terasology.engine.recording.RecordAndReplayUtils;
import org.terasology.engine.rendering.backdrop.BackdropProvider;
import org.terasology.engine.rendering.backdrop.Skysphere;
import org.terasology.engine.rendering.cameras.Camera;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.engine.utilities.random.FastRandom;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.engine.world.WorldProvider;
import org.terasology.engine.world.block.Block;
import org.terasology.engine.world.block.BlockManager;
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.engine.world.chunks.ChunkProvider;
import org.terasology.engine.world.chunks.localChunkProvider.LocalChunkProvider;
import org.terasology.engine.world.chunks.localChunkProvider.RelevanceSystem;
import org.terasology.engine.world.generator.ScalableWorldGenerator;
import org.terasology.engine.world.generator.UnresolvedWorldGeneratorException;
import org.terasology.engine.world.generator.WorldGenerator;
import org.terasology.engine.world.generator.internal.WorldGeneratorManager;
@ -48,15 +41,17 @@
import org.terasology.engine.world.generator.plugin.WorldGeneratorPluginLibrary;
import org.terasology.engine.world.internal.EntityAwareWorldProvider;
import org.terasology.engine.world.internal.WorldInfo;
import org.terasology.engine.world.internal.WorldProviderCore;
import org.terasology.engine.world.internal.WorldProviderCoreImpl;
import org.terasology.engine.world.internal.WorldProviderWrapper;
import org.terasology.engine.world.sun.BasicCelestialModel;
import org.terasology.engine.world.sun.CelestialModel;
import org.terasology.engine.world.sun.CelestialSystem;
import org.terasology.engine.world.sun.DefaultCelestialSystem;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.exceptions.UnresolvedDependencyException;
import java.io.IOException;
import javax.inject.Inject;
import java.nio.file.Path;
import static com.google.common.base.Verify.verify;
@ -68,10 +63,12 @@ public class InitialiseWorld extends SingleStepLoadProcess {
private final GameManifest gameManifest;
private final Context context;
private final ServiceRegistry serviceRegistry;
public InitialiseWorld(GameManifest gameManifest, Context context) {
public InitialiseWorld(GameManifest gameManifest, Context context, ServiceRegistry serviceRegistry) {
this.gameManifest = gameManifest;
this.context = context;
this.serviceRegistry = serviceRegistry;
}
@Override
@ -79,13 +76,22 @@ public String getMessage() {
return "Initializing world...";
}
/**
* This work-around exists because you cannot easily have two instances of {@link WorldProviderCore} in the context at a given time.
* One of these instances exists purely to wrap the other, so we instantiate both at the same time here to leave only one instance.
*/
public static final class WorldProviderCoreWorkAround extends EntityAwareWorldProvider
implements WorldProviderCore, BlockEntityRegistry {
@Inject
public WorldProviderCoreWorkAround(WorldInfo info, ChunkProvider chunkProvider, BlockManager blockManager,
EntityManager entityManager, ComponentSystemManager componentSystemManager) {
super(new WorldProviderCoreImpl(info, chunkProvider, blockManager, entityManager), entityManager, componentSystemManager);
}
}
@Override
public boolean step() {
BlockManager blockManager = context.get(BlockManager.class);
ExtraBlockDataManager extraDataManager = context.get(ExtraBlockDataManager.class);
ModuleEnvironment environment = context.get(ModuleManager.class).getEnvironment();
context.put(WorldGeneratorPluginLibrary.class, new DefaultWorldGeneratorPluginLibrary(environment, context));
serviceRegistry.with(WorldGeneratorPluginLibrary.class).lifetime(Lifetime.Singleton).use(DefaultWorldGeneratorPluginLibrary.class);
WorldInfo worldInfo = verifyNotNull(gameManifest.getWorldInfo(TerasologyConstants.MAIN_WORLD),
"Game manifest does not contain a MAIN_WORLD");
@ -95,6 +101,8 @@ public boolean step() {
worldInfo.setSeed(random.nextString(16));
}
serviceRegistry.with(WorldInfo.class).lifetime(Lifetime.Singleton).use(() -> worldInfo);
logger.info("World seed: \"{}\"", worldInfo.getSeed()); //NOPMD
// TODO: Separate WorldRenderer from world handling in general
@ -102,9 +110,10 @@ public boolean step() {
WorldGenerator worldGenerator;
try {
worldGenerator = WorldGeneratorManager.createGenerator(worldInfo.getWorldGenerator(), context);
// setting the world seed will create the world builder
worldGenerator.setWorldSeed(worldInfo.getSeed());
context.put(WorldGenerator.class, worldGenerator);
serviceRegistry.with(WorldGenerator.class).lifetime(Lifetime.Singleton).use(() -> worldGenerator);
if (worldGenerator instanceof ScalableWorldGenerator) {
serviceRegistry.with(ScalableWorldGenerator.class).lifetime(Lifetime.Singleton).use(() -> (ScalableWorldGenerator) worldGenerator);
}
} catch (UnresolvedWorldGeneratorException | UnresolvedDependencyException e) {
logger.atError().log("Unable to load world generator {}. Available world generators: {}",
worldInfo.getWorldGenerator(), worldGeneratorManager.getWorldGenerators());
@ -113,65 +122,30 @@ public boolean step() {
}
// Init. a new world
EngineEntityManager entityManager = (EngineEntityManager) context.get(EntityManager.class);
boolean writeSaveGamesEnabled = context.get(SystemConfig.class).writeSaveGamesEnabled.get();
//Gets save data from a normal save or from a recording if it is a replay
Path saveOrRecordingPath = getSaveOrRecordingPath();
StorageManager storageManager;
RecordAndReplaySerializer recordAndReplaySerializer = context.get(RecordAndReplaySerializer.class);
RecordAndReplayUtils recordAndReplayUtils = context.get(RecordAndReplayUtils.class);
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus = context.get(RecordAndReplayCurrentStatus.class);
try {
storageManager = writeSaveGamesEnabled
? new ReadWriteStorageManager(saveOrRecordingPath, environment, entityManager, blockManager,
extraDataManager, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus)
: new ReadOnlyStorageManager(saveOrRecordingPath, environment, entityManager, blockManager,
extraDataManager);
} catch (IOException e) {
logger.error("Unable to create storage manager!", e);
context.get(GameEngine.class).changeState(new StateMainMenu("Unable to create storage manager!"));
return true; // We need to return true, otherwise the loading state will just call us again immediately
}
context.put(StorageManager.class, storageManager);
LocalChunkProvider chunkProvider = new LocalChunkProvider(storageManager,
entityManager,
worldGenerator,
blockManager,
extraDataManager,
context.get(Config.class),
Maps.newConcurrentMap());
RelevanceSystem relevanceSystem = new RelevanceSystem(chunkProvider);
context.put(RelevanceSystem.class, relevanceSystem);
context.get(ComponentSystemManager.class).register(relevanceSystem, "engine:relevanceSystem");
chunkProvider.setRelevanceSystem(relevanceSystem);
Block unloadedBlock = blockManager.getBlock(BlockManager.UNLOADED_ID);
WorldProviderCoreImpl worldProviderCore = new WorldProviderCoreImpl(worldInfo, chunkProvider, unloadedBlock,
context);
EntityAwareWorldProvider entityWorldProvider = new EntityAwareWorldProvider(worldProviderCore, context);
WorldProvider worldProvider = new WorldProviderWrapper(entityWorldProvider, extraDataManager);
context.put(WorldProvider.class, worldProvider);
chunkProvider.setBlockEntityRegistry(entityWorldProvider);
context.put(BlockEntityRegistry.class, entityWorldProvider);
context.get(ComponentSystemManager.class).register(entityWorldProvider, "engine:BlockEntityRegistry");
serviceRegistry.with(StorageManager.class).lifetime(Lifetime.Singleton)
.use(writeSaveGamesEnabled ? ReadWriteStorageManager.class : ReadOnlyStorageManager.class);
serviceRegistry.with(ChunkProvider.class).lifetime(Lifetime.Singleton).use(LocalChunkProvider.class);
serviceRegistry.with(RelevanceSystem.class).lifetime(Lifetime.Singleton).use(RelevanceSystem.class);
// Provides both WorldProviderCore and BlockEntityRegistry
serviceRegistry.with(WorldProviderCoreWorkAround.class).lifetime(Lifetime.Singleton);
serviceRegistry.with(WorldProvider.class).lifetime(Lifetime.Singleton).use(WorldProviderWrapper.class);
DefaultCelestialSystem celestialSystem = new DefaultCelestialSystem(new BasicCelestialModel(), context);
context.put(CelestialSystem.class, celestialSystem);
context.get(ComponentSystemManager.class).register(celestialSystem);
serviceRegistry.with(CelestialModel.class).lifetime(Lifetime.Singleton).use(BasicCelestialModel.class);
serviceRegistry.with(CelestialSystem.class).lifetime(Lifetime.Singleton).use(DefaultCelestialSystem.class);
Skysphere skysphere = new Skysphere(context);
BackdropProvider backdropProvider = skysphere;
context.put(BackdropProvider.class, backdropProvider);
serviceRegistry.with(BackdropProvider.class).lifetime(Lifetime.Singleton).use(Skysphere.class);
RenderingSubsystemFactory engineSubsystemFactory = context.get(RenderingSubsystemFactory.class);
WorldRenderer worldRenderer = engineSubsystemFactory.createWorldRenderer(context);
context.put(WorldRenderer.class, worldRenderer);
engineSubsystemFactory.registerWorldRenderer(context, serviceRegistry);
// TODO: These shouldn't be done here, nor so strongly tied to the world renderer
LocalPlayer localPlayer = new LocalPlayer();
localPlayer.setRecordAndReplayClasses(context.get(DirectionAndOriginPosRecorderList.class),
context.get(RecordAndReplayCurrentStatus.class));
context.put(LocalPlayer.class, localPlayer);
context.put(Camera.class, worldRenderer.getActiveCamera());
serviceRegistry.with(LocalPlayer.class).lifetime(Lifetime.Singleton).use(() -> localPlayer);
// Camera activeCamera = worldRenderer.getActiveCamera();
// serviceRegistry.with(Camera.class).lifetime(Lifetime.Singleton).use(() -> activeCamera);
return true;
}

View file

@ -8,6 +8,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.bootstrap.EnvironmentSwitchHandler;
import org.terasology.engine.core.modes.StateMainMenu;
@ -19,7 +20,10 @@
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.network.Server;
import org.terasology.engine.network.ServerInfoMessage;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.world.internal.WorldInfo;
import org.terasology.gestalt.di.BeanContext;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.naming.NameVersion;
@ -111,12 +115,18 @@ public boolean step() {
}
oldEnvironment = moduleManager.getEnvironment();
moduleManager.loadEnvironment(moduleSet, true);
moduleManager.loadEnvironment(context, moduleSet, true);
context.get(Game.class).load(gameManifest);
EnvironmentSwitchHandler environmentSwitchHandler = context.get(EnvironmentSwitchHandler.class);
applyModuleThread = new Thread(() -> environmentSwitchHandler.handleSwitchToGameEnvironment(context));
ContextImpl modulesContext = new ContextImpl(context, moduleManager.getEnvironment().getBeans(BeanContext.class).stream().findFirst().get());
ServiceRegistry gameContextRegistry = new ServiceRegistry();
applyModuleThread = new Thread(() -> {
environmentSwitchHandler.handleSwitchToGameEnvironment(modulesContext, gameContextRegistry);
Context gameContext = new ContextImpl(modulesContext, gameContextRegistry);
CoreRegistry.setContext(gameContext);
});
applyModuleThread.start();
return false;

View file

@ -3,19 +3,20 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.world.chunks.blockdata.ExtraBlockDataManager;
import org.terasology.gestalt.di.ServiceRegistry;
/**
* Sets up an ExtraBlockDataManager based on @ExtraBlockSystem classes from the loaded modules.
* Depends on block definitions and module classes already being loaded.
*/
public class LoadExtraBlockData extends SingleStepLoadProcess {
private final Context context;
private final ServiceRegistry serviceRegistry;
public LoadExtraBlockData(Context context) {
this.context = context;
public LoadExtraBlockData(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
@Override
@ -25,7 +26,7 @@ public String getMessage() {
@Override
public boolean step() {
context.put(ExtraBlockDataManager.class, new ExtraBlockDataManager(context));
serviceRegistry.with(ExtraBlockDataManager.class).lifetime(Lifetime.Singleton).use(ExtraBlockDataManager.class);
return true;
}

View file

@ -3,11 +3,10 @@
package org.terasology.engine.core.modes.loadProcesses;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.Config;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.persistence.typeHandling.extensionTypes.BlockFamilyTypeHandler;
import org.terasology.engine.persistence.typeHandling.extensionTypes.BlockTypeHandler;
@ -19,16 +18,16 @@
import org.terasology.engine.world.block.tiles.WorldAtlas;
import org.terasology.engine.world.block.tiles.WorldAtlasImpl;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
public class RegisterBlocks extends SingleStepLoadProcess {
private final Context context;
private final GameManifest gameManifest;
private final ServiceRegistry serviceRegistry;
public RegisterBlocks(Context context, GameManifest gameManifest) {
public RegisterBlocks(Context context, ServiceRegistry serviceRegistry) {
this.context = context;
this.gameManifest = gameManifest;
this.serviceRegistry = serviceRegistry;
}
@Override
@ -40,11 +39,9 @@ public String getMessage() {
public boolean step() {
NetworkSystem networkSystem = context.get(NetworkSystem.class);
WorldAtlas atlas = new WorldAtlasImpl(context.get(Config.class).getRendering().getMaxTextureAtlasResolution());
context.put(WorldAtlas.class, atlas);
ModuleEnvironment environment = context.get(ModuleManager.class).getEnvironment();
context.put(BlockFamilyLibrary.class, new BlockFamilyLibrary(environment, context));
serviceRegistry.with(WorldAtlas.class).lifetime(Lifetime.Singleton).use(() -> atlas);
serviceRegistry.with(BlockFamilyLibrary.class).lifetime(Lifetime.Singleton).use(BlockFamilyLibrary.class);
BlockManagerImpl blockManager;
if (networkSystem.getMode().isAuthority()) {
@ -53,12 +50,9 @@ public boolean step() {
} else {
blockManager = new BlockManagerImpl(atlas, context.get(AssetManager.class), false);
}
context.put(BlockManager.class, blockManager);
serviceRegistry.with(BlockManager.class).lifetime(Lifetime.Singleton).use(() -> blockManager);
context.get(TypeHandlerLibrary.class).addTypeHandler(Block.class, new BlockTypeHandler(blockManager));
context.get(TypeHandlerLibrary.class).addTypeHandler(BlockFamily.class, new BlockFamilyTypeHandler(blockManager));
blockManager.initialise(gameManifest.getRegisteredBlockFamilies(), gameManifest.getBlockIdMap());
return true;
}

View file

@ -12,6 +12,7 @@
import org.terasology.engine.core.modes.StateMainMenu;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.game.GameManifest;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.dependencyresolution.DependencyResolver;
@ -28,12 +29,14 @@ public class RegisterMods extends SingleStepLoadProcess {
private static final Logger logger = LoggerFactory.getLogger(RegisterMods.class);
private final Context context;
private final ServiceRegistry serviceRegistry;
private final GameManifest gameManifest;
private Thread applyModulesThread;
private ModuleEnvironment oldEnvironment;
public RegisterMods(Context context, GameManifest gameManifest) {
public RegisterMods(Context context, ServiceRegistry serviceRegistry, GameManifest gameManifest) {
this.context = context;
this.serviceRegistry = serviceRegistry;
this.gameManifest = gameManifest;
}
@ -65,14 +68,14 @@ public boolean step() {
ResolutionResult result = resolver.resolve(moduleIds);
if (result.isSuccess()) {
oldEnvironment = moduleManager.getEnvironment();
ModuleEnvironment env = moduleManager.loadEnvironment(result.getModules(), true);
ModuleEnvironment env = moduleManager.loadEnvironment(context, result.getModules(), true);
for (Module moduleInfo : env.getModulesOrderedByDependencies()) {
logger.atInfo().log("Activating module: {}:{}", moduleInfo.getId(), moduleInfo.getVersion());
}
EnvironmentSwitchHandler environmentSwitchHandler = context.get(EnvironmentSwitchHandler.class);
applyModulesThread = new Thread(() -> environmentSwitchHandler.handleSwitchToGameEnvironment(context));
applyModulesThread = new Thread(() -> environmentSwitchHandler.handleSwitchToGameEnvironment(context, serviceRegistry));
applyModulesThread.start();
return false;
} else {

View file

@ -0,0 +1,57 @@
// Copyright 2024 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.ComponentSystemManager;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.entitySystem.systems.ComponentSystem;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.registry.InjectionHelper;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.engine.world.chunks.remoteChunkProvider.RemoteChunkProvider;
import org.terasology.engine.world.generator.WorldGenerator;
import org.terasology.engine.world.sun.CelestialSystem;
public class RegisterRemoteWorldSystems extends SingleStepLoadProcess {
private final Context context;
private final GameManifest gameManifest;
public RegisterRemoteWorldSystems(GameManifest gameManifest, Context context) {
this.context = context;
this.gameManifest = gameManifest;
}
@Override
public String getMessage() {
return "Registering World Systems...";
}
@Override
public boolean step() {
// WorldGenerator worldGenerator = context.get(WorldGenerator.class);
// InjectionHelper.inject(worldGenerator, context);
// // setting the world seed will create the world builder
// worldGenerator.setWorldSeed(gameManifest.getSeed());
context.get(NetworkSystem.class).setRemoteWorldProvider(context.get(RemoteChunkProvider.class));
ComponentSystemManager componentSystemManager = context.get(ComponentSystemManager.class);
componentSystemManager.register((ComponentSystem) context.get(BlockEntityRegistry.class), "engine:BlockEntityRegistry");
componentSystemManager.register((ComponentSystem) context.get(CelestialSystem.class));
WorldRenderer worldRenderer = context.get(WorldRenderer.class);
float reflectionHeight = context.get(NetworkSystem.class).getServer().getInfo().getReflectionHeight();
worldRenderer.getActiveCamera().setReflectionHeight(reflectionHeight);
worldRenderer.init();
return true;
}
@Override
public int getExpectedCost() {
return 1;
}
}

View file

@ -10,6 +10,9 @@
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.internal.PojoEntityManager;
import org.terasology.engine.entitySystem.prefab.PrefabManager;
import org.terasology.engine.network.NetworkMode;
public class RegisterSystems extends SingleStepLoadProcess {
@ -38,6 +41,8 @@ public boolean step() {
}
componentSystemManager.loadSystems(moduleManager.getEnvironment(), netMode);
((PojoEntityManager) context.get(EntityManager.class)).setPrefabManager(context.get(PrefabManager.class));
return true;
}

View file

@ -0,0 +1,57 @@
// Copyright 2024 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.ComponentSystemManager;
import org.terasology.engine.core.modes.SingleStepLoadProcess;
import org.terasology.engine.entitySystem.systems.ComponentSystem;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.registry.InjectionHelper;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.engine.world.chunks.ChunkProvider;
import org.terasology.engine.world.chunks.localChunkProvider.LocalChunkProvider;
import org.terasology.engine.world.chunks.localChunkProvider.RelevanceSystem;
import org.terasology.engine.world.generator.WorldGenerator;
import org.terasology.engine.world.internal.EntityAwareWorldProvider;
import org.terasology.engine.world.sun.CelestialSystem;
public class RegisterWorldSystems extends SingleStepLoadProcess {
private final Context context;
private final GameManifest gameManifest;
public RegisterWorldSystems(GameManifest gameManifest, Context context) {
this.context = context;
this.gameManifest = gameManifest;
}
@Override
public String getMessage() {
return "Registering World Systems...";
}
@Override
public boolean step() {
WorldGenerator worldGenerator = context.get(WorldGenerator.class);
InjectionHelper.inject(worldGenerator, context);
// setting the world seed will create the world builder
worldGenerator.setWorldSeed(gameManifest.getSeed());
ComponentSystemManager componentSystemManager = context.get(ComponentSystemManager.class);
context.get(ComponentSystemManager.class).register(context.get(RelevanceSystem.class), "engine:relevanceSystem");
componentSystemManager.register((ComponentSystem) context.get(BlockEntityRegistry.class), "engine:BlockEntityRegistry");
componentSystemManager.register((ComponentSystem) context.get(CelestialSystem.class));
((LocalChunkProvider) context.get(ChunkProvider.class)).setRelevanceSystem(context.get(RelevanceSystem.class));
context.get(LocalChunkProvider.class).setBlockEntityRegistry(context.get(EntityAwareWorldProvider.class));
context.get(WorldRenderer.class).init();
return true;
}
@Override
public int getExpectedCost() {
return 1;
}
}

View file

@ -12,10 +12,11 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.context.internal.ContextImpl;
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.utilities.Jvm;
import org.terasology.gestalt.di.DefaultBeanContext;
import org.terasology.gestalt.di.index.CompoundClassIndex;
import org.terasology.gestalt.di.index.UrlClassIndex;
import org.terasology.gestalt.module.Module;
@ -357,7 +358,15 @@ public void resolveAndLoadEnvironment(Name... modules) {
resolveAndLoadEnvironment(Arrays.asList(modules));
}
public void resolveAndLoadEnvironment(Context context, Name... modules) {
resolveAndLoadEnvironment(context, Arrays.asList(modules));
}
public void resolveAndLoadEnvironment(Iterable<Name> modules) {
resolveAndLoadEnvironment(new ContextImpl(), modules);
}
public void resolveAndLoadEnvironment(Context context, Iterable<Name> modules) {
DependencyResolver resolver = new DependencyResolver(registry);
ResolutionResult result = resolver.resolve(modules);
@ -366,18 +375,22 @@ public void resolveAndLoadEnvironment(Iterable<Name> modules) {
throw new RuntimeException("Failed to resolve dependencies for " + modules);
}
loadEnvironment(result.getModules(), true);
loadEnvironment(context, result.getModules(), true);
}
public ModuleEnvironment loadEnvironment(Set<Module> modules, boolean asPrimary) {
return loadEnvironment(new ContextImpl(), modules, asPrimary);
}
public ModuleEnvironment loadEnvironment(Context context, Set<Module> modules, boolean asPrimary) {
Set<Module> finalModules = Sets.newLinkedHashSet(modules);
finalModules.add(engineModule);
ModuleEnvironment newEnvironment;
boolean permissiveSecurityEnabled = Boolean.parseBoolean(System.getProperty(SystemConfig.PERMISSIVE_SECURITY_ENABLED_PROPERTY));
if (permissiveSecurityEnabled) {
newEnvironment = new ModuleEnvironment(new DefaultBeanContext(), finalModules, wrappingPermissionProviderFactory);
newEnvironment = new ModuleEnvironment(((ContextImpl) context).getBeanContext(), finalModules, wrappingPermissionProviderFactory);
} else {
newEnvironment = new ModuleEnvironment(new DefaultBeanContext(), finalModules, permissionProviderFactory);
newEnvironment = new ModuleEnvironment(((ContextImpl) context).getBeanContext(), finalModules, permissionProviderFactory);
}
if (asPrimary) {
environment = newEnvironment;

View file

@ -8,6 +8,7 @@
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.GameState;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
@IndexInherited
public interface EngineSubsystem {
@ -19,21 +20,21 @@ public interface EngineSubsystem {
/**
* Called on each system before initialisation.
* This is an opportunity to add anything into the root context that will carry across the entire rune of the engine,
* and may be used by other systems
* This is an opportunity to add anything into the root context that will carry across the entire run of the engine,
* and may be used by other systems.
*
* @param rootContext The root context, that will survive the entire run of the engine
* @param serviceRegistry the service registry used to create the root context that will carry across the entire run of the engine.
*/
default void preInitialise(Context rootContext) {
default void preInitialise(ServiceRegistry serviceRegistry) {
}
/**
* Called to initialise the system
*
* @param engine The game engine
* @param rootContext The root context, that will survive the entire run of the engine
* @param serviceRegistry The service registry used to create the context that will carry across the entire run of the engine.
*/
default void initialise(GameEngine engine, Context rootContext) {
default void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
}
/**

View file

@ -3,11 +3,9 @@
package org.terasology.engine.core.subsystem;
import org.terasology.engine.context.Context;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.gestalt.di.ServiceRegistry;
@FunctionalInterface
public interface RenderingSubsystemFactory {
WorldRenderer createWorldRenderer(Context context);
void registerWorldRenderer(Context context, ServiceRegistry serviceRegistry);
}

View file

@ -2,20 +2,29 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.logic.console.commandSystem.adapter.ParameterAdapterManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class CommandSubsystem implements EngineSubsystem {
@Inject
public CommandSubsystem() {
}
@Override
public String getName() {
return "Command";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.put(ParameterAdapterManager.class, ParameterAdapterManager.createCore());
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
ParameterAdapterManager parameterAdapterManager = ParameterAdapterManager.createCore();
serviceRegistry.with(ParameterAdapterManager.class).lifetime(Lifetime.Singleton).use(() -> parameterAdapterManager);
}
}

View file

@ -3,33 +3,29 @@
package org.terasology.engine.core.subsystem.common;
import com.google.common.collect.Iterables;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.facade.BindsConfiguration;
import org.terasology.engine.config.facade.BindsConfigurationImpl;
import org.terasology.engine.config.facade.InputDeviceConfiguration;
import org.terasology.engine.config.facade.InputDeviceConfigurationImpl;
import org.terasology.engine.config.flexible.AutoConfigManager;
import org.terasology.engine.config.flexible.AutoConfigTypeHandlerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.i18n.TranslationSystem;
import org.terasology.engine.identity.CertificateGenerator;
import org.terasology.engine.identity.CertificatePair;
import org.terasology.engine.identity.PrivateIdentityCertificate;
import org.terasology.engine.identity.PublicIdentityCertificate;
import org.terasology.engine.identity.storageServiceClient.StorageServiceWorker;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedData;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataReader;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataSerializer;
import org.terasology.engine.persistence.typeHandling.gson.GsonPersistedDataWriter;
import org.terasology.persistence.serializers.Serializer;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import javax.inject.Inject;
/**
* The configuration subsystem manages Terasology's configuration
*/
@ -37,8 +33,18 @@ public class ConfigurationSubsystem implements EngineSubsystem {
public static final String SERVER_PORT_PROPERTY = "org.terasology.serverPort";
private static final Logger logger = LoggerFactory.getLogger(ConfigurationSubsystem.class);
@Inject
protected TypeHandlerLibrary typeHandlerLibrary;
@Inject
protected TranslationSystem translationSystem;
@Inject
protected AutoConfigManager autoConfigManager;
private Config config;
private AutoConfigManager autoConfigManager;
@Inject
public ConfigurationSubsystem() {
}
@Override
public String getName() {
@ -46,8 +52,8 @@ public String getName() {
}
@Override
public void preInitialise(Context rootContext) {
config = new Config(rootContext);
public void preInitialise(ServiceRegistry serviceRegistry) {
config = new Config();
config.load();
String serverPortProperty = System.getProperty(SERVER_PORT_PROPERTY);
@ -68,36 +74,17 @@ public void preInitialise(Context rootContext) {
// TODO: Move to display subsystem
logger.info("Video Settings: {}", config.renderConfigAsJson(config.getRendering())); //NOPMD
rootContext.put(Config.class, config);
serviceRegistry.with(Config.class).lifetime(Lifetime.Singleton).use(() -> config);
//add facades
rootContext.put(InputDeviceConfiguration.class, new InputDeviceConfigurationImpl(config));
rootContext.put(BindsConfiguration.class, new BindsConfigurationImpl(config));
serviceRegistry.with(InputDeviceConfiguration.class).lifetime(Lifetime.Singleton).use(() -> new InputDeviceConfigurationImpl(config));
serviceRegistry.with(BindsConfiguration.class).lifetime(Lifetime.Singleton).use(() -> new BindsConfigurationImpl(config));
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
// TODO: Put here because of TypeHandlerLibrary dependency,
// might need to move to preInitialise or elsewhere
TypeHandlerLibrary typeHandlerLibrary = rootContext.get(TypeHandlerLibrary.class);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Serializer<GsonPersistedData> serializer = new Serializer<>(
typeHandlerLibrary,
new GsonPersistedDataSerializer(),
new GsonPersistedDataWriter(gson),
new GsonPersistedDataReader(gson)
);
autoConfigManager = new AutoConfigManager(serializer);
typeHandlerLibrary.addTypeHandlerFactory(new AutoConfigTypeHandlerFactory(typeHandlerLibrary));
rootContext.put(AutoConfigManager.class, autoConfigManager);
autoConfigManager.loadConfigsIn(rootContext);
}
@Override
public void postInitialise(Context rootContext) {
StorageServiceWorker storageServiceWorker = new StorageServiceWorker(rootContext);
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
StorageServiceWorker storageServiceWorker = new StorageServiceWorker(config, translationSystem);
storageServiceWorker.initializeFromConfig();
rootContext.put(StorageServiceWorker.class, storageServiceWorker);
serviceRegistry.with(StorageServiceWorker.class).lifetime(Lifetime.Singleton).use(() -> storageServiceWorker);
}
private void checkServerIdentity() {
@ -132,4 +119,7 @@ public void shutdown() {
autoConfigManager.saveConfigsToDisk();
}
public Config getConfig() {
return config;
}
}

View file

@ -2,21 +2,29 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.game.Game;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
// TODO: Get rid of this subsystem, it is kind of silly (remove Game class, convert to entity?)
public class GameSubsystem implements EngineSubsystem {
@Inject
public GameSubsystem() {
}
@Override
public String getName() {
return "Game";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.put(Game.class, new Game());
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
Game game = new Game();
serviceRegistry.with(Game.class).lifetime(Lifetime.Singleton).use(() -> game);
}
}

View file

@ -15,11 +15,12 @@
import io.micrometer.jmx.JmxMeterRegistry;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.monitoring.gui.AdvancedMonitor;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
import java.time.Duration;
public class MonitoringSubsystem implements EngineSubsystem {
@ -28,17 +29,26 @@ public class MonitoringSubsystem implements EngineSubsystem {
private AdvancedMonitor advancedMonitor;
@Inject
protected SystemConfig systemConfig;
@Inject
protected Time time;
@Inject
public MonitoringSubsystem() {
}
@Override
public String getName() {
return "Monitoring";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
if (rootContext.get(SystemConfig.class).monitoringEnabled.get()) {
public void postInitialise(Context context) {
if (systemConfig.monitoringEnabled.get()) {
advancedMonitor = new AdvancedMonitor();
advancedMonitor.setVisible(true);
initMicrometerMetrics(rootContext.get(Time.class));
initMicrometerMetrics(time);
}
}

View file

@ -2,35 +2,39 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.engine.network.internal.NetworkSystemImpl;
import org.terasology.engine.network.internal.ServerConnectListManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class NetworkSubsystem implements EngineSubsystem {
private NetworkSystem networkSystem;
@Inject
public NetworkSubsystem() {
}
@Override
public String getName() {
return "Network";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
networkSystem = new NetworkSystemImpl((EngineTime) rootContext.get(Time.class), rootContext);
rootContext.put(NetworkSystem.class, networkSystem);
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
serviceRegistry.with(NetworkSystem.class).lifetime(Lifetime.Singleton).use(NetworkSystemImpl.class);
}
@Override
public void postInitialise(Context rootContext) {
rootContext.put(ServerConnectListManager.class, new ServerConnectListManager(rootContext));
networkSystem = rootContext.get(NetworkSystem.class);
}
@Override

View file

@ -2,20 +2,28 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.physics.CollisionGroupManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class PhysicsSubsystem implements EngineSubsystem {
@Inject
public PhysicsSubsystem() {
}
@Override
public String getName() {
return "Physics";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.put(CollisionGroupManager.class, new CollisionGroupManager());
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
CollisionGroupManager collisionGroupManager = new CollisionGroupManager();
serviceRegistry.with(CollisionGroupManager.class).lifetime(Lifetime.Singleton).use(() -> collisionGroupManager);
}
}

View file

@ -6,6 +6,7 @@
import com.snowplowanalytics.snowplow.tracker.emitter.Emitter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.TelemetryConfig;
import org.terasology.engine.config.facade.TelemetryConfiguration;
@ -15,7 +16,9 @@
import org.terasology.engine.telemetry.Metrics;
import org.terasology.engine.telemetry.TelemetryEmitter;
import org.terasology.engine.telemetry.logstash.TelemetryLogstashAppender;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
import java.net.MalformedURLException;
import java.net.URL;
@ -40,21 +43,25 @@ public class TelemetrySubSystem implements EngineSubsystem {
private Emitter emitter;
@Inject
public TelemetrySubSystem() {
}
@Override
public String getName() {
return "Telemetry";
}
@Override
public void preInitialise(Context rootContext) {
public void preInitialise(ServiceRegistry serviceRegistry) {
// Add metrics to context, this helps show metric values in ui
metrics = new Metrics();
rootContext.put(Metrics.class, metrics);
serviceRegistry.with(Metrics.class).lifetime(Lifetime.Singleton).use(() -> metrics);
// Add snowplow emitter to context, contributors can use this emitter to emit other event
emitter = TelemetryEmitter.builder().build();
rootContext.put(Emitter.class, emitter);
serviceRegistry.with(Emitter.class).lifetime(Lifetime.Singleton).use(() -> emitter);
}
@Override

View file

@ -2,20 +2,32 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.common;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.world.generator.internal.WorldGeneratorManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class WorldGenerationSubsystem implements EngineSubsystem {
@Inject
protected ModuleManager moduleManager;
@Inject
public WorldGenerationSubsystem() {
}
@Override
public String getName() {
return "World Generation";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.put(WorldGeneratorManager.class, new WorldGeneratorManager(rootContext));
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
WorldGeneratorManager worldGeneratorManager = new WorldGeneratorManager(moduleManager);
serviceRegistry.with(WorldGeneratorManager.class).lifetime(Lifetime.Singleton).use(() -> worldGeneratorManager);
}
}

View file

@ -4,10 +4,14 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.subsystem.DisplayDevice;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class HibernationSubsystem implements EngineSubsystem {
@ -15,15 +19,19 @@ public class HibernationSubsystem implements EngineSubsystem {
private HibernationManager hibernationManager;
private DisplayDevice displayDevice;
@Inject
public HibernationSubsystem() {
}
@Override
public String getName() {
return "Hibernation";
}
@Override
public void preInitialise(Context rootContext) {
public void preInitialise(ServiceRegistry serviceRegistry) {
hibernationManager = new HibernationManager();
rootContext.put(HibernationManager.class, hibernationManager);
serviceRegistry.with(HibernationManager.class).lifetime(Lifetime.Singleton).use(() -> hibernationManager);
}
@Override

View file

@ -6,10 +6,10 @@
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.BindsConfig;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.facade.BindsConfiguration;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.SimpleUri;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.engine.core.subsystem.EngineSubsystem;
@ -27,6 +27,7 @@
import org.terasology.engine.input.internal.BindableAxisImpl;
import org.terasology.engine.input.internal.BindableButtonImpl;
import org.terasology.engine.input.internal.BindableRealAxis;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.dependencyresolution.DependencyResolver;
import org.terasology.gestalt.module.dependencyresolution.ResolutionResult;
@ -37,21 +38,27 @@
import org.terasology.input.InputType;
import org.terasology.input.MouseInput;
import javax.inject.Inject;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static java.util.Collections.unmodifiableCollection;
public class BindsSubsystem implements EngineSubsystem, BindsManager {
private static final Logger logger = LoggerFactory.getLogger(BindsSubsystem.class);
private BindsConfiguration bindsConfiguration;
@Inject
protected BindsConfiguration bindsConfiguration;
private BindsConfiguration defaultBindsConfig = new BindsConfigAdapter(new BindsConfig());
private Map<SimpleUri, BindableButton> buttonLookup = Maps.newHashMap();
private List<BindableButton> buttonBinds = Lists.newArrayList();
private Context context;
@Inject
protected Optional<ModuleManager> moduleManager;
@Inject
protected Optional<Config> config;
private Map<String, BindableRealAxis> axisLookup = Maps.newHashMap();
private List<AbstractBindableAxis> axisBinds = Lists.newArrayList();
@ -63,6 +70,10 @@ public class BindsSubsystem implements EngineSubsystem, BindsManager {
private BindableButton mouseWheelUpBind;
private BindableButton mouseWheelDownBind;
@Inject
public BindsSubsystem() {
}
@Override
public BindableButton getMouseWheelUpBind() {
return mouseWheelUpBind;
@ -109,10 +120,8 @@ public List<BindableButton> getButtonBinds() {
}
@Override
public void preInitialise(Context passedContext) {
context = passedContext;
bindsConfiguration = passedContext.get(BindsConfiguration.class);
passedContext.put(BindsManager.class, this);
public void preInitialise(ServiceRegistry serviceRegistry) {
serviceRegistry.with(BindsManager.class).lifetime(Lifetime.Singleton).use(() -> this);
}
@Override
@ -127,18 +136,21 @@ public BindsConfig getDefaultBindsConfig() {
public void updateConfigWithDefaultBinds() {
//default bindings are overridden
defaultBindsConfig = new BindsConfigAdapter(new BindsConfig());
updateDefaultBinds(context, defaultBindsConfig);
updateDefaultBinds(defaultBindsConfig);
//actual bindings may be actualized
updateDefaultBinds(context, bindsConfiguration);
updateDefaultBinds(bindsConfiguration);
}
private void updateDefaultBinds(Context passedContext, BindsConfiguration config) {
ModuleManager moduleManager = passedContext.get(ModuleManager.class);
DependencyResolver resolver = new DependencyResolver(moduleManager.getRegistry());
for (Name moduleId : moduleManager.getRegistry().getModuleIds()) {
private void updateDefaultBinds(BindsConfiguration config) {
if (moduleManager.isEmpty()) {
return;
}
DependencyResolver resolver = new DependencyResolver(moduleManager.get().getRegistry());
for (Name moduleId : moduleManager.get().getRegistry().getModuleIds()) {
ResolutionResult result = resolver.resolve(moduleId);
if (result.isSuccess()) {
try (ModuleEnvironment environment = moduleManager.loadEnvironment(result.getModules(), false)) {
try (ModuleEnvironment environment = moduleManager.get().loadEnvironment(result.getModules(), false)) {
FromModule filter = new FromModule(environment, moduleId);
Iterable<Class<?>> buttons = environment.getTypesAnnotatedWith(RegisterBindButton.class, filter);
Iterable<Class<?>> axes = environment.getTypesAnnotatedWith(RegisterRealBindAxis.class, filter);
@ -195,12 +207,13 @@ private List<Input> fetchDefaultBindings(Class<?> event, BindsConfiguration conf
@Override
public void registerBinds() {
ModuleManager moduleManager = context.get(ModuleManager.class);
ModuleEnvironment environment = moduleManager.getEnvironment();
clearBinds();
registerButtonBinds(environment);
registerAxisBinds(environment);
registerRealAxisBinds(environment);
if (moduleManager.isPresent()) {
ModuleEnvironment environment = moduleManager.get().getEnvironment();
clearBinds();
registerButtonBinds(environment);
registerAxisBinds(environment);
registerRealAxisBinds(environment);
}
}
private void clearBinds() {
@ -382,7 +395,9 @@ public void shutdown() {
@Override
public void saveBindsConfig() {
//TODO replace with flexible config when binds are no longer saved in the Config.
context.get(Config.class).save();
if (config.isPresent()) {
config.get().save();
}
}
/**

View file

@ -2,28 +2,35 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.headless;
import org.terasology.context.Lifetime;
import org.terasology.engine.audio.AudioManager;
import org.terasology.engine.audio.StaticSound;
import org.terasology.engine.audio.StreamingSound;
import org.terasology.engine.audio.nullAudio.NullAudioManager;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class HeadlessAudio implements EngineSubsystem {
private AudioManager audioManager;
@Inject
public HeadlessAudio() {
}
@Override
public String getName() {
return "Audio";
}
@Override
public void initialise(GameEngine engine, Context context) {
initNoSound(context);
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
initNoSound(serviceRegistry);
}
@Override
@ -42,9 +49,9 @@ public void shutdown() {
audioManager.dispose();
}
private void initNoSound(Context context) {
private void initNoSound(ServiceRegistry serviceRegistry) {
audioManager = new NullAudioManager();
context.put(AudioManager.class, audioManager);
serviceRegistry.with(AudioManager.class).lifetime(Lifetime.Singleton).use(() -> audioManager);
}
}

View file

@ -2,7 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.headless;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.subsystem.DisplayDevice;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
@ -29,11 +30,19 @@
import org.terasology.engine.rendering.assets.texture.Texture;
import org.terasology.engine.rendering.assets.texture.TextureData;
import org.terasology.engine.rendering.assets.texture.subtexture.Subtexture;
import org.terasology.engine.rendering.nui.internal.TerasologyCanvasRenderer;
import org.terasology.gestalt.assets.AssetType;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.nui.canvas.CanvasRenderer;
import javax.inject.Inject;
public class HeadlessGraphics implements EngineSubsystem {
@Inject
public HeadlessGraphics() {
}
@Override
public String getName() {
@ -62,18 +71,22 @@ public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager)
}
@Override
public void postInitialise(Context context) {
context.put(RenderingSubsystemFactory.class, new HeadlessRenderingSubsystemFactory());
public void initialise(GameEngine gameEngine, ServiceRegistry serviceRegistry) {
HeadlessRenderingSubsystemFactory headlessRenderingSubsystemFactory = new HeadlessRenderingSubsystemFactory();
serviceRegistry.with(RenderingSubsystemFactory.class).lifetime(Lifetime.Singleton).use(() -> headlessRenderingSubsystemFactory);
HeadlessDisplayDevice headlessDisplay = new HeadlessDisplayDevice();
context.put(DisplayDevice.class, headlessDisplay);
initHeadless(context);
serviceRegistry.with(DisplayDevice.class).lifetime(Lifetime.Singleton).use(() -> headlessDisplay);
initHeadless(serviceRegistry);
context.put(CanvasRenderer.class, new HeadlessCanvasRenderer());
HeadlessCanvasRenderer headlessCanvasRenderer = new HeadlessCanvasRenderer();
serviceRegistry.with(CanvasRenderer.class).lifetime(Lifetime.Singleton).use(() -> headlessCanvasRenderer);
serviceRegistry.with(TerasologyCanvasRenderer.class).lifetime(Lifetime.Singleton).use(() -> headlessCanvasRenderer);
}
private void initHeadless(Context context) {
context.put(ShaderManager.class, new ShaderManagerHeadless());
private void initHeadless(ServiceRegistry serviceRegistry) {
ShaderManagerHeadless shaderManagerHeadless = new ShaderManagerHeadless();
serviceRegistry.with(ShaderManager.class).lifetime(Lifetime.Singleton).use(() -> shaderManagerHeadless);
}

View file

@ -5,7 +5,12 @@
import org.terasology.engine.context.Context;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import javax.inject.Inject;
public class HeadlessInput implements EngineSubsystem {
@Inject
public HeadlessInput() {
}
@Override
public String getName() {

View file

@ -2,29 +2,37 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.headless;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.subsystem.common.TimeSubsystem;
import org.terasology.engine.core.subsystem.headless.device.TimeSystem;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class HeadlessTimer implements TimeSubsystem {
private EngineTime time;
@Inject
public HeadlessTimer() {
}
@Override
public String getName() {
return "Time";
}
@Override
public void preInitialise(Context context) {
initTimer(context);
public void preInitialise(ServiceRegistry serviceRegistry) {
initTimer(serviceRegistry);
}
private void initTimer(Context context) {
private void initTimer(ServiceRegistry serviceRegistry) {
time = new TimeSystem();
context.put(Time.class, time);
serviceRegistry.with(Time.class).lifetime(Lifetime.Singleton).use(() -> time);
serviceRegistry.with(EngineTime.class).lifetime(Lifetime.Singleton).use(() -> time);
}
@Override

View file

@ -16,10 +16,12 @@
import org.terasology.engine.core.module.StandardModuleExtension;
import org.terasology.engine.game.GameManifest;
import org.terasology.engine.network.NetworkMode;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.nui.layers.mainMenu.savedGames.GameInfo;
import org.terasology.engine.rendering.nui.layers.mainMenu.savedGames.GameProvider;
import org.terasology.engine.world.internal.WorldInfo;
import org.terasology.engine.world.time.WorldTime;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.naming.Name;
@ -47,9 +49,16 @@ public StateHeadlessSetup(NetworkMode networkMode) {
@Override
public void init(GameEngine gameEngine) {
ServiceRegistry serviceRegistry = new ServiceRegistry();
context = gameEngine.createChildContext();
initEntityAndComponentManagers(true);
createLocalPlayer(context);
registerEntityAndComponentManagers(true, serviceRegistry);
registerLocalPlayer(serviceRegistry);
context = gameEngine.createChildContext(serviceRegistry);
initEntityAndComponentManagers();
CoreRegistry.setContext(context);
createLocalPlayer();
GameManifest gameManifest;
List<GameInfo> savedGames = GameProvider.getSavedGames();

View file

@ -2,16 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.headless.renderer;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.gestalt.di.ServiceRegistry;
public class HeadlessRenderingSubsystemFactory implements RenderingSubsystemFactory {
@Override
public WorldRenderer createWorldRenderer(Context context) {
return new HeadlessWorldRenderer(context);
public void registerWorldRenderer(Context context, ServiceRegistry serviceRegistry) {
serviceRegistry.with(WorldRenderer.class).lifetime(Lifetime.Singleton).use(HeadlessWorldRenderer.class);
}
}

View file

@ -21,6 +21,7 @@
import org.terasology.engine.world.chunks.Chunks;
import org.terasology.engine.world.chunks.RenderableChunk;
import javax.inject.Inject;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -43,10 +44,19 @@ public class HeadlessWorldRenderer implements WorldRenderer {
private Config config;
@Inject
public HeadlessWorldRenderer(WorldProvider worldProvider, ChunkProvider chunkProvider, Config config) {
this.worldProvider = worldProvider;
this.chunkProvider = chunkProvider;
this.config = config;
}
public HeadlessWorldRenderer(Context context) {
this.worldProvider = context.get(WorldProvider.class);
this.chunkProvider = context.get(ChunkProvider.class);
config = context.get(Config.class);
this(context.get(WorldProvider.class), context.get(ChunkProvider.class), context.get(Config.class));
}
@Override
public void init() {
}
@Override

View file

@ -6,8 +6,8 @@
import org.lwjgl.system.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.gestalt.di.ServiceRegistry;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
@ -19,7 +19,7 @@ public abstract class BaseLwjglSubsystem implements EngineSubsystem {
private static boolean initialised;
@Override
public void preInitialise(Context context) {
public void preInitialise(ServiceRegistry serviceRegistry) {
if (!initialised) {
initLogger();
initialised = true;

View file

@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.audio.AudioManager;
import org.terasology.engine.audio.StaticSound;
import org.terasology.engine.audio.StreamingSound;
@ -11,31 +12,40 @@
import org.terasology.engine.audio.openAL.OpenALException;
import org.terasology.engine.audio.openAL.OpenALManager;
import org.terasology.engine.config.AudioConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.GameState;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class LwjglAudio extends BaseLwjglSubsystem {
private static final Logger logger = LoggerFactory.getLogger(LwjglAudio.class);
@Inject
protected AudioConfig audioConfig;
private AudioManager audioManager;
@Inject
public LwjglAudio() {
}
@Override
public String getName() {
return "Audio";
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
try {
audioManager = new OpenALManager(rootContext.get(AudioConfig.class));
audioManager = new OpenALManager(audioConfig);
} catch (OpenALException e) {
logger.warn("Could not load OpenAL manager - sound is disabled", e);
audioManager = new NullAudioManager();
}
rootContext.put(AudioManager.class, audioManager);
serviceRegistry.with(AudioManager.class).lifetime(Lifetime.Singleton).use(() -> audioManager);
}
@Override

View file

@ -6,9 +6,7 @@
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.system.MemoryUtil;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.RenderingConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.subsystem.DisplayDevice;
import org.terasology.engine.core.subsystem.DisplayDeviceInfo;
import org.terasology.engine.core.subsystem.Resolution;
@ -40,8 +38,8 @@ public class LwjglDisplayDevice extends AbstractSubscribable implements DisplayD
private int windowHeight = 0;
private boolean isWindowDirty = true;
public LwjglDisplayDevice(Context context) {
this.config = context.get(Config.class).getRendering();
public LwjglDisplayDevice(RenderingConfig config) {
this.config = config;
}
@Override

View file

@ -9,27 +9,32 @@
import org.lwjgl.system.MemoryUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.RenderingConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.subsystem.DisplayDevice;
import org.terasology.engine.rendering.ShaderManager;
import org.terasology.engine.rendering.ShaderManagerLwjgl;
import org.terasology.engine.rendering.nui.internal.LwjglCanvasRenderer;
import org.terasology.engine.rendering.nui.internal.TerasologyCanvasRenderer;
import org.terasology.engine.utilities.OS;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import org.terasology.nui.canvas.CanvasRenderer;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class LwjglGraphics extends BaseLwjglSubsystem {
private static final Logger logger = LoggerFactory.getLogger(LwjglGraphics.class);
private Context context;
@Inject
protected Config rootConfig;
private RenderingConfig config;
private GameEngine engine;
@ -37,37 +42,40 @@ public class LwjglGraphics extends BaseLwjglSubsystem {
private LwjglGraphicsManager graphics = new LwjglGraphicsManager();
@Inject
public LwjglGraphics() {
}
@Override
public String getName() {
return "Graphics";
}
@Override
public void initialise(GameEngine gameEngine, Context rootContext) {
public void initialise(GameEngine gameEngine, ServiceRegistry serviceRegistry) {
logger.info("Starting initialization of LWJGL");
this.engine = gameEngine;
this.context = rootContext;
this.config = context.get(Config.class).getRendering();
lwjglDisplay = new LwjglDisplayDevice(context);
context.put(DisplayDevice.class, lwjglDisplay);
this.config = rootConfig.getRendering();
lwjglDisplay = new LwjglDisplayDevice(config);
serviceRegistry.with(DisplayDevice.class).lifetime(Lifetime.Singleton).use(() -> lwjglDisplay);
logger.info("Initial initialization complete");
}
@Override
public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager) {
graphics.registerCoreAssetTypes(assetTypeManager);
}
@Override
public void postInitialise(Context rootContext) {
graphics.registerRenderingSubsystem(context);
graphics.registerRenderingSubsystem(serviceRegistry);
initGLFW();
initWindow();
initOpenGL();
context.put(ShaderManager.class, new ShaderManagerLwjgl());
context.put(CanvasRenderer.class, new LwjglCanvasRenderer(context));
ShaderManagerLwjgl shaderManager = new ShaderManagerLwjgl();
serviceRegistry.with(ShaderManager.class).lifetime(Lifetime.Singleton).use(() -> shaderManager);
serviceRegistry.with(CanvasRenderer.class).lifetime(Lifetime.Singleton).use(LwjglCanvasRenderer.class);
serviceRegistry.with(TerasologyCanvasRenderer.class).lifetime(Lifetime.Singleton).use(LwjglCanvasRenderer.class);
logger.info("LWJGL renderer initialisation complete");
}
@Override
public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager) {
graphics.registerCoreAssetTypes(assetTypeManager);
}
@Override
@ -80,7 +88,7 @@ public void postUpdate(GameState currentState, float delta) {
}
lwjglDisplay.update();
int frameLimit = context.get(Config.class).getRendering().getFrameLimit();
int frameLimit = config.getFrameLimit();
if (frameLimit > 0) {
Lwjgl2Sync.sync(frameLimit);
}

View file

@ -6,7 +6,7 @@
import com.google.common.collect.Queues;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.GameThread;
import org.terasology.engine.core.subsystem.DisplayDeviceInfo;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
@ -32,6 +32,7 @@
import org.terasology.gestalt.assets.AssetType;
import org.terasology.gestalt.assets.module.ModuleAssetScanner;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import java.nio.ByteBuffer;
import java.util.List;
@ -98,8 +99,9 @@ public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager)
assetTypeManager.createAssetType(Subtexture.class, Subtexture::new);
}
public void registerRenderingSubsystem(Context context) {
context.put(RenderingSubsystemFactory.class, new LwjglRenderingSubsystemFactory());
public void registerRenderingSubsystem(ServiceRegistry serviceRegistry) {
LwjglRenderingSubsystemFactory renderingSubsystemFactory = new LwjglRenderingSubsystemFactory();
serviceRegistry.with(RenderingSubsystemFactory.class).lifetime(Lifetime.Singleton).use(() -> renderingSubsystemFactory);
}
public void processActions() {

View file

@ -3,9 +3,11 @@
package org.terasology.engine.core.subsystem.lwjgl;
import org.lwjgl.glfw.GLFW;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.Config;
import org.terasology.engine.config.ControllerConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.modes.GameState;
import org.terasology.engine.core.subsystem.config.BindsManager;
import org.terasology.engine.input.InputSystem;
@ -13,11 +15,18 @@
import org.terasology.engine.input.lwjgl.LwjglKeyboardDevice;
import org.terasology.engine.input.lwjgl.LwjglMouseDevice;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class LwjglInput extends BaseLwjglSubsystem {
private Context context;
@Inject
public LwjglInput() {
}
@Override
public String getName() {
return "Input";
@ -27,6 +36,12 @@ public String getName() {
public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager) {
}
@Override
public void initialise(GameEngine engine, ServiceRegistry serviceRegistry) {
InputSystem inputSystem = new InputSystem();
serviceRegistry.with(InputSystem.class).lifetime(Lifetime.Singleton).use(() -> inputSystem);
}
@Override
public void postInitialise(Context rootContext) {
this.context = rootContext;
@ -41,9 +56,8 @@ public void postUpdate(GameState currentState, float delta) {
private void initControls() {
Config config = context.get(Config.class);
InputSystem inputSystem = context.get(InputSystem.class);
InputSystem inputSystem = new InputSystem();
context.put(InputSystem.class, inputSystem);
inputSystem.setMouseDevice(new LwjglMouseDevice(config.getRendering()));
inputSystem.setKeyboardDevice(new LwjglKeyboardDevice());

View file

@ -2,20 +2,42 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.lwjgl;
import org.terasology.context.Lifetime;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.subsystem.RenderingSubsystemFactory;
import org.terasology.engine.rendering.cameras.Camera;
import org.terasology.engine.rendering.cameras.PerspectiveCamera;
import org.terasology.engine.rendering.dag.RenderGraph;
import org.terasology.engine.rendering.dag.RenderTaskListGenerator;
import org.terasology.engine.rendering.opengl.ScreenGrabber;
import org.terasology.engine.rendering.opengl.fbms.DisplayResolutionDependentFbo;
import org.terasology.engine.rendering.primitives.ChunkTessellator;
import org.terasology.engine.rendering.world.RenderableWorld;
import org.terasology.engine.rendering.world.RenderableWorldImpl;
import org.terasology.engine.rendering.world.WorldRenderer;
import org.terasology.engine.rendering.world.WorldRendererImpl;
import org.terasology.engine.world.chunks.LodChunkProvider;
import org.terasology.gestalt.di.ServiceRegistry;
public class LwjglRenderingSubsystemFactory implements RenderingSubsystemFactory {
public LwjglRenderingSubsystemFactory() {
}
@Override
public WorldRenderer createWorldRenderer(Context context) {
return new WorldRendererImpl(context);
public void registerWorldRenderer(Context context, ServiceRegistry serviceRegistry) {
ChunkTessellator chunkTessellator = new ChunkTessellator();
serviceRegistry.with(ChunkTessellator.class).lifetime(Lifetime.Singleton).use(() -> chunkTessellator);
serviceRegistry.with(RenderGraph.class).lifetime(Lifetime.Singleton).use(RenderGraph.class);
serviceRegistry.with(ScreenGrabber.class).lifetime(Lifetime.Singleton).use(ScreenGrabber.class);
serviceRegistry.with(DisplayResolutionDependentFbo.class).lifetime(Lifetime.Singleton).use(DisplayResolutionDependentFbo.class);
serviceRegistry.with(LodChunkProvider.class).lifetime(Lifetime.Singleton).use(LodChunkProvider.class);
serviceRegistry.with(RenderableWorld.class).lifetime(Lifetime.Singleton).use(RenderableWorldImpl.class);
RenderTaskListGenerator renderTaskListGenerator = new RenderTaskListGenerator();
serviceRegistry.with(RenderTaskListGenerator.class).lifetime(Lifetime.Singleton).use(() -> renderTaskListGenerator);
serviceRegistry.with(Camera.class).lifetime(Lifetime.Singleton).use(PerspectiveCamera.class);
serviceRegistry.with(WorldRenderer.class).lifetime(Lifetime.Singleton).use(WorldRendererImpl.class);
}
}

View file

@ -2,26 +2,34 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.engine.core.subsystem.lwjgl;
import org.terasology.engine.context.Context;
import org.terasology.context.Lifetime;
import org.terasology.engine.core.EngineTime;
import org.terasology.engine.core.Time;
import org.terasology.engine.core.internal.TimeLwjgl;
import org.terasology.engine.core.subsystem.common.TimeSubsystem;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
public class LwjglTimer extends BaseLwjglSubsystem implements TimeSubsystem {
private EngineTime time;
@Inject
public LwjglTimer() {
}
@Override
public String getName() {
return "Time";
}
@Override
public void preInitialise(Context context) {
super.preInitialise(context);
public void preInitialise(ServiceRegistry serviceRegistry) {
super.preInitialise(serviceRegistry);
time = new TimeLwjgl();
context.put(Time.class, time);
serviceRegistry.with(Time.class).lifetime(Lifetime.Singleton).use(() -> time);
serviceRegistry.with(EngineTime.class).lifetime(Lifetime.Singleton).use(() -> time);
}
@Override

View file

@ -17,6 +17,7 @@
import org.slf4j.LoggerFactory;
import org.terasology.engine.core.TerasologyConstants;
import org.terasology.engine.entitySystem.entity.EntityBuilder;
import org.terasology.engine.entitySystem.entity.EntityManager;
import org.terasology.engine.entitySystem.entity.EntityRef;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.BeforeDeactivateComponent;
import org.terasology.engine.entitySystem.entity.lifecycleEvents.BeforeRemoveComponent;
@ -25,6 +26,7 @@
import org.terasology.engine.entitySystem.entity.lifecycleEvents.OnChangedComponent;
import org.terasology.engine.entitySystem.event.internal.EventSystem;
import org.terasology.engine.entitySystem.metadata.ComponentLibrary;
import org.terasology.engine.entitySystem.metadata.EntitySystemLibrary;
import org.terasology.engine.entitySystem.prefab.Prefab;
import org.terasology.engine.entitySystem.prefab.PrefabManager;
import org.terasology.engine.entitySystem.sectors.SectorSimulationComponent;
@ -33,6 +35,7 @@
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -44,7 +47,7 @@
import static org.terasology.engine.entitySystem.entity.internal.EntityScope.SECTOR;
public class PojoEntityManager implements EngineEntityManager {
public class PojoEntityManager implements EntityManager, EngineEntityManager {
public static final long NULL_ID = 0;
private static final Logger logger = LoggerFactory.getLogger(PojoEntityManager.class);
@ -70,6 +73,20 @@ public class PojoEntityManager implements EngineEntityManager {
private TypeHandlerLibrary typeSerializerLibrary;
public PojoEntityManager() {
}
@Inject
public PojoEntityManager(Optional<PrefabManager> prefabManager, Optional<EventSystem> eventSystem,
Optional<EntitySystemLibrary> entitySystemLibrary, Optional<TypeHandlerLibrary> typeSerializerLibrary) {
this.prefabManager = prefabManager.orElse(null);
this.eventSystem = eventSystem.orElse(null);
if (entitySystemLibrary.isPresent()) {
this.componentLibrary = entitySystemLibrary.get().getComponentLibrary();
}
this.typeSerializerLibrary = typeSerializerLibrary.orElse(null);
}
@Override
public RefStrategy getEntityRefStrategy() {
return refStrategy;

View file

@ -27,12 +27,14 @@
import org.terasology.engine.entitySystem.systems.ComponentSystem;
import org.terasology.engine.entitySystem.systems.NetFilterEvent;
import org.terasology.engine.monitoring.PerformanceMonitor;
import org.terasology.engine.network.NetworkSystem;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.entitysystem.event.Event;
import org.terasology.gestalt.entitysystem.event.ReceiveEvent;
import javax.annotation.Nullable;
import javax.inject.Inject;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
@ -50,7 +52,7 @@
public class EventSystemImpl implements EventSystem {
private static final Logger logger = LoggerFactory.getLogger(EventSystemImpl.class);
private final boolean isAutority;
private final boolean isAuthority;
private Map<Class<? extends Event>, SetMultimap<Class<? extends Component>, EventHandlerInfo>> componentSpecificHandlers = Maps.newHashMap();
private SetMultimap<Class<? extends Event>, EventHandlerInfo> generalHandlers = HashMultimap.create();
@ -64,8 +66,13 @@ public class EventSystemImpl implements EventSystem {
private BlockingQueue<PendingEvent> pendingEvents = Queues.newLinkedBlockingQueue();
public EventSystemImpl(boolean isAutority) {
this.isAutority = isAutority;
@Inject
public EventSystemImpl(NetworkSystem networkSystem) {
this(networkSystem.getMode().isAuthority());
}
public EventSystemImpl(boolean isAuthority) {
this.isAuthority = isAuthority;
this.mainThread = Thread.currentThread();
}
@ -105,7 +112,7 @@ public void registerEventHandler(ComponentSystem handler) {
if (receiveEventAnnotation != null) {
NetFilterEvent netFilterAnnotation = method.getAnnotation(NetFilterEvent.class);
if (netFilterAnnotation != null && !netFilterAnnotation.netFilter().isValidFor(isAutority, false)) {
if (netFilterAnnotation != null && !netFilterAnnotation.netFilter().isValidFor(isAuthority, false)) {
continue;
}

View file

@ -5,6 +5,7 @@
import com.google.common.collect.Iterables;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.module.Module;
@ -16,6 +17,8 @@
import org.terasology.reflection.metadata.ModuleClassLibrary;
import org.terasology.reflection.reflect.ReflectFactory;
import javax.inject.Inject;
/**
* The library for metadata about components (and their fields).
*/
@ -23,6 +26,11 @@ public class ComponentLibrary extends ModuleClassLibrary<Component> {
private static final Logger logger = LoggerFactory.getLogger(ComponentLibrary.class);
@Inject
public ComponentLibrary(ModuleManager moduleManager, ReflectFactory reflectFactory, CopyStrategyLibrary copyStrategyLibrary) {
super(moduleManager::getEnvironment, reflectFactory, copyStrategyLibrary);
}
public ComponentLibrary(ModuleEnvironment environment, ReflectFactory reflectFactory, CopyStrategyLibrary copyStrategyLibrary) {
super(() -> environment, reflectFactory, copyStrategyLibrary);
}

View file

@ -5,11 +5,12 @@
import org.terasology.engine.context.Context;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.persistence.typeHandling.TypeHandlerLibrary;
import org.terasology.reflection.copy.CopyStrategyLibrary;
import org.terasology.reflection.reflect.ReflectFactory;
import javax.inject.Inject;
/**
* The set of metadata libraries used by the entity system
*
@ -20,19 +21,21 @@ public class EntitySystemLibrary {
private final ComponentLibrary componentLibrary;
private final EventLibrary eventLibrary;
public EntitySystemLibrary(Context context, TypeHandlerLibrary typeHandlerLibrary) {
// NOTE: Work-around to fix tests
ModuleManager manager = context.get(ModuleManager.class);
ModuleEnvironment environment = null;
if (manager != null) {
environment = manager.getEnvironment();
}
ReflectFactory reflectFactory = context.get(ReflectFactory.class);
CopyStrategyLibrary copyStrategyLibrary = context.get(CopyStrategyLibrary.class);
@Inject
public EntitySystemLibrary(TypeHandlerLibrary typeHandlerLibrary, ComponentLibrary componentLibrary, EventLibrary eventLibrary) {
this.typeHandlerLibrary = typeHandlerLibrary;
this.componentLibrary = new ComponentLibrary(environment, reflectFactory, copyStrategyLibrary);
this.eventLibrary = new EventLibrary(environment, reflectFactory, copyStrategyLibrary);
this.componentLibrary = componentLibrary;
this.eventLibrary = eventLibrary;
}
public EntitySystemLibrary(Context context, TypeHandlerLibrary typeHandlerLibrary) {
this(typeHandlerLibrary,
new ComponentLibrary(context.get(ModuleManager.class) != null ? context.get(ModuleManager.class).getEnvironment() : null,
context.get(ReflectFactory.class),
context.get(CopyStrategyLibrary.class)),
new EventLibrary(context.get(ModuleManager.class) != null ? context.get(ModuleManager.class).getEnvironment() : null,
context.get(ReflectFactory.class),
context.get(CopyStrategyLibrary.class)));
}
/**

View file

@ -4,6 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.core.module.ModuleManager;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.entitysystem.event.Event;
import org.terasology.gestalt.module.ModuleEnvironment;
@ -12,6 +13,8 @@
import org.terasology.reflection.metadata.ModuleClassLibrary;
import org.terasology.reflection.reflect.ReflectFactory;
import javax.inject.Inject;
/**
* The library for metadata about events (and their fields).
*
@ -20,6 +23,11 @@ public class EventLibrary extends ModuleClassLibrary<Event> {
private static final Logger logger = LoggerFactory.getLogger(EventLibrary.class);
@Inject
public EventLibrary(ModuleManager moduleManager, ReflectFactory reflectFactory, CopyStrategyLibrary copyStrategyLibrary) {
super(moduleManager::getEnvironment, reflectFactory, copyStrategyLibrary);
}
public EventLibrary(ModuleEnvironment environment, ReflectFactory reflectFactory, CopyStrategyLibrary copyStrategyLibrary) {
super(() -> environment, reflectFactory, copyStrategyLibrary);
}

View file

@ -9,6 +9,7 @@
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.entitysystem.component.Component;
import javax.inject.Inject;
import java.util.Collection;
import java.util.HashSet;
import java.util.stream.Collectors;
@ -22,6 +23,11 @@ public class PojoPrefabManager implements PrefabManager {
private final AssetManager assetManager;
@Inject
public PojoPrefabManager(AssetManager assetManager) {
this.assetManager = assetManager;
}
public PojoPrefabManager(Context context) {
this.assetManager = context.get(AssetManager.class);
}

View file

@ -3,16 +3,29 @@
package org.terasology.engine.i18n;
import org.terasology.context.Lifetime;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.core.GameEngine;
import org.terasology.engine.core.subsystem.EngineSubsystem;
import org.terasology.engine.i18n.assets.Translation;
import org.terasology.gestalt.assets.management.AssetManager;
import org.terasology.gestalt.assets.module.ModuleAwareAssetTypeManager;
import org.terasology.gestalt.di.ServiceRegistry;
import javax.inject.Inject;
/**
* Registers internationalization systems.
*/
public class I18nSubsystem implements EngineSubsystem {
@Inject
protected SystemConfig systemConfig;
@Inject
protected AssetManager assetManager;
@Inject
public I18nSubsystem() {
}
@Override
public String getName() {
@ -25,8 +38,8 @@ public void registerCoreAssetTypes(ModuleAwareAssetTypeManager assetTypeManager)
}
@Override
public void initialise(GameEngine engine, Context rootContext) {
rootContext.put(TranslationSystem.class, new TranslationSystemImpl(rootContext));
public void preInitialise(ServiceRegistry serviceRegistry) {
serviceRegistry.with(TranslationSystem.class).lifetime(Lifetime.Singleton).use(TranslationSystemImpl.class);
}
@Override

View file

@ -6,13 +6,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.config.SystemConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.i18n.assets.Translation;
import org.terasology.engine.persistence.TemplateEngine;
import org.terasology.engine.persistence.TemplateEngineImpl;
import org.terasology.gestalt.assets.ResourceUrn;
import org.terasology.gestalt.assets.management.AssetManager;
import javax.inject.Inject;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@ -37,12 +37,13 @@ public class TranslationSystemImpl implements TranslationSystem {
private AssetManager assetManager;
/**
* @param context the context to use
* @param systemConfig the system config to use.
* @param assetManager the asset manager to use.
*/
public TranslationSystemImpl(Context context) {
systemConfig = context.get(SystemConfig.class);
assetManager = context.get(AssetManager.class);
@Inject
public TranslationSystemImpl(SystemConfig systemConfig, AssetManager assetManager) {
this.systemConfig = systemConfig;
this.assetManager = assetManager;
refresh();
}

View file

@ -9,7 +9,6 @@
import org.terasology.engine.config.Config;
import org.terasology.engine.config.IdentityStorageServiceConfig;
import org.terasology.engine.config.SecurityConfig;
import org.terasology.engine.context.Context;
import org.terasology.engine.i18n.TranslationSystem;
import org.terasology.engine.identity.ClientIdentity;
import org.terasology.engine.identity.PublicIdentityCertificate;
@ -44,11 +43,11 @@ public final class StorageServiceWorker {
private final Deque<ConsoleNotification> notificationBuffer;
private Map<PublicIdentityCertificate, ClientIdentity> conflictSolutionsToUpload;
public StorageServiceWorker(Context context) {
this.config = context.get(Config.class);
public StorageServiceWorker(Config config, TranslationSystem translationSystem) {
this.config = config;
this.storageConfig = this.config.getIdentityStorageService();
this.securityConfig = this.config.getSecurity();
this.translationSystem = context.get(TranslationSystem.class);
this.translationSystem = translationSystem;
this.notificationBuffer = new LinkedBlockingDeque<>();
this.conflictingRemoteIdentities = new ArrayDeque<>();
}

View file

@ -24,6 +24,7 @@
import org.terasology.nui.FontUnderline;
import org.terasology.engine.utilities.collection.CircularBuffer;
import javax.inject.Inject;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@ -48,6 +49,7 @@ public class ConsoleImpl implements Console {
private final NetworkSystem networkSystem;
private final Context context;
@Inject
public ConsoleImpl(Context context) {
this.networkSystem = context.get(NetworkSystem.class);
this.context = context;

View file

@ -83,6 +83,7 @@
import reactor.core.publisher.Mono;
import reactor.netty.FutureMono;
import javax.inject.Inject;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.time.Duration;
@ -147,6 +148,7 @@ public class NetworkSystemImpl implements EntityChangeSubscriber, NetworkSystem
private ServerImpl server;
private EventLoopGroup clientGroup;
@Inject
public NetworkSystemImpl(EngineTime time, Context context) {
this.time = time;
this.config = context.get(Config.class).getNetwork();

View file

@ -9,6 +9,7 @@
import org.terasology.engine.core.PathManager;
import org.terasology.engine.core.subsystem.DisplayDevice;
import javax.inject.Inject;
import java.io.IOException;
import java.io.Writer;
import java.nio.file.Files;
@ -33,6 +34,7 @@ public class ServerConnectListManager {
private final Path blacklistPath;
private final Path whitelistPath;
@Inject
public ServerConnectListManager(Context context) {
blacklistPath = PathManager.getInstance().getHomePath().resolve("blacklist.json");
whitelistPath = PathManager.getInstance().getHomePath().resolve("whitelist.json");

View file

@ -53,6 +53,8 @@
import org.terasology.protobuf.EntityData;
import reactor.core.publisher.Mono;
import javax.inject.Inject;
import javax.inject.Provider;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
@ -108,26 +110,50 @@ public final class ReadWriteStorageManager extends AbstractStorageManager
* that will use the privateEntityManager.
*/
private final ComponentLibrary entityRefReplacingComponentLibrary;
private Provider<ChunkProvider> chunkProvider;
private final Provider<NetworkSystem> networkSystem;
private final Time time;
private final Game game;
private final BlockManager blockManager;
public ReadWriteStorageManager(Path savePath, ModuleEnvironment environment, EngineEntityManager entityManager, BlockManager blockManager,
ExtraBlockDataManager extraDataManager, RecordAndReplaySerializer recordAndReplaySerializer,
RecordAndReplayUtils recordAndReplayUtils, RecordAndReplayCurrentStatus recordAndReplayCurrentStatus)
throws IOException {
RecordAndReplayUtils recordAndReplayUtils, RecordAndReplayCurrentStatus recordAndReplayCurrentStatus) {
this(savePath, environment, entityManager, blockManager, extraDataManager,
true, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
true, recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus,
() -> CoreRegistry.get(ChunkProvider.class), () -> CoreRegistry.get(NetworkSystem.class), CoreRegistry.get(Time.class),
CoreRegistry.get(Game.class));
}
@Inject
public ReadWriteStorageManager(Game game, ModuleManager moduleManager, EngineEntityManager entityManager, BlockManager blockManager,
ExtraBlockDataManager extraDataManager, RecordAndReplaySerializer recordAndReplaySerializer,
RecordAndReplayUtils recordAndReplayUtils,
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus, Provider<ChunkProvider> chunkProvider,
Provider<NetworkSystem> networkSystem, Time time) {
this(recordAndReplayCurrentStatus.getStatus() == RecordAndReplayStatus.PREPARING_REPLAY
? PathManager.getInstance().getRecordingPath(game.getName())
: PathManager.getInstance().getSavePath(game.getName()),
moduleManager.getEnvironment(), entityManager, blockManager, extraDataManager, true, recordAndReplaySerializer,
recordAndReplayUtils, recordAndReplayCurrentStatus, chunkProvider, networkSystem, time, game);
}
ReadWriteStorageManager(Path savePath, ModuleEnvironment environment, EngineEntityManager entityManager,
BlockManager blockManager, ExtraBlockDataManager extraDataManager, boolean storeChunksInZips,
RecordAndReplaySerializer recordAndReplaySerializer, RecordAndReplayUtils recordAndReplayUtils,
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus) throws IOException {
BlockManager blockManager, ExtraBlockDataManager extraDataManager, boolean storeChunksInZips,
RecordAndReplaySerializer recordAndReplaySerializer, RecordAndReplayUtils recordAndReplayUtils,
RecordAndReplayCurrentStatus recordAndReplayCurrentStatus, Provider<ChunkProvider> chunkProvider,
Provider<NetworkSystem> networkSystem, Time time, Game game) {
super(savePath, environment, entityManager, blockManager, extraDataManager, storeChunksInZips);
entityManager.subscribeForDestruction(this);
entityManager.subscribeForChanges(this);
// TODO Ensure that the component library and the type serializer library are thread save (e.g. immutable)
this.privateEntityManager = createPrivateEntityManager(entityManager.getComponentLibrary());
Files.createDirectories(getStoragePathProvider().getStoragePathDirectory());
try {
Files.createDirectories(getStoragePathProvider().getStoragePathDirectory());
} catch (IOException e) {
throw new RuntimeException(e);
}
this.saveTransactionHelper = new SaveTransactionHelper(getStoragePathProvider());
this.config = CoreRegistry.get(Config.class);
this.systemConfig = CoreRegistry.get((SystemConfig.class));
@ -137,7 +163,11 @@ public ReadWriteStorageManager(Path savePath, ModuleEnvironment environment, Eng
this.recordAndReplaySerializer = recordAndReplaySerializer;
this.recordAndReplayUtils = recordAndReplayUtils;
this.recordAndReplayCurrentStatus = recordAndReplayCurrentStatus;
this.chunkProvider = chunkProvider;
this.networkSystem = networkSystem;
this.time = time;
this.game = game;
this.blockManager = blockManager;
}
private static EngineEntityManager createPrivateEntityManager(ComponentLibrary componentLibrary) {
@ -240,12 +270,8 @@ private SaveTransaction createSaveTransaction() {
SaveTransactionBuilder saveTransactionBuilder = new SaveTransactionBuilder(privateEntityManager,
entitySetDeltaRecorder, isStoreChunksInZips(), getStoragePathProvider(), worldDirectoryWriteLock,
recordAndReplaySerializer, recordAndReplayUtils, recordAndReplayCurrentStatus);
ChunkProvider chunkProvider = CoreRegistry.get(ChunkProvider.class);
NetworkSystem networkSystem = CoreRegistry.get(NetworkSystem.class);
addChunksToSaveTransaction(saveTransactionBuilder, chunkProvider);
addPlayersToSaveTransaction(saveTransactionBuilder, networkSystem);
addChunksToSaveTransaction(saveTransactionBuilder, chunkProvider.get());
addPlayersToSaveTransaction(saveTransactionBuilder, networkSystem.get());
addGlobalStoreBuilderToSaveTransaction(saveTransactionBuilder);
addGameManifestToSaveTransaction(saveTransactionBuilder);
@ -332,10 +358,7 @@ public void onEntityDestroyed(EntityRef entity) {
}
private void addGameManifestToSaveTransaction(SaveTransactionBuilder saveTransactionBuilder) {
BlockManager blockManager = CoreRegistry.get(BlockManager.class);
UniverseConfig universeConfig = config.getUniverseConfig();
Time time = CoreRegistry.get(Time.class);
Game game = CoreRegistry.get(Game.class);
GameManifest gameManifest = new GameManifest(game.getName(), game.getSeed(), time.getGameTimeInMs());
for (Module module : CoreRegistry.get(ModuleManager.class).getEnvironment()) {
@ -380,8 +403,9 @@ public void update() {
}
private boolean isRunModeAllowSaving() {
NetworkSystem networkSystem = CoreRegistry.get(NetworkSystem.class);
return networkSystem.getMode().isAuthority();
NetworkSystem networkSystemInstance = networkSystem.get();
return networkSystemInstance != null && networkSystemInstance.getMode().isAuthority() && chunkProvider.get() != null
&& blockManager != null;
}
private void startSaving() {
@ -442,9 +466,8 @@ private void saveComplete() {
}
private boolean isSavingNecessary() {
ChunkProvider chunkProvider = CoreRegistry.get(ChunkProvider.class);
int unloadedChunkCount = unloadedAndUnsavedChunkMap.size();
int loadedChunkCount = chunkProvider.getAllChunks().size();
int loadedChunkCount = chunkProvider.get().getAllChunks().size();
double totalChunkCount = unloadedChunkCount + loadedChunkCount;
double percentageUnloaded = 100.0 * unloadedChunkCount / totalChunkCount;
if (percentageUnloaded >= systemConfig.maxUnloadedChunksPercentageTillSave.get()) {
@ -466,7 +489,6 @@ private void scheduleNextAutoSave() {
private void saveGamePreviewImage() {
final ScreenGrabber screenGrabber = CoreRegistry.get(ScreenGrabber.class);
final Game game = CoreRegistry.get(Game.class);
if (screenGrabber != null && game != null) {
screenGrabber.takeGamePreview(PathManager.getInstance().getSavePath(game.getName()));
}
@ -534,4 +556,11 @@ public DelayedEntityRef createDelayedEntityRef(long id) {
entitySetDeltaRecorder.registerDelayedEntityRef(delayedEntityRef);
return delayedEntityRef;
}
/**
* TODO: This should not be public. It is only used for unit tests.
*/
public void testSetChunkProvider(ChunkProvider chunkProvider) {
this.chunkProvider = () -> chunkProvider;
}
}

View file

@ -73,6 +73,8 @@
import org.terasology.persistence.typeHandling.reflection.SerializationSandbox;
import org.terasology.reflection.TypeRegistry;
import javax.inject.Inject;
/**
* A library of type handlers. This is used for the construction of class metadata. This library should be initialised
* by adding a number of base type handlers, describing how to serialize each supported type. It will then produce
@ -91,8 +93,12 @@ protected TypeHandlerLibraryImpl(SerializationSandbox sandbox) {
addTypeHandlerFactory(new ComponentClassTypeHandlerFactory());
}
@Inject
public TypeHandlerLibraryImpl(ModuleManager moduleManager, TypeRegistry typeRegistry) {
super(new ModuleEnvironmentSandbox(moduleManager, typeRegistry));
// TODO: This used to be done in TypeHandlerLibraryImpl.forModuleEnvironment().
populateWithDefaultHandlers(this);
}

View file

@ -51,6 +51,7 @@
import org.terasology.engine.monitoring.PerformanceMonitor;
import org.terasology.engine.physics.CollisionGroup;
import org.terasology.engine.physics.HitResult;
import org.terasology.engine.physics.Physics;
import org.terasology.engine.physics.StandardCollisionGroup;
import org.terasology.engine.physics.components.RigidBodyComponent;
import org.terasology.engine.physics.components.TriggerComponent;
@ -64,11 +65,11 @@
import org.terasology.engine.physics.engine.PhysicsSystem;
import org.terasology.engine.physics.engine.RigidBody;
import org.terasology.engine.physics.engine.SweepCallback;
import org.terasology.engine.registry.CoreRegistry;
import org.terasology.engine.rendering.assets.mesh.resource.VertexAttributeBinding;
import org.terasology.engine.world.BlockEntityRegistry;
import org.terasology.joml.geom.AABBf;
import javax.inject.Inject;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@ -83,7 +84,7 @@
* Physics engine implementation using TeraBullet (a customised version of JBullet).
*/
@RegisterSystem
public class BulletPhysics implements PhysicsEngine {
public class BulletPhysics implements PhysicsEngine, Physics {
public static final int AABB_SIZE = Integer.MAX_VALUE;
public static final float SIMD_EPSILON = 1.1920929E-7F;
@ -117,8 +118,8 @@ public class BulletPhysics implements PhysicsEngine {
*/
private ArrayList<btConvexShape> shapes = Lists.newArrayList();
public BulletPhysics() {
@Inject
public BulletPhysics(BlockEntityRegistry blockEntityRegistry) {
ghostPairCallback = new btGhostPairCallback();
broadphase = new btDbvtBroadphase();
@ -129,10 +130,9 @@ public BulletPhysics() {
discreteDynamicsWorld =
new btDiscreteDynamicsWorld(dispatcher, broadphase, sequentialImpulseConstraintSolver, defaultCollisionConfiguration);
discreteDynamicsWorld.setGravity(new Vector3f(0f, -PhysicsEngine.GRAVITY, 0f));
blockEntityRegistry = CoreRegistry.get(BlockEntityRegistry.class);
this.blockEntityRegistry = blockEntityRegistry;
discreteDynamicsWorld.getBroadphase().getOverlappingPairCache().setInternalGhostPairCallback(ghostPairCallback);
}
public btDiscreteDynamicsWorld getWorld() {

Some files were not shown because too many files have changed in this diff Show more