Exemplo n.º 1
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            return fork_deferred(self._pending_chunks[x, z])

        chunk = Chunk(x, z)
        self.serializer.load_chunk(chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk, x=x, z=z, seed=self.seed,
            generators=configuration.getlist("bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                dtype=uint8).reshape(chunk.heightmap.shape)
            chunk.metadata = fromstring(kwargs["metadata"],
                dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(kwargs["skylight"],
                dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                dtype=uint8).reshape(chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        return fork_deferred(d)
Exemplo n.º 2
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield self._pending_chunks[x, z].deferred()
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            #self.factory.scan_chunk(chunk)
            returnValue(chunk)

        if self.async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                x=x,
                z=z,
                seed=self.seed,
                generators=configuration.getlist(self.config_name, "generators")
            )

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(kwargs["blocks"],
                    dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                    dtype=uint8).reshape(chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                    dtype=uint8).reshape(chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                    dtype=uint8).reshape(chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                    dtype=uint8).reshape(chunk.blocklight.shape)

                return chunk
            d.addCallback(fill_chunk)
        else:
            # Populate the chunk the slow way. :c
            for stage in self.pipeline:
                stage.populate(chunk, self.seed)

            chunk.regenerate()
            d = succeed(chunk)

        # Set up our event and generate our return-value Deferred. It has to
        # be done early becaues PendingEvents only fire exactly once and it
        # might fire immediately in certain cases.
        pe = PendingEvent()
        # This one is for our return value.
        retval = pe.deferred()
        # This one is for scanning the chunk for automatons.
        #pe.deferred().addCallback(self.factory.scan_chunk)
        self._pending_chunks[x, z] = pe

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        d.chainDeferred(pe)

        # Because multiple people might be attached to this callback, we're
        # going to do something magical here. We will yield a forked version
        # of our Deferred. This means that we will wait right here, for a
        # long, long time, before actually returning with the chunk, *but*,
        # when we actually finish, we'll be ready to return the chunk
        # immediately. Our caller cannot possibly care because they only see a
        # Deferred either way.
        retval = yield retval
        returnValue(retval)
Exemplo n.º 3
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                              x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            return fork_deferred(self._pending_chunks[x, z])

        chunk = Chunk(x, z)
        self.serializer.load_chunk(chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk,
                              x=x,
                              z=z,
                              seed=self.seed,
                              generators=configuration.getlist(
                                  "bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                                      dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                                         dtype=uint8).reshape(
                                             chunk.heightmap.shape)
            chunk.metadata = fromstring(
                kwargs["metadata"], dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(
                kwargs["skylight"], dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                                          dtype=uint8).reshape(
                                              chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        return fork_deferred(d)
Exemplo n.º 4
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield fork_deferred(self._pending_chunks[x, z])
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            returnValue(chunk)

        if self.async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                x=x,
                z=z,
                seed=self.seed,
                generators=configuration.getlist(self.config_name, "generators")
            )
            self._pending_chunks[x, z] = d

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(kwargs["blocks"],
                    dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                    dtype=uint8).reshape(chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                    dtype=uint8).reshape(chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                    dtype=uint8).reshape(chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                    dtype=uint8).reshape(chunk.blocklight.shape)

                return chunk
            d.addCallback(fill_chunk)
        else:
            self.populate_chunk(chunk)
            d = succeed(chunk)
            self._pending_chunks[x, z] = d

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)

        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        retval = yield fork_deferred(d)
        returnValue(retval)
Exemplo n.º 5
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: Deferred that will be called with the Chunk
        """

        if not async:
            return deferLater(reactor, 0.000001, self.factory.world.load_chunk,
                x, z)

        if (x, z) in self.chunk_cache:
            return succeed(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            return succeed(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            d = Deferred()
            self._pending_chunks[x, z].chainDeferred(d)
            return d

        chunk = Chunk(x, z)

        first, second, filename = names_for_chunk(x, z)
        f = self.folder.child(first).child(second)
        if not f.exists():
            f.makedirs()
        f = f.child(filename)
        if f.exists() and f.getsize():
            chunk.load_from_tag(read_from_file(f.open("r")))

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            return succeed(chunk)

        d = deferToAMPProcess(MakeChunk, x=x, z=z, seed=self.seed,
            generators=configuration.getlist("bravo", "generators"))
        self._pending_chunks[x, z] = d

        def pp(kwargs):
            chunk.blocks = fromstring(kwargs["blocks"],
                dtype=uint8).reshape(chunk.blocks.shape)
            chunk.heightmap = fromstring(kwargs["heightmap"],
                dtype=uint8).reshape(chunk.heightmap.shape)
            chunk.metadata = fromstring(kwargs["metadata"],
                dtype=uint8).reshape(chunk.metadata.shape)
            chunk.skylight = fromstring(kwargs["skylight"],
                dtype=uint8).reshape(chunk.skylight.shape)
            chunk.blocklight = fromstring(kwargs["blocklight"],
                dtype=uint8).reshape(chunk.blocklight.shape)

            chunk.populated = True
            chunk.dirty = True

            # Apply the current season to the chunk.
            if self.season:
                self.season.transform(chunk)

            # Since this chunk hasn't been given to any player yet, there's no
            # conceivable way that any meaningful damage has been accumulated;
            # anybody loading any part of this chunk will want the entire thing.
            # Thus, it should start out undamaged.
            chunk.clear_damage()

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        forked = Deferred()
        d.chainDeferred(forked)
        forked.addCallback(lambda none: chunk)
        return forked
Exemplo n.º 6
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield self._pending_chunks[x, z].deferred()
            returnValue(retval)

        try:
            chunk = yield maybeDeferred(self.serializer.load_chunk, x, z)
        except SerializerReadException:
            # Looks like the chunk wasn't already on disk. Guess we're gonna
            # need to keep going.
            chunk = Chunk(x, z)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            if self.factory:
                self.factory.scan_chunk(chunk)
            returnValue(chunk)

        if self. async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            generators = [plugin.name for plugin in self.pipeline]

            d = deferToAMPProcess(MakeChunk,
                                  x=x,
                                  z=z,
                                  seed=self.level.seed,
                                  generators=generators)

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = array("B")
                chunk.blocks.fromstring(kwargs["blocks"])
                chunk.heightmap = array("B")
                chunk.heightmap.fromstring(kwargs["heightmap"])
                chunk.metadata = array("B")
                chunk.metadata.fromstring(kwargs["metadata"])
                chunk.skylight = array("B")
                chunk.skylight.fromstring(kwargs["skylight"])
                chunk.blocklight = array("B")
                chunk.blocklight.fromstring(kwargs["blocklight"])
                return chunk

            d.addCallback(fill_chunk)
        else:
            # Populate the chunk the slow way. :c
            for stage in self.pipeline:
                stage.populate(chunk, self.level.seed)

            chunk.regenerate()
            d = succeed(chunk)

        # Set up our event and generate our return-value Deferred. It has to
        # be done early becaues PendingEvents only fire exactly once and it
        # might fire immediately in certain cases.
        pe = PendingEvent()
        # This one is for our return value.
        retval = pe.deferred()
        # This one is for scanning the chunk for automatons.
        if self.factory:
            pe.deferred().addCallback(self.factory.scan_chunk)
        self._pending_chunks[x, z] = pe

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)
        d.chainDeferred(pe)

        # Because multiple people might be attached to this callback, we're
        # going to do something magical here. We will yield a forked version
        # of our Deferred. This means that we will wait right here, for a
        # long, long time, before actually returning with the chunk, *but*,
        # when we actually finish, we'll be ready to return the chunk
        # immediately. Our caller cannot possibly care because they only see a
        # Deferred either way.
        retval = yield retval
        returnValue(retval)
Exemplo n.º 7
0
    def request_chunk(self, x, z):
        """
        Request a ``Chunk`` to be delivered later.

        :returns: ``Deferred`` that will be called with the ``Chunk``
        """

        if (x, z) in self.chunk_cache:
            returnValue(self.chunk_cache[x, z])
        elif (x, z) in self.dirty_chunk_cache:
            returnValue(self.dirty_chunk_cache[x, z])
        elif (x, z) in self._pending_chunks:
            # Rig up another Deferred and wrap it up in a to-go box.
            retval = yield fork_deferred(self._pending_chunks[x, z])
            returnValue(retval)

        chunk = Chunk(x, z)
        yield maybeDeferred(self.serializer.load_chunk, chunk)

        if chunk.populated:
            self.chunk_cache[x, z] = chunk
            self.postprocess_chunk(chunk)
            returnValue(chunk)

        if self. async:
            from ampoule import deferToAMPProcess
            from bravo.remote import MakeChunk

            d = deferToAMPProcess(MakeChunk,
                                  x=x,
                                  z=z,
                                  seed=self.seed,
                                  generators=configuration.getlist(
                                      self.config_name, "generators"))
            self._pending_chunks[x, z] = d

            # Get chunk data into our chunk object.
            def fill_chunk(kwargs):
                chunk.blocks = fromstring(
                    kwargs["blocks"], dtype=uint8).reshape(chunk.blocks.shape)
                chunk.heightmap = fromstring(kwargs["heightmap"],
                                             dtype=uint8).reshape(
                                                 chunk.heightmap.shape)
                chunk.metadata = fromstring(kwargs["metadata"],
                                            dtype=uint8).reshape(
                                                chunk.metadata.shape)
                chunk.skylight = fromstring(kwargs["skylight"],
                                            dtype=uint8).reshape(
                                                chunk.skylight.shape)
                chunk.blocklight = fromstring(kwargs["blocklight"],
                                              dtype=uint8).reshape(
                                                  chunk.blocklight.shape)

                return chunk

            d.addCallback(fill_chunk)
        else:
            self.populate_chunk(chunk)
            d = succeed(chunk)
            self._pending_chunks[x, z] = d

        def pp(chunk):
            chunk.populated = True
            chunk.dirty = True

            self.postprocess_chunk(chunk)

            self.dirty_chunk_cache[x, z] = chunk
            del self._pending_chunks[x, z]

            return chunk

        # Set up callbacks.
        d.addCallback(pp)

        # Multiple people might be subscribed to this pending callback. We're
        # going to keep it for ourselves and fork off another Deferred for our
        # caller.
        retval = yield fork_deferred(d)
        returnValue(retval)