public bool Subscribe(IEventListener <ChunkState> listener, ChunkState evt, bool registerListener) { if (listener == null || listener == this) { return(false); } ChunkEvent chunkListener = (ChunkEvent)listener; // Register if (registerListener) { // Make sure this section is not registered yet for (int i = 0; i < Listeners.Length; i++) { ChunkEvent l = Listeners[i]; // Do not register if already registred if (l == listener) { return(false); } } // Subscribe in the first free slot for (int i = 0; i < Listeners.Length; i++) { ChunkEvent l = Listeners[i]; if (l == null) { ++ListenerCount; Assert.IsTrue(ListenerCount <= 6); Listeners[i] = chunkListener; return(true); } } // We want to register but there is no free space Assert.IsTrue(false); } // Unregister else { // Only unregister already registered sections for (int i = 0; i < Listeners.Length; i++) { ChunkEvent l = Listeners[i]; if (l == listener) { --ListenerCount; Assert.IsTrue(ListenerCount >= 0); Listeners[i] = null; return(true); } } } return(false); }
public void NotifyAll(ChunkState state) { // Notify each registered listener for (int i = 0; i < Listeners.Length; i++) { ChunkEvent l = Listeners[i]; if (l != null) { l.OnNotified(this, state); } } }
public void NotifyOne(IEventListener <ChunkState> listener, ChunkState state) { // Notify one of the listeners for (int i = 0; i < Listeners.Length; i++) { ChunkEvent l = Listeners[i]; if (l == listener) { l.OnNotified(this, state); return; } } }
private void ProcessSetBlockQueue() { if (m_setBlockQueue.Count <= 0) { return; } StateManager.RequestState(ChunkState.FinalizeData | ChunkState.BuildVerticesNow); int rebuildMask = 0; // Modify blocks for (int j = 0; j < m_setBlockQueue.Count; j++) { SetBlockContext context = m_setBlockQueue[j]; int x, y, z; Helpers.GetIndex3DFrom1D(context.Index, out x, out y, out z); this[x, y, z] = context.Block; if ( // Only check neighbors if it is still needed rebuildMask == 0x3f || // Only check neighbors when it is a change of a block on a chunk's edge (((x + 1) & EngineSettings.ChunkConfig.Mask) > 1 && ((y + 1) & EngineSettings.ChunkConfig.Mask) > 1 && ((z + 1) & EngineSettings.ChunkConfig.Mask) > 1) ) { continue; } int cx = Pos.X; int cy = Pos.Y; int cz = Pos.Z; // If it is an edge position, notify neighbor as well // Iterate over neighbors and decide which ones should be notified to rebuild for (int i = 0; i < StateManager.Listeners.Length; i++) { ChunkEvent listener = StateManager.Listeners[i]; if (listener == null) { continue; } // No further checks needed once we know all neighbors need to be notified if (rebuildMask == 0x3f) { break; } ChunkStateManagerClient listenerChunk = (ChunkStateManagerClient)listener; int lx = listenerChunk.chunk.Pos.X; int ly = listenerChunk.chunk.Pos.Y; int lz = listenerChunk.chunk.Pos.Z; if ((ly == cy || lz == cz) && ( // Section to the left ((x == 0) && (lx + EngineSettings.ChunkConfig.Mask == cx)) || // Section to the right ((x == EngineSettings.ChunkConfig.Mask) && (lx - EngineSettings.ChunkConfig.Mask == cx)) )) { rebuildMask = rebuildMask | (1 << i); } if ((lx == cx || lz == cz) && ( // Section to the bottom ((y == 0) && (ly + EngineSettings.ChunkConfig.Mask == cy)) || // Section to the top ((y == EngineSettings.ChunkConfig.Mask) && (ly - EngineSettings.ChunkConfig.Mask == cy)) )) { rebuildMask = rebuildMask | (1 << i); } if ((ly == cy || lx == cx) && ( // Section to the back ((z == 0) && (lz + EngineSettings.ChunkConfig.Mask == cz)) || // Section to the front ((z == EngineSettings.ChunkConfig.Mask) && (lz - EngineSettings.ChunkConfig.Mask == cz)) )) { rebuildMask = rebuildMask | (1 << i); } } } m_setBlockQueue.Clear(); // Notify neighbors that they need to rebuilt their geometry if (rebuildMask > 0) { for (int j = 0; j < StateManager.Listeners.Length; j++) { ChunkStateManagerClient listener = (ChunkStateManagerClient)StateManager.Listeners[j]; if (listener != null && ((rebuildMask >> j) & 1) != 0) { listener.RequestState(ChunkState.FinalizeData | ChunkState.BuildVerticesNow); } } } }