@Override public boolean step() { NetworkSystem networkSystem = context.get(NetworkSystem.class); WorldAtlas atlas = new WorldAtlasImpl(context.get(Config.class).getRendering().getMaxTextureAtlasResolution()); context.put(WorldAtlas.class, atlas); BlockManagerImpl blockManager; if (networkSystem.getMode().isAuthority()) { blockManager = new BlockManagerImpl(atlas, context.get(AssetManager.class), true); blockManager.subscribe(context.get(NetworkSystem.class)); } else { blockManager = new BlockManagerImpl(atlas, context.get(AssetManager.class), false); } context.put(BlockManager.class, blockManager); context .get(TypeSerializationLibrary.class) .add(Block.class, new BlockTypeHandler(blockManager)); context .get(TypeSerializationLibrary.class) .add(BlockFamily.class, new BlockFamilyTypeHandler(blockManager)); blockManager.initialise( gameManifest.getRegisteredBlockFamilies(), gameManifest.getBlockIdMap()); return true; }
private void addPlayersToSaveTransaction( SaveTransactionBuilder saveTransactionBuilder, NetworkSystem networkSystem) { unloadedAndSavingPlayerMap.clear(); /** * New entries might be added concurrently. By using putAll + clear to transfer entries we might * loose new ones added in between putAll and clear. By iterating we can make sure that all * entities removed from unloadedAndUnsavedPlayerMap get added to unloadedAndSavingPlayerMap. */ Iterator<Map.Entry<String, EntityData.PlayerStore>> unsavedEntryIterator = unloadedAndUnsavedPlayerMap.entrySet().iterator(); while (unsavedEntryIterator.hasNext()) { Map.Entry<String, EntityData.PlayerStore> entry = unsavedEntryIterator.next(); unloadedAndSavingPlayerMap.put(entry.getKey(), entry.getValue()); unsavedEntryIterator.remove(); } for (Client client : networkSystem.getPlayers()) { // If there is a newer undisposed version of the player,we don't need to save the disposed // version: unloadedAndSavingPlayerMap.remove(client.getId()); EntityRef character = client.getEntity().getComponent(ClientComponent.class).character; saveTransactionBuilder.addLoadedPlayer(client.getId(), createPlayerStore(client, character)); } for (Map.Entry<String, EntityData.PlayerStore> entry : unloadedAndSavingPlayerMap.entrySet()) { saveTransactionBuilder.addUnloadedPlayer(entry.getKey(), entry.getValue()); } }
@ReceiveEvent public void onPlaySound(PlaySoundForOwnerEvent playSoundEvent, EntityRef entity) { ClientComponent clientComponent = networkSystem.getOwnerEntity(entity).getComponent(ClientComponent.class); if (clientComponent != null && !clientComponent.local) { return; } audioManager.playSound( playSoundEvent.getSound(), playSoundEvent.getVolume(), AudioManager.PRIORITY_HIGH); }
@Override public String getMetrics() { // only update the metric a minimum once a second, cache the result long currentTime = time.getGameTimeInMs(); long timeDifference = currentTime - lastTime; if (timeDifference >= 1000) { StringBuilder builder = new StringBuilder(); builder.append(getName()); builder.append("\n"); builder.append(String.format("Elapsed: %dms%n", timeDifference)); builder.append(String.format("In Msg: %d%n", networkSystem.getIncomingMessagesDelta())); builder.append(String.format("In Bytes: %d%n", networkSystem.getIncomingBytesDelta())); builder.append(String.format("Out Msg: %d%n", networkSystem.getOutgoingMessagesDelta())); builder.append(String.format("Out Bytes: %d%n", networkSystem.getOutgoingBytesDelta())); if (lastTime != 0) { // ignore the first update as it will not have useful data lastMetric = builder.toString(); } lastTime = currentTime; } return lastMetric; }
private boolean isRunModeAllowSaving() { NetworkSystem networkSystem = CoreRegistry.get(NetworkSystem.class); return networkSystem.getMode().isAuthority(); }
@Override public boolean isAvailable() { return networkSystem.getMode() != NetworkMode.NONE; }
/** * The main loop runs until the EngineState is set back to INITIALIZED by shutdown() or until the * OS requests the application's window to be closed. Engine cleanup and disposal occur * afterwards. */ private void mainLoop() { NetworkSystem networkSystem = CoreRegistry.get(NetworkSystem.class); DisplayDevice display = CoreRegistry.get(DisplayDevice.class); PerformanceMonitor.startActivity("Other"); // MAIN GAME LOOP while (engineState == EngineState.RUNNING && !display.isCloseRequested()) { long totalDelta; float updateDelta; float subsystemsDelta; // Only process rendering and updating once a second if (!display.isActive() && isHibernationAllowed()) { time.setPaused(true); Iterator<Float> updateCycles = time.tick(); while (updateCycles.hasNext()) { updateCycles.next(); } try { Thread.sleep(100); } catch (InterruptedException e) { logger.warn("Display inactivity sleep interrupted", e); } display.processMessages(); time.setPaused(false); continue; } processPendingState(); if (currentState == null) { shutdown(); break; } Iterator<Float> updateCycles = time.tick(); try (Activity ignored = PerformanceMonitor.startActivity("Network Update")) { networkSystem.update(); } totalDelta = 0; while (updateCycles.hasNext()) { updateDelta = updateCycles.next(); // gameTime gets updated here! totalDelta += time.getDeltaInMs(); try (Activity ignored = PerformanceMonitor.startActivity("Main Update")) { currentState.update(updateDelta); } } subsystemsDelta = totalDelta / 1000f; for (EngineSubsystem subsystem : getSubsystems()) { try (Activity ignored = PerformanceMonitor.startActivity(subsystem.getClass().getSimpleName())) { subsystem.preUpdate(currentState, subsystemsDelta); } } // Waiting processes are set by modules via GameThread.a/synch() methods. GameThread.processWaitingProcesses(); for (EngineSubsystem subsystem : getSubsystems()) { try (Activity ignored = PerformanceMonitor.startActivity(subsystem.getClass().getSimpleName())) { subsystem.postUpdate(currentState, subsystemsDelta); } } PerformanceMonitor.rollCycle(); PerformanceMonitor.startActivity("Other"); } PerformanceMonitor.endActivity(); // This becomes important only if display.isCloseRequested() is true. // In all other circumstances the EngineState is already set to // INITIALIZED by the time the flow gets here. engineState = EngineState.INITIALIZED; }
@Before public void setup() { GameThread.setGameThread(); AssetManager assetManager = CoreRegistry.put( AssetManager.class, new AssetManager(new ModuleManagerImpl(new ModuleSecurityManager()))); assetManager.setAssetFactory( AssetType.PREFAB, new AssetFactory<PrefabData, Prefab>() { @Override public Prefab buildAsset(AssetUri uri, PrefabData data) { return new PojoPrefab(uri, data); } }); EntitySystemBuilder builder = new EntitySystemBuilder(); CoreRegistry.put(ComponentSystemManager.class, mock(ComponentSystemManager.class)); blockManager = CoreRegistry.put( BlockManager.class, new BlockManagerImpl(mock(WorldAtlas.class), new DefaultBlockFamilyFactoryRegistry())); NetworkSystem networkSystem = mock(NetworkSystem.class); when(networkSystem.getMode()).thenReturn(NetworkMode.NONE); entityManager = builder.build(moduleManager, networkSystem, new ReflectionReflectFactory()); worldStub = new WorldProviderCoreStub(BlockManager.getAir()); worldProvider = new EntityAwareWorldProvider(worldStub, entityManager); plainBlock = new Block(); blockManager.addBlockFamily( new SymmetricFamily(new BlockUri("test:plainBlock"), plainBlock), true); blockWithString = new Block(); PrefabData prefabData = new PrefabData(); prefabData.addComponent(new StringComponent("Test")); Assets.generateAsset( new AssetUri(AssetType.PREFAB, "test:prefabWithString"), prefabData, Prefab.class); blockWithString.setPrefab("test:prefabWithString"); blockManager.addBlockFamily( new SymmetricFamily(new BlockUri("test:blockWithString"), blockWithString), true); blockWithDifferentString = new Block(); prefabData = new PrefabData(); prefabData.addComponent(new StringComponent("Test2")); Assets.generateAsset( new AssetUri(AssetType.PREFAB, "test:prefabWithDifferentString"), prefabData, Prefab.class); blockWithDifferentString.setPrefab("test:prefabWithDifferentString"); blockManager.addBlockFamily( new SymmetricFamily( new BlockUri("test:blockWithDifferentString"), blockWithDifferentString), true); blockWithRetainedComponent = new Block(); prefabData = new PrefabData(); prefabData.addComponent(new RetainedOnBlockChangeComponent(3)); Assets.generateAsset( new AssetUri(AssetType.PREFAB, "test:prefabWithRetainedComponent"), prefabData, Prefab.class); blockWithRetainedComponent.setPrefab("test:prefabWithRetainedComponent"); blockManager.addBlockFamily( new SymmetricFamily( new BlockUri("test:blockWithRetainedComponent"), blockWithRetainedComponent), true); blockInFamilyOne = new Block(); blockInFamilyOne.setKeepActive(true); blockInFamilyOne.setPrefab("test:prefabWithString"); blockInFamilyTwo = new Block(); blockInFamilyTwo.setPrefab("test:prefabWithString"); blockInFamilyTwo.setKeepActive(true); blockManager.addBlockFamily( new HorizontalBlockFamily( new BlockUri("test:blockFamily"), ImmutableMap.<Side, Block>of( Side.FRONT, blockInFamilyOne, Side.LEFT, blockInFamilyTwo, Side.RIGHT, blockInFamilyTwo, Side.BACK, blockInFamilyOne), Collections.<String>emptyList()), true); keepActiveBlock = new Block(); keepActiveBlock.setKeepActive(true); keepActiveBlock.setPrefab("test:prefabWithString"); blockManager.addBlockFamily( new SymmetricFamily(new BlockUri("test:keepActiveBlock"), keepActiveBlock), true); worldProvider.initialise(); }