Coverage for /home/kale/kxgames/libraries/kxg/kxg/messages.py : 100%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
#!/usr/bin/env python3
# This class defers initializing all of its members until the appropriate # setter is called, rather than initializing everything in a constructor. # This is done to avoid sending unnecessary information over the network.
else:
Can't ask who sent a message before it's been sent.
This error means Message.was_sent_by() or Message.was_sent_by_referee() got called on a message that hadn't been sent yet. Normally you would only call these methods from within Message.on_check().""")
""" Return a list of all the tokens that are referenced (i.e. contained in) this message. Tokens that haven't been assigned an id yet are searched recursively for tokens. So this method may return fewer results after the message is sent. This information is used by the game engine to catch mistakes like forgetting to add a token to the world or keeping a stale reference to a token after its been removed. """
# Use the pickle machinery to find all the tokens contained at any # level of this message. When an object is being pickled, the Pickler # calls its persistent_id() method for each object it encounters. We # hijack this method to add every Token we encounter to a list.
# This definitely feels like a hacky abuse of the pickle machinery, but # that notwithstanding this should be quite robust and quite fast.
# Recursively descend into tokens that haven't been assigned an # id yet, but not into tokens that have.
# Use BytesIO to basically ignore the serialized data stream, since we # only care about visiting all the objects that would be pickled.
# Called by the actor. If no MessageCheck exception is raised, the # message will be sent as usual. Otherwise, the behavior will depend # on what kind of actor is handling the message. Actor (uniplayer and # multiplayer clients) will Normal Actor will simply not send the # message. ServerActor (multiplayer server) will decide if the error # should be handled by undoing the message or asking the clients to # sync themselves. raise NotImplementedError
# Called only by ServerActor if on_check() returns False. If this # method returns True, the message will be relayed to the rest of the # clients with the sync error flag set. Otherwise the message will not # be sent and the ClientForum that sent the message will be instructed # to undo it. If a soft error is detected, this method should save # information about the world that it could use to resynchronize all # the clients.
# Called by the forum on every machine running the game. Allowed to # make changes to the game world, but should not change the message # itself. Called before any signal-handling callbacks.
# Called by the forum upon receiving a message with the soft error flag # set. This flag indicates that the client that sent the message is # slightly out of sync with the server, but that the message will be # relayed as usual and that the clients should use the opportunity to # quietly resynchronize themselves.
# Called by ClientForum only upon receiving a message with the hard # error flag set. This flag indicates that the server refused to relay # the given message to the other clients, presumably because it was too # far out of sync with the world on the server, and that the message # needs to be undone on this client. Only the ClientForum that sent # the offending message will call this method. The message {self} was rejected by the server.
This client attempted to send a {message_cls} message, but it was rejected by the server. To fix this error, either figure out why the client is getting out of sync with the server or implement a {message_cls}.on_undo() that undoes everything done in {message_cls}.on_execute().""")
""" Assign id numbers to any tokens that will be added to the world by this message.
This method is called by Actor but not by ServerActor, so it's guaranteed to be called exactly once. In fact, this method is not really different from the constructor, except that the id_factory object is nicely provided. That's useful for assigning ids to tokens but probably nothing else. This method is called before _check() so that _check() can make sure that valid ids were assigned (although by default it doesn't). """
# Deal with tokens to be created or destroyed.
# Save the id numbers for the tokens we're removing so we can restore # them if we need to undo this message.
# Let derived classes execute themselves.
# The tokens in self.tokens_to_add() haven't been added to the world # yet, because the message was copied and pickled before it was # executed on the server. We need to access the tokens that are # actually in the world before we can remove them again.
# The tokens in self.tokens_to_remove() have already been removed from # the world. We want to add them back, and we want to make sure they # end up with the id as before.
# Let derived classes execute themselves.
def require_message(object):
def require_message_cls(cls): expected Message subclass, but got {wrong_thing} instead.""")
|