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)
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)
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)
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)
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
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)
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)