def test_simple_dispatch_store_selects_handler_based_on_all_arguments(): dispatch_store = SimpleDispatchStore() int_float_handler = Mock() dispatch_store.add_handler(match_args(int, float), int_float_handler) float_int_handler = Mock() dispatch_store.add_handler(match_args(float, int), float_int_handler) assert dispatch_store.get_handler(1.0, 2) == float_int_handler assert dispatch_store.get_handler(3, 4.0) == int_float_handler
def test_trie_dispatch_store_ambiguous_rule_resolving_depends_on_insertion_order( ): general_handler = Mock(name='general') specific_handler = Mock(name='specific') dispatch_store1 = TrieDispatchStore() dispatch_store1.add_handler(match_args(object), general_handler) dispatch_store1.add_handler(match_args(int), specific_handler) dispatch_store2 = TrieDispatchStore() dispatch_store2.add_handler(match_args(int), specific_handler) dispatch_store2.add_handler(match_args(object), general_handler) assert dispatch_store1.get_handler(0) == general_handler assert dispatch_store2.get_handler(0) == specific_handler
def test_ranking_dispatch_store(): created_orders = [] def order(signature): created_orders.append(signature) return [- {object: 0, int: 1}[ty] for ty in signature] select_first = lambda x: x[0] dispatch_store = RankingDispatchStore(order=order, select=select_first) general_handler = Mock(name='general') dispatch_store.add_handler(match_args(object), general_handler) specific_handler = Mock(name='specific') dispatch_store.add_handler(match_args(int), specific_handler) handler = dispatch_store.get_handler(0) assert set(created_orders) == {(object, ), (int, )} assert handler == specific_handler
from .person import Person from .place import Place from .thing import Thing def take_thing(thing, person): move(thing, person.bag, person) def drop_thing(thing, person): move(thing, person.location, person) # default generic move generic_move.add_handler( match_args(Thing, Container, Container, Person), lambda thing, src, dst, actor: tell([thing, "is not movable"], actor) ) def move_steal(mobile_thing, from_bag, to_bag, actor): former_holder = from_bag.holder new_holder = to_bag.holder if from_bag is to_bag: tell([new_holder, "is already carrying", mobile_thing], actor) elif actor is former_holder: narrate([actor, "gives", mobile_thing, "to", new_holder], actor) elif actor is new_holder: narrate([actor, "takes", mobile_thing, "from", former_holder], actor) else:
def things_in_place(self): return [thing for thing in self.things if not is_person(thing)] def people_in_place(self): return [thing for thing in self.things if is_person(thing)] def all_things_in_place(self): return self.things_in_place() + [thing for person in self.people_in_place() for thing in person.get_things()] def find_exit_in_direction(self, direction): return self.exits.get(direction) def find_exit(self, dst): for exit in self.exits.values(): if exit.target == dst: return exit return None from ..adventure_substrate.messaging import Message from ..generics import send_message from chapter03.multimethods import match_args send_message.add_handler( match_args(Message, Place), lambda message, place: [send_message(message, person) for person in place.people_in_place()] ) from .person import is_person from .exit import Exit
if debug_output(): send_message(message, debug_output) def say(person, message): narrate([person, "says:", *message], person) def announce(*message): for place in world.all_places: send_message(list(message), place) def format_message(message): return " ".join(format_item(item) for item in message) def format_item(item): try: return item.name except AttributeError: return str(item) def possessive(person): return person.name + "'s" send_message.add_handler(match_args(Message, type(None)), lambda message, thing: print(message, '@', thing))
import chapter05.common.display from .object import Object class Screen(Object): def __init__(self, name: str): super().__init__(name) def display(self, msg): print(msg) from ..adventure_substrate.messaging import Message, format_message from ..generics import send_message from chapter03.multimethods import match_args send_message.add_handler( match_args(Message, Screen), lambda message, screen: chapter05.common.display.display( format_message(message)))
tell(["Your bag contains:", *my_things], self) things = [*self.things_here(), *self.people_here()] if things: tell(["You see here:", *things], self) vistas = self.vistas_here() if vistas: tell(["You can see:", *vistas], self) exits = self.exits_here() if exits: tell(["You can exit:", [x.direction for x in exits]], self) else: tell(["There are no exits...", "you are dead and gone to heaven!"], self) def enter_place(self): super().enter_place() self.look_around() world.the_clock.tick() from chapter03.multimethods import match_args from ..adventure_substrate.messaging import tell, Message from ..generics import send_message send_message.add_handler( match_args(Message, Avatar), lambda message, avatar: send_message(message, avatar.screen))
from chapter03.adventure_game.adventure_substrate.messaging import Message from chapter03.multimethods import match_args from .object import Object from ..generics import send_message class Thing(Object): def __init__(self, name: str, location): super().__init__(name) self.location = location location.add_thing(self) def clock_tick(self): # override to add behavior pass send_message.add_handler( match_args(Message, Thing), lambda message, thing: None )