133 lines
3.9 KiB
Ruby
Executable File
133 lines
3.9 KiB
Ruby
Executable File
#
|
|
# File:: levels.rb
|
|
# Description:: Levels.xml and <level>.dat file parser.
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 26 November 2008
|
|
#
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Uses
|
|
#----------------------------------------------------------------------------
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/util/string'
|
|
require 'rexml/document'
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Implementation
|
|
#----------------------------------------------------------------------------
|
|
module Pipeline
|
|
|
|
#
|
|
# == Description
|
|
# The Pipeline::Levels class defines a levels.xml parser and <level>.dat file
|
|
# parser for fetching information about a level. The concept of levels was
|
|
# first introduced in Jimmy.
|
|
#
|
|
class Levels
|
|
attr_reader :project # Project reference
|
|
attr_reader :branch # Branch reference
|
|
attr_reader :filename # String filename of levels.xml file.
|
|
attr_reader :levels # Hash of level uiname to Level objects.
|
|
|
|
def initialize( project, branch, filename )
|
|
throw ArgumentError.new( "Invalid project object (#{project.class})." ) \
|
|
unless ( project.is_a?( Pipeline::Project ) )
|
|
throw ArgumentError.new( "Invalid branch object (#{branch.class})." ) \
|
|
unless ( branch.is_a?( Pipeline::Branch ) )
|
|
project.load_config( )
|
|
|
|
@project = project
|
|
@branch = branch
|
|
@filename = filename
|
|
@levels = {}
|
|
|
|
File.open( @filename ) do |fp|
|
|
xmldoc = REXML::Document.new( fp )
|
|
xmldoc.elements.each( 'levels/level' ) do |xml_node|
|
|
|
|
level = Level::from_xml( xml_node, self )
|
|
throw RuntimeError.new( "Duplicate level data, key #{level.uiname} already used." ) \
|
|
if ( @levels.has_key?( level.uiname ) )
|
|
|
|
@levels[level.uiname] = level
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# The Pipeline::Level class defines data read from the levels.xml file and
|
|
# the <level>.dat file - essentially a mapping of file type to a filename.
|
|
#
|
|
# The filenames returned have environment values ready for substitution.
|
|
#
|
|
class Level
|
|
attr_reader :levels # Reference to owning Levels object.
|
|
attr_reader :uiname # Level friendlyname
|
|
attr_reader :title # Level title string
|
|
attr_reader :dat_filename # String filename of <level>.dat file.
|
|
attr_reader :dat # Hash of file type String keys to filenames
|
|
|
|
def initialize( levels, uiname, title, dat_filename )
|
|
@levels = levels
|
|
@uiname = uiname
|
|
@title = title
|
|
@levels.branch.in_env do |env|
|
|
@dat_filename = env.subst( dat_filename )
|
|
end
|
|
@dat = {}
|
|
|
|
parse_dat( )
|
|
end
|
|
|
|
#
|
|
# Create a Level object from an XML node.
|
|
#
|
|
def Level::from_xml( xml_node, levels )
|
|
uiname = xml_node.attributes['friendlyName']
|
|
title = xml_node.attributes['title']
|
|
filename = xml_node.attributes['filename']
|
|
filename.gsub!( 'common:', '$(common)' )
|
|
|
|
Level.new( levels, uiname, title, filename )
|
|
end
|
|
|
|
#--------------------------------------------------------------------------
|
|
# Private Methods
|
|
#--------------------------------------------------------------------------
|
|
private
|
|
def parse_dat( )
|
|
|
|
dat_data = []
|
|
File::open( @dat_filename ) do |fp|
|
|
dat_data = fp.readlines( )
|
|
end
|
|
|
|
dat_data.each do |line|
|
|
# Ignore comments and empty lines
|
|
line.strip!
|
|
next if ( 0 == line.size )
|
|
next if ( line.starts_with( '#' ) )
|
|
|
|
# Replace common: and platform: with our environment tokens.
|
|
line_dup = line.dup
|
|
line_dup.gsub!( /common:/i, '$(common)' )
|
|
line_dup.gsub!( /platform:/i, '$(platform)' )
|
|
|
|
@levels.branch.in_env do |env|
|
|
parts = line_dup.split( ' ' )
|
|
key = parts[0].upcase
|
|
file = env.subst( OS::Path::normalise( parts[1] ) )
|
|
|
|
@dat[key] = [] unless ( @dat.has_key?( key ) )
|
|
@dat[key] << file
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# levels.rb
|