Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
 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);
         }
     }
 }
Ejemplo n.º 3
0
 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;
         }
     }
 }
Ejemplo n.º 4
0
        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);
                    }
                }
            }
        }