88 lines
2.6 KiB
Python
88 lines
2.6 KiB
Python
"""PlaceLoader is a system to load simple plain text data to build a room-based space."""
|
|
|
|
from enum import Enum
|
|
from typing import Dict, List, TextIO, Type
|
|
|
|
from .things import Place
|
|
from .interpret import Interpreter
|
|
|
|
|
|
class PlaceLoaderStates(Enum):
|
|
START = 0
|
|
DESC = 1
|
|
EXITS = 2
|
|
|
|
|
|
class PlaceLoader:
|
|
"""
|
|
A factory which loads a simple data format containing a description of rooms, and how
|
|
they are connected, and produces room objects for each one.
|
|
|
|
The format is a plain text file containing a series of room definitions:
|
|
|
|
ROOMNAME
|
|
DESCRIPTION (multiple lines)
|
|
.
|
|
direction,alias ROOMNAME2
|
|
.
|
|
ROOMNAME2 ...
|
|
|
|
"""
|
|
|
|
def __init__(self, in_file: TextIO, baseplace: Type[Place] = Place):
|
|
"""Initialize the factory by loading a description file.
|
|
|
|
Arguments:
|
|
in_file: A file to load the places from.
|
|
baseplace: A type to initialize the rooms from.
|
|
|
|
"""
|
|
self.base = baseplace
|
|
self.places: Dict[str, Place] = {} # indexed by name
|
|
|
|
if in_file:
|
|
self.process_file(in_file)
|
|
|
|
def process_file(self, in_file: TextIO) -> None:
|
|
"""Load any room information from the passed in file.
|
|
|
|
Arguments:
|
|
in_file: The file to load the rooms from.
|
|
|
|
"""
|
|
state = PlaceLoaderStates.START
|
|
desc: List[str] = []
|
|
temp_exits: Dict[Place, List[str]] = {}
|
|
for line in in_file:
|
|
line = line.strip()
|
|
if state == PlaceLoaderStates.START:
|
|
rm = self.base(line)
|
|
temp_exits[rm] = []
|
|
state = PlaceLoaderStates.DESC
|
|
desc = []
|
|
elif state == PlaceLoaderStates.DESC:
|
|
if line == ".":
|
|
state = PlaceLoaderStates.EXITS
|
|
rm.description = desc
|
|
else:
|
|
desc.append(line)
|
|
elif state == PlaceLoaderStates.EXITS:
|
|
if line == ".":
|
|
state = PlaceLoaderStates.START
|
|
self.places[rm.name] = rm
|
|
else:
|
|
temp_exits[rm].append(line)
|
|
|
|
# assemble the exits
|
|
for place in list(self.places.values()):
|
|
for ext in temp_exits[place]:
|
|
names, destination = ext.split(" ", 1)
|
|
for nm in names.split(","):
|
|
place.ways[nm] = self.places[destination]
|
|
place.update_go()
|
|
|
|
|
|
def interpreter_from_placeloader(placeloader: PlaceLoader) -> Interpreter:
|
|
"""Return an interpreter intialized with the contents of a placeloader."""
|
|
return Interpreter(list(placeloader.places.values()))
|