<s> """<STR_LIT>""" <EOL> import logging <EOL> from mpf . devices . ball_device import BallDevice <EOL> from mpf . system . tasks import DelayManager <EOL> class Playfield ( BallDevice ) : <EOL> config_section = '<STR_LIT>' <EOL> collection = '<STR_LIT>' <EOL> class_label = '<STR_LIT>' <EOL> def __init__ ( self , machine , name , config , collection = None , validate = True ) : <EOL> self . log = logging . getLogger ( '<STR_LIT>' ) <EOL> self . machine = machine <EOL> self . name = name . lower ( ) <EOL> self . tags = list ( ) <EOL> self . label = None <EOL> self . debug = False <EOL> self . config = dict ( ) <EOL> self . _count_consistent = True <EOL> self . unexpected_balls = <NUM_LIT:0> <EOL> if validate : <EOL> self . config = self . machine . config_processor . process_config2 ( <EOL> self . config_section , config , self . name ) <EOL> else : <EOL> self . config = config <EOL> if self . config [ '<STR_LIT>' ] : <EOL> self . debug = True <EOL> self . log . debug ( "<STR_LIT>" ) <EOL> self . log . debug ( "<STR_LIT>" , config ) <EOL> self . tags = self . config [ '<STR_LIT>' ] <EOL> self . label = self . config [ '<STR_LIT:label>' ] <EOL> self . delay = DelayManager ( ) <EOL> self . machine . ball_devices [ name ] = self <EOL> if '<STR_LIT:default>' in self . config [ '<STR_LIT>' ] : <EOL> self . machine . playfield = self <EOL> self . _balls = <NUM_LIT:0> <EOL> self . available_balls = <NUM_LIT:0> <EOL> self . num_balls_requested = <NUM_LIT:0> <EOL> self . queued_balls = list ( ) <EOL> self . _playfield = True <EOL> for device in self . machine . ball_devices : <EOL> for target in device . config [ '<STR_LIT>' ] : <EOL> if target == self . name : <EOL> self . machine . events . add_handler ( <EOL> event = '<STR_LIT>' + device . name + <EOL> '<STR_LIT>' , <EOL> handler = self . _source_device_eject_success ) <EOL> self . machine . events . add_handler ( <EOL> event = '<STR_LIT>' + device . name + <EOL> '<STR_LIT>' , <EOL> handler = self . _source_device_eject_failed ) <EOL> self . machine . events . add_handler ( <EOL> event = '<STR_LIT>' + device . name + <EOL> '<STR_LIT>' , <EOL> handler = self . _source_device_eject_attempt ) <EOL> break <EOL> self . machine . events . add_handler ( '<STR_LIT>' + self . name , <EOL> self . _ball_removed_handler ) <EOL> self . machine . events . add_handler ( '<STR_LIT>' + self . name + '<STR_LIT>' , <EOL> self . playfield_switch_hit ) <EOL> self . machine . events . add_handler ( '<STR_LIT>' , <EOL> self . _initialize ) <EOL> def _initialize ( self ) : <EOL> self . ball_controller = self . machine . ball_controller <EOL> for device in self . machine . playfield_transfers : <EOL> if device . config [ '<STR_LIT>' ] == self . name : <EOL> self . machine . events . add_handler ( <EOL> event = '<STR_LIT>' + device . name + <EOL> '<STR_LIT>' , <EOL> handler = self . _source_device_eject_success ) <EOL> self . machine . events . add_handler ( <EOL> event = '<STR_LIT>' + device . name + <EOL> '<STR_LIT>' , <EOL> handler = self . _source_device_eject_attempt ) <EOL> def add_missing_balls ( self , balls ) : <EOL> if self . unexpected_balls : <EOL> self . unexpected_balls -= <NUM_LIT:1> <EOL> balls -= <NUM_LIT:1> <EOL> self . balls += balls <EOL> @ property <EOL> def balls ( self ) : <EOL> return self . _balls <EOL> @ balls . setter <EOL> def balls ( self , balls ) : <EOL> prior_balls = self . _balls <EOL> ball_change = balls - prior_balls <EOL> if ball_change : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , prior_balls , balls , ball_change ) <EOL> if balls >= <NUM_LIT:0> : <EOL> self . _balls = balls <EOL> else : <EOL> self . log . warning ( "<STR_LIT>" <EOL> "<STR_LIT>" , balls ) <EOL> self . _balls = <NUM_LIT:0> <EOL> self . unexpected_balls = <NUM_LIT:0> <EOL> self . log . debug ( "<STR_LIT>" , <EOL> self . _balls , prior_balls ) <EOL> if ball_change > <NUM_LIT:0> : <EOL> self . machine . events . post_relay ( '<STR_LIT>' + self . name + <EOL> '<STR_LIT>' , new_balls = ball_change , <EOL> unclaimed_balls = ball_change ) <EOL> if ball_change : <EOL> self . machine . events . post ( self . name + '<STR_LIT>' , <EOL> balls = balls , change = ball_change ) <EOL> def count_balls ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> return <NUM_LIT:0> <EOL> def get_additional_ball_capacity ( self ) : <EOL> """<STR_LIT>""" <EOL> return <NUM_LIT> <EOL> def add_ball ( self , balls = <NUM_LIT:1> , source_name = None , source_device = None , <EOL> player_controlled = False , reset = False ) : <EOL> """<STR_LIT>""" <EOL> if balls < <NUM_LIT:1> : <EOL> self . log . error ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return False <EOL> if source_device : <EOL> pass <EOL> elif source_name and source_name in self . machine . ball_devices : <EOL> source_device = self . machine . ball_devices [ source_name ] <EOL> else : <EOL> for device in self . machine . ball_devices . items_tagged ( '<STR_LIT>' ) : <EOL> if self in device . config [ '<STR_LIT>' ] : <EOL> source_device = device <EOL> break <EOL> if not source_device : <EOL> self . log . critical ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return False <EOL> if reset : <EOL> source_device . stop ( ) <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , balls , <EOL> source_device . name , player_controlled ) <EOL> if player_controlled : <EOL> source_device . setup_player_controlled_eject ( balls = balls , <EOL> target = self ) <EOL> else : <EOL> source_device . eject ( balls = balls , target = self , get_ball = True ) <EOL> return True <EOL> def mark_playfield_active ( self ) : <EOL> self . machine . events . post_boolean ( self . name + "<STR_LIT>" ) <EOL> def playfield_switch_hit ( self , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if ( not self . balls or ( kwargs . get ( '<STR_LIT>' ) and self . balls - kwargs [ '<STR_LIT>' ] < <NUM_LIT:0> ) ) : <EOL> self . mark_playfield_active ( ) <EOL> if not self . num_balls_requested : <EOL> if self . machine . game : <EOL> self . unexpected_balls = <NUM_LIT:1> <EOL> if self . machine . config [ '<STR_LIT>' ] [ '<STR_LIT>' ] : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> self . balls = <NUM_LIT:1> <EOL> self . machine . events . post ( '<STR_LIT>' + self . name ) <EOL> def _ball_removed_handler ( self , balls , ** kwargs ) : <EOL> self . _count_consistent = False <EOL> self . machine . events . post ( '<STR_LIT>' + self . name + "<STR_LIT>" , <EOL> callback = self . _ball_removed_handler2 , balls = balls ) <EOL> def _ball_removed_handler2 ( self , balls ) : <EOL> self . log . debug ( "<STR_LIT>" , balls ) <EOL> self . balls -= balls <EOL> self . _count_consistent = True <EOL> def _source_device_eject_attempt ( self , balls , target , ** kwargs ) : <EOL> if target == self : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , balls ) <EOL> self . num_balls_requested += balls <EOL> def _source_device_eject_failed ( self , balls , target , ** kwargs ) : <EOL> if target == self : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , balls ) <EOL> self . num_balls_requested -= balls <EOL> def _source_device_eject_success ( self , balls , target ) : <EOL> if target == self : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" , balls ) <EOL> self . balls += balls <EOL> self . num_balls_requested -= balls <EOL> if self . num_balls_requested < <NUM_LIT:0> : <EOL> self . log . critical ( "<STR_LIT>" <EOL> "<STR_LIT>" , <EOL> self . num_balls_requested ) <EOL> raise Exception ( "<STR_LIT>" <EOL> "<STR_LIT>" , self . num_balls_requested ) <EOL> def ok_to_confirm_ball_via_playfield_switch ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . balls : <EOL> return True <EOL> else : <EOL> return False <EOL> def ball_search_schedule ( self , secs = None , force = False ) : <EOL> """<STR_LIT>""" <EOL> if self . machine . config [ '<STR_LIT>' ] : <EOL> if not self . flag_no_ball_search or force is True : <EOL> if secs is not None : <EOL> start_ms = secs * <NUM_LIT:1000> <EOL> else : <EOL> start_ms = ( self . machine . config [ '<STR_LIT>' ] <EOL> [ '<STR_LIT>' ] * <NUM_LIT:1000> ) <EOL> self . log . debug ( "<STR_LIT>" , <EOL> start_ms / <NUM_LIT> ) <EOL> self . delay . reset ( "<STR_LIT>" , <EOL> ms = start_ms , <EOL> callback = self . ball_search_begin ) <EOL> def ball_search_disable ( self ) : <EOL> """<STR_LIT>""" <EOL> self . log . debug ( "<STR_LIT>" ) <EOL> self . delay . remove ( '<STR_LIT>' ) <EOL> def ball_search_begin ( self , force = False ) : <EOL> """<STR_LIT>""" <EOL> if not self . flag_no_ball_search : <EOL> self . log . debug ( "<STR_LIT>" ) <EOL> if self . balls or force : <EOL> self . flag_ball_search_in_progress = True <EOL> self . machine . events . post ( "<STR_LIT>" ) <EOL> else : <EOL> self . log . debug ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> def ball_search_failed ( self ) : <EOL> """<STR_LIT>""" <EOL> self . log . debug ( "<STR_LIT>" ) <EOL> self . ball_search_end ( ) <EOL> self . ball_lost ( ) <EOL> def ball_search_end ( self ) : <EOL> """<STR_LIT>""" <EOL> self . log . debug ( "<STR_LIT>" ) <EOL> self . flag_ball_search_in_progress = False <EOL> self . machine . events . post ( "<STR_LIT>" ) <EOL> def ball_lost ( self ) : <EOL> """<STR_LIT>""" <EOL> self . num_balls_known = self . balls <EOL> self . num_balls_missing = ( self . machine . config [ '<STR_LIT>' ] <EOL> [ '<STR_LIT>' ] - self . balls ) <EOL> self . num_balls_live = <NUM_LIT:0> <EOL> self . log . debug ( "<STR_LIT>" , <EOL> self . num_balls_known , self . num_balls_missing ) <EOL> def ball_found ( self , num = <NUM_LIT:1> ) : <EOL> """<STR_LIT>""" <EOL> self . log . debug ( "<STR_LIT>" , num ) <EOL> self . num_balls_known += num <EOL> self . num_balls_missing -= num <EOL> self . log . debug ( "<STR_LIT>" , <EOL> self . num_balls_known , self . num_balls_missing ) <EOL> self . ball_update_all_counts ( ) <EOL> def eject ( self , * args , ** kwargs ) : <EOL> pass <EOL> def eject_all ( self , * args , ** kwargs ) : <EOL> pass <EOL> def is_playfield ( self ) : <EOL> return True <EOL> def add_incoming_ball ( self , source ) : <EOL> pass <EOL> def remove_incoming_ball ( self , source ) : <EOL> pass </s>
