Module: StoryTeller::Game::Loader
- Included in:
- Runtime
- Defined in:
- lib/story_teller/game/loader.rb
Overview
The Game::Loader module loads a game from a given directory.
Constant Summary collapse
- PreGameComponents =
%i[modules].freeze
- EnsureFirst =
[/emotes.inf/, /grammar.inf/].freeze
- GrammarParsedInfoMessage =
'Parsed grammar %<file>s in %0.2<elapsed>f milliseconds'.freeze
Instance Method Summary collapse
- #first_orphan_object_with_description_that_has_light ⇒ Object
- #game_files(game_path) ⇒ Object
- #game_serial ⇒ Object
- #grammar_files ⇒ Object
- #handle_load_failure(e) ⇒ Object
- #load_game(game_dir_path = game_path) ⇒ Object
-
#load_game_files(game_path = @game_dir_path) ⇒ Object
def load_game_files(game_path = @game_dir_path) log.info “Loading story game #gamegame.name from #game_path” Dir.glob(File.join(game_path, ‘*.rb’)).each do |file| next unless File.file?(file) log.trace “Loading file: #file” require file end log.debug “Loaded story game #gamegame.name” end.
- #load_game_files_with_committing(game_path) ⇒ Object
- #load_game_files_without_committing(game_path) ⇒ Object
- #load_game_states ⇒ Object
- #load_game_sub(component, start = Time.now) ⇒ Object
- #load_game_subcomponents(components = game_components) ⇒ Object
- #load_grammars ⇒ Object
- #load_library ⇒ Object
- #load_path=(path) ⇒ Object
- #post_game_components ⇒ Object
- #pre_game_components ⇒ Object
- #preserve_persisted_world? ⇒ Boolean
-
#prioritize_if(list, &condition) ⇒ Object
Move to the front of the list any element matching the given condition.
- #refresh_preserved_world_object(object, preserved_ids) ⇒ Object
- #refresh_preserved_world_objects(preserved_ids) ⇒ Object
- #release ⇒ Object
- #reload_game ⇒ Object
- #reset_constants ⇒ Object
- #same_path?(first, second) ⇒ Boolean
- #top_level_game_path(game_dir_path) ⇒ Object
Instance Method Details
#first_orphan_object_with_description_that_has_light ⇒ Object
106 107 108 |
# File 'lib/story_teller/game/loader.rb', line 106 def first_orphan_object_with_description_that_has_light Inform::Object.all.find { |o| !o.description.nil? && o.has?(:light) }&.name end |
#game_files(game_path) ⇒ Object
185 186 187 188 189 |
# File 'lib/story_teller/game/loader.rb', line 185 def game_files(game_path) return [game_path] if File.file?(game_path) Dir.glob(File.join(game_path, '*.rb')).select { |file| File.file?(file) } end |
#game_serial ⇒ Object
132 133 134 |
# File 'lib/story_teller/game/loader.rb', line 132 def game_serial defined?(::Serial) ? ::Serial : File.mtime(@game_dir_path).strftime('%y%m%d') end |
#grammar_files ⇒ Object
238 239 240 241 242 243 244 |
# File 'lib/story_teller/game/loader.rb', line 238 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
218 219 220 221 222 223 224 225 226 227 |
# File 'lib/story_teller/game/loader.rb', line 218 def handle_load_failure(e) case e. when /PG::UndefinedTable/ log.error "Fatal: Database initialization is required" abort else log.error "Error loading game: #{e.class.name}: #{e.}" e.backtrace.each { |t| log.error t } end end |
#load_game(game_dir_path = game_path) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/story_teller/game/loader.rb', line 83 def load_game(game_dir_path = game_path) self.load_path = game_dir_path load_game_subcomponents(pre_game_components) load_game_files(top_level_game_path(game_dir_path)) load_library load_game_subcomponents(post_game_components) load_grammars reset_constants rescue StandardError => e handle_load_failure(e) raise end |
#load_game_files(game_path = @game_dir_path) ⇒ Object
def load_game_files(game_path = @game_dir_path)
log.info "Loading story game #{game.name} from #{game_path}"
Dir.glob(File.join(game_path, '*.rb')).each do |file|
next unless File.file?(file)
log.trace "Loading file: #{file}"
require file
end
log.debug "Loaded story game #{game.name}"
end
162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/story_teller/game/loader.rb', line 162 def load_game_files(game_path = @game_dir_path) log.info "Loading story game #{game.name} from #{game_path}" if preserve_persisted_world? load_game_files_without_committing(game_path) else load_game_files_with_committing(game_path) end log.debug "Loaded story game #{game.name}" end |
#load_game_files_with_committing(game_path) ⇒ Object
178 179 180 181 182 183 |
# File 'lib/story_teller/game/loader.rb', line 178 def load_game_files_with_committing(game_path) game_files(game_path).each do |file| log.trace "Loading file: #{file}" require file end end |
#load_game_files_without_committing(game_path) ⇒ Object
191 192 193 194 195 196 197 198 199 |
# File 'lib/story_teller/game/loader.rb', line 191 def load_game_files_without_committing(game_path) preserved_ids = persistence.world_object_ids persistence.without_committing! do load_game_files_with_committing(game_path) end refresh_preserved_world_objects(preserved_ids) end |
#load_game_states ⇒ Object
261 262 263 264 |
# File 'lib/story_teller/game/loader.rb', line 261 def load_game_states states = game.config.fetch(:additional_promiscuous_states, []).map(&:to_sym) Session.add_promiscuous_states(states) end |
#load_game_sub(component, start = Time.now) ⇒ Object
140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/story_teller/game/loader.rb', line 140 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, '*')).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_subcomponents(components = game_components) ⇒ Object
115 116 117 |
# File 'lib/story_teller/game/loader.rb', line 115 def load_game_subcomponents(components = game_components) components.each { |component| load_game_sub(component) } end |
#load_grammars ⇒ Object
248 249 250 251 252 253 254 255 |
# File 'lib/story_teller/game/loader.rb', line 248 def load_grammars grammar_files.each do |file_path| start = Time.now StoryTeller::Library::Loader.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_library ⇒ Object
257 258 259 |
# File 'lib/story_teller/game/loader.rb', line 257 def load_library StoryTeller::Library::Loader.load_library end |
#load_path=(path) ⇒ Object
110 111 112 113 |
# File 'lib/story_teller/game/loader.rb', line 110 def load_path=(path) @game_dir_path = path $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path) end |
#post_game_components ⇒ Object
123 124 125 |
# File 'lib/story_teller/game/loader.rb', line 123 def post_game_components game_components - pre_game_components end |
#pre_game_components ⇒ Object
119 120 121 |
# File 'lib/story_teller/game/loader.rb', line 119 def pre_game_components game_components & PreGameComponents end |
#preserve_persisted_world? ⇒ Boolean
174 175 176 |
# File 'lib/story_teller/game/loader.rb', line 174 def preserve_persisted_world? [:persist] && persistence.world_tree? end |
#prioritize_if(list, &condition) ⇒ Object
Move to the front of the list any element matching the given condition
230 231 232 233 234 |
# File 'lib/story_teller/game/loader.rb', line 230 def prioritize_if(list, &condition) element = list.find(&condition) return list if element.nil? list.unshift(list.delete(element)) end |
#refresh_preserved_world_object(object, preserved_ids) ⇒ Object
207 208 209 210 211 212 213 214 215 216 |
# File 'lib/story_teller/game/loader.rb', line 207 def refresh_preserved_world_object(object, preserved_ids) return if object.id.nil? unless preserved_ids.include?(object.id) raise GameLoadError, "Source object is missing from preserved world: #{object.object_name}" end object.associations.clear if object.respond_to?(:associations) object.refresh end |
#refresh_preserved_world_objects(preserved_ids) ⇒ Object
201 202 203 204 205 |
# File 'lib/story_teller/game/loader.rb', line 201 def refresh_preserved_world_objects(preserved_ids) ObjectSpace.each_object(Inform::Object) do |object| refresh_preserved_world_object(object, preserved_ids) end end |
#release ⇒ Object
136 137 138 |
# File 'lib/story_teller/game/loader.rb', line 136 def release defined?(::Release) ? ::Release : 0 end |
#reload_game ⇒ Object
266 267 268 |
# File 'lib/story_teller/game/loader.rb', line 266 def reload_game load_game end |
#reset_constants ⇒ Object
127 128 129 130 |
# File 'lib/story_teller/game/loader.rb', line 127 def reset_constants reset_constant(:HDR_GAMESERIAL, game_serial) reset_constant(:HDR_GAMERELEASE, release) end |
#same_path?(first, second) ⇒ Boolean
102 103 104 |
# File 'lib/story_teller/game/loader.rb', line 102 def same_path?(first, second) File.(first) == File.(second) end |
#top_level_game_path(game_dir_path) ⇒ Object
96 97 98 99 100 |
# File 'lib/story_teller/game/loader.rb', line 96 def top_level_game_path(game_dir_path) return game_dir_path unless same_path?(game_dir_path, game.path) game.file_path || game_dir_path end |