コード例 #1
0
ファイル: config_processor.py プロジェクト: unRARed/mpf
    def _load_config_file_and_return_loaded_files(
        self,
        filename,
        config_type: str,
        ignore_unknown_sections=False
    ) -> Tuple[dict, List[str]]:  # pragma: no cover
        """Load a config file and return loaded files."""
        # config_type is str 'machine' or 'mode', which specifies whether this
        # file being loaded is a machine config or a mode config file
        expected_version_str = ConfigProcessor.get_expected_version(
            config_type)

        config = FileManager.load(filename, expected_version_str, True)
        subfiles = []

        if not ConfigValidator.config_spec:
            ConfigValidator.load_config_spec()

        if not config:
            return dict(), []

        self.log.info('Loading config: %s', filename)

        if config_type in ("machine", "mode"):
            if not isinstance(config, dict):
                raise ConfigFileError(
                    "Config should be a dict: {}".format(config),
                    self.log.name, "ConfigProcessor")
            for k in config.keys():
                try:
                    if config_type not in ConfigValidator.config_spec[k][
                            '__valid_in__']:
                        raise ValueError(
                            'Found a "{}:" section in config file {}, '
                            'but that section is not valid in {} config '
                            'files.'.format(k, filename, config_type))
                except KeyError:
                    if not ignore_unknown_sections:
                        raise ValueError(
                            'Found a "{}:" section in config file {}, '
                            'but that section is not valid in {} config '
                            'files.'.format(k, filename, config_type))

        try:
            if 'config' in config:
                path = os.path.split(filename)[0]

                for file in Util.string_to_list(config['config']):
                    full_file = os.path.join(path, file)
                    subfiles.append(full_file)
                    subconfig, subsubfiles = self._load_config_file_and_return_loaded_files(
                        full_file, config_type)
                    subfiles.extend(subsubfiles)
                    config = Util.dict_merge(config, subconfig)
            return config, subfiles
        except TypeError:
            return dict(), []
コード例 #2
0
ファイル: config_processor.py プロジェクト: sushobhit27/mpf
    def load_config_file(
            filename,
            config_type: str,
            ignore_unknown_sections=False) -> dict:  # pragma: no cover
        """Load a config file."""
        # config_type is str 'machine' or 'mode', which specifies whether this
        # file being loaded is a machine config or a mode config file
        expected_version_str = ConfigProcessor.get_expected_version(
            config_type)
        config = FileManager.load(filename, expected_version_str, True)

        if not ConfigValidator.config_spec:
            ConfigValidator.load_config_spec()

        if not config:
            return dict()

        for k in config.keys():
            try:
                if config_type not in ConfigValidator.config_spec[k][
                        '__valid_in__']:
                    raise ValueError(
                        'Found a "{}:" section in config file {}, '
                        'but that section is not valid in {} config '
                        'files.'.format(k, filename, config_type))
            except KeyError:
                if not ignore_unknown_sections:
                    raise ValueError(
                        'Found a "{}:" section in config file {}, '
                        'but that section is not valid in {} config '
                        'files.'.format(k, filename, config_type))

        try:
            if 'config' in config:
                path = os.path.split(filename)[0]

                for file in Util.string_to_list(config['config']):
                    full_file = os.path.join(path, file)
                    config = Util.dict_merge(
                        config,
                        ConfigProcessor.load_config_file(
                            full_file, config_type))
            return config
        except TypeError:
            return dict()
コード例 #3
0
ファイル: config_processor.py プロジェクト: sushobhit27/mpf
    def load_config_files_with_cache(
            self,
            filenames: List[str],
            config_type: str,
            load_from_cache=True,
            store_to_cache=True,
            ignore_unknown_sections=False) -> dict:  # pragma: no cover
        """Load multiple configs with a combined cache."""
        config = dict()  # type: Any
        # Step 1: Check timestamps of the filelist vs cache
        cache_file = self.get_cache_filename(filenames)
        if load_from_cache:
            cache_time = self._get_mtime_or_negative(cache_file)
            if cache_time < 0:
                load_from_cache = False

        if load_from_cache:
            for configfile in filenames:
                if not os.path.isfile(configfile) or os.path.getmtime(
                        configfile) > cache_time:
                    load_from_cache = False
                    self.log.warning('Config file in cache changed: %s',
                                     configfile)
                    break

        # Step 2: Get cache content
        if load_from_cache:
            config, loaded_files = self._load_config_from_cache(cache_file)
            if not config:
                load_from_cache = False
        else:
            loaded_files = None

        # Step 3: Check timestamps of included files vs cache
        if loaded_files:
            for configfile in loaded_files:
                if not os.path.isfile(configfile) or os.path.getmtime(
                        configfile) > cache_time:
                    load_from_cache = False
                    self.log.warning('Config file in cache changed: %s',
                                     configfile)
                    break

        # Step 4: Return cache
        if load_from_cache:
            return config

        # Step 5: If we did not get it from cache load it from files
        if not ConfigValidator.config_spec:
            ConfigValidator.load_config_spec()

        config = dict()
        loaded_files = []
        for configfile in filenames:
            self.log.info('Loading config from file %s.', configfile)
            file_config, file_subfiles = self._load_config_file_and_return_loaded_files(
                configfile, config_type, ignore_unknown_sections)
            loaded_files.extend(file_subfiles)
            config = Util.dict_merge(config, file_config)

        # Step 6: Store to cache
        if store_to_cache:
            with open(cache_file, 'wb') as f:
                pickle.dump((config, loaded_files), f, protocol=4)
                self.log.info('Config file cache created: %s', cache_file)

        return config
コード例 #4
0
ファイル: mc.py プロジェクト: elliotstarks/mpf-mc
    def __init__(self, options, config, machine_path,
                 thread_stopper=None, **kwargs):

        self.log = logging.getLogger('mpfmc')
        self.log.info("Mission Pinball Framework Media Controller v%s", __version__)
        self.log.info("Mission Pinball Framework Game Engine v%s", __mpfversion__)

        if (__version__.split('.')[0] != __mpfversion__.split('.')[0] or
                __version__.split('.')[1] != __mpfversion__.split('.')[1]):

            self.log.error("MPF MC and MPF Game engines must be same "
                           "major.minor versions. You have MPF v{} and MPF-MC"
                           " v{}".format(__mpfversion__, __version__))

            raise ValueError("MPF MC and MPF Game engines must be same "
                           "major.minor versions. You have MPF v{} and MPF-MC"
                           " v{}".format(__mpfversion__, __version__))

        super().__init__(**kwargs)

        self.options = options
        self.machine_config = config
        self.log.info("Machine path: %s", machine_path)
        self.machine_path = machine_path
        self.clock = Clock
        # pylint: disable-msg=protected-access
        self.log.info("Starting clock at %sHz", Clock._max_fps)
        self._boot_holds = set()
        self.mpf_path = os.path.dirname(mpf.__file__)
        self.modes = CaseInsensitiveDict()
        self.player_list = list()
        self.player = None
        self.num_players = 0
        self.bcp_client_connected = False
        self.placeholder_manager = McPlaceholderManager(self)
        self.settings = McSettingsController(self)

        self.animation_configs = dict()
        self.active_slides = dict()
        self.scriptlets = list()

        self.register_boot_hold('init')
        self.displays = CaseInsensitiveDict()
        self.machine_vars = CaseInsensitiveDict()
        self.machine_var_monitor = False
        self.monitors = dict()
        self.targets = dict()
        """Dict which contains all the active slide frames in the machine that
        a slide can target. Will always contain an entry called 'default'
        which will be used if a slide doesn't specify targeting.
        """

        self.keyboard = None
        self.physical_dmds = []
        self.physical_rgb_dmds = []
        self.crash_queue = queue.Queue()
        self.ticks = 0
        self.start_time = 0
        self.is_init_done = False

        if thread_stopper:
            self.thread_stopper = thread_stopper
        else:
            self.thread_stopper = threading.Event()

        # Core components
        self.config_validator = ConfigValidator(self)
        self.events = EventManager(self)
        self.mode_controller = ModeController(self)
        create_config_collections(self, self.machine_config['mpf-mc']['config_collections'])
        ConfigValidator.load_config_spec()

        self.config_processor = ConfigProcessor(self)
        self.transition_manager = TransitionManager(self)

        self._set_machine_path()

        self._load_font_paths()

        # Initialize the sound system (must be done prior to creating the AssetManager).
        # If the sound system is not available, do not load any other sound-related modules.
        if SoundSystem is None:
            self.sound_system = None
        else:
            self.sound_system = SoundSystem(self)

        self.asset_manager = ThreadedAssetManager(self)
        self.bcp_processor = BcpProcessor(self)

        # Asset classes
        ImageAsset.initialize(self)
        VideoAsset.initialize(self)

        self._initialise_sound_system()

        self.clock.schedule_interval(self._check_crash_queue, 1)

        self.events.add_handler("client_connected", self._create_physical_dmds)
        self.events.add_handler("player_turn_start", self.player_start_turn)