Module: Inform::Game::Loader

Included in:
Runtime
Defined in:
lib/runtime/game_loader.rb

Overview

The Game::Loader module loads a game from a given directory.

Constant Summary collapse

EnsureFirst =
[/emotes.inf/, /grammar.inf/].freeze
GrammarParsedInfoMessage =
'Parsed grammar %<file>s in %0.2<elapsed>f milliseconds'.freeze

Instance Method Summary collapse

Instance Method Details

#first_orphan_object_with_description_that_has_lightObject



41
42
43
# File 'lib/runtime/game_loader.rb', line 41

def first_orphan_object_with_description_that_has_light
  Inform::Object.all.find { |o| !o.description.nil? && o.has?(:light) }&.name
end

#grammar_filesObject



100
101
102
103
104
105
106
# File 'lib/runtime/game_loader.rb', line 100

def grammar_files
  files = Dir.glob(File.join(grammar_module_path, '*'))
  EnsureFirst.each do |pattern|
    prioritize_if(files) { |file_path| file_path.match?(pattern) }
  end
  files
end

#handle_load_failure(e) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# File 'lib/runtime/game_loader.rb', line 80

def handle_load_failure(e)
  case e.message
  when /PG::UndefinedTable/
    log.error "Fatal: Database initialization is required"
    abort
  else
    log.error "Error loading game: #{e.class.name}: #{e.message}"
    e.backtrace.each { |t| log.error t }
  end
end

#load_game(game_dir_path = Inform::Game.config[:game_path]) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/runtime/game_loader.rb', line 29

def load_game(game_dir_path = Inform::Game.config[:game_path])
  self.load_path = game_dir_path
  require_relative 'world_tree'
  load_game_subcomponents
  load_game_files
  load_grammars
  reset_constants
  load_library
rescue StandardError => e
  handle_load_failure(e)
end

#load_game_files(game_path = @game_dir_path) ⇒ Object



71
72
73
74
75
76
77
78
# File 'lib/runtime/game_loader.rb', line 71

def load_game_files(game_path = @game_dir_path)
  log.info "Loading game: #{game_path}"
  Dir.glob(File.join(game_path, '*.rb')).sort.each do |file|
    next unless File.file?(file)
    log.debug "Loading file: #{file}"
    require file
  end
end

#load_game_statesObject



119
120
121
122
# File 'lib/runtime/game_loader.rb', line 119

def load_game_states
  states = Inform::Game.config.fetch(:additional_promiscuous_states, []).map(&:to_sym)
  Session.add_promiscuous_states(states)
end

#load_game_sub(component, start = Time.now) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
# File 'lib/runtime/game_loader.rb', line 59

def load_game_sub(component, start = Time.now)
  game_component_path = File.join(@game_dir_path, component.to_s)
  Dir.glob(File.join(game_component_path, '*')).sort.each do |file|
    next unless File.file?(file)
    log.debug "Loading file: #{file}"
    require file
  end
ensure
  elapsed = (Time.now - start) * 1000
  log.debug format("Loaded #{component} in %0.2f milliseconds", elapsed)
end

#load_game_subcomponentsObject



50
51
52
# File 'lib/runtime/game_loader.rb', line 50

def load_game_subcomponents
  game_components.each { |component| load_game_sub(component) }
end

#load_grammarsObject



110
111
112
113
114
115
116
117
# File 'lib/runtime/game_loader.rb', line 110

def load_grammars
  grammar_files.each do |file_path|
    start = Time.now
    Inform.load_grammar_by_path(file_path)
    elapsed = (Time.now - start) * 1000
    log.debug format(GrammarParsedInfoMessage, file: File.basename(file_path), elapsed: elapsed)
  end
end

#load_path=(path) ⇒ Object



45
46
47
48
# File 'lib/runtime/game_loader.rb', line 45

def load_path=(path)
  @game_dir_path = path
  $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
end

#prioritize_if(list, &condition) ⇒ Object

Move to the front of the list any element matching the given condition



92
93
94
95
96
# File 'lib/runtime/game_loader.rb', line 92

def prioritize_if(list, &condition)
  element = list.find(&condition)
  return list if element.nil?
  list.unshift(list.delete(element))
end

#reload_gameObject



124
125
126
# File 'lib/runtime/game_loader.rb', line 124

def reload_game
  load_game
end

#reset_constantsObject



54
55
56
57
# File 'lib/runtime/game_loader.rb', line 54

def reset_constants
  reset_constant(:HDR_GAMESERIAL, defined?(Serial) ? Serial : File.mtime(@game_dir_path).strftime('%y%m%d'))
  reset_constant(:HDR_GAMERELEASE, defined?(Release) ? Release : 0)
end