Files
2025-09-29 00:52:08 +02:00

221 lines
7.3 KiB
Ruby
Executable File

#
# File:: pipeline/projectutil/RAVE/data_convert.rb
# Description:: RAVE data conversion functions.
#
# Author:: David Muir <david.muir@rockstarnorth.com>
# Date:: 16 November 2009
#
#----------------------------------------------------------------------------
# Uses
#----------------------------------------------------------------------------
require 'pipeline/config/projects'
require 'pipeline/config/project'
require 'pipeline/log/log'
require 'pipeline/os/path'
require 'pipeline/util/environment'
require 'pipeline/util/rage'
include Pipeline
require 'REXML/document'
#-----------------------------------------------------------------------------
# Functions
#-----------------------------------------------------------------------------
module Pipeline
module ProjectUtil
module RAVE
#
# Return the Project and Branch objects for an Array of audio-filenames.
# If the files belong to multiple projects or branches a RuntimeError
# exception is raised.
#
# The optional block is executed with the project, branch and filename
# String.
#
# == Example Usage
# DHM TODO
#
def RAVE::get_project_from_filenames( filenames, &block )
raise ArgumentError.new( "Invalid Array of filenames (#{filenames.class})." ) \
unless ( filenames.is_a?( Array ) )
config = Pipeline::Config::instance()
conv_project = nil
conv_branch = nil
filenames.each do |filename|
throw IOError.new( "File #{filename} does not exist or is not readable." ) \
unless ( ::File::exists?( filename ) and ::File::readable?( filename ) )
filename = OS::Path::normalise( File::expand_path( filename ) )
config.projects.each_pair do |name, project|
next unless ( filename.starts_with( project.root ) )
project.load_config( )
project.branches.each_pair do |branch_name, branch|
next unless ( branch.is_audio_file?( filename ) )
throw RuntimeError.new( "Audio files from multiple projects, invalid conversion." ) \
unless ( conv_project.nil? or project == conv_project )
throw RuntimeError.new( "Audio files from multiple branches, invalid conversion." ) \
unless ( conv_branch.nil? or branch == conv_branch )
conv_project = project
conv_branch = branch
# Call user-block
yield( conv_project, conv_branch, filename ) \
if ( block_given? and ( not ( conv_project.nil? or conv_branch.nil? ) ) )
end
end
end
# Return project and branch.
[ conv_project, conv_branch ]
end
#
# Return project settings file for a particular Project.
#
def RAVE::get_project_settings_filename( project, branch = nil )
throw ArgumentError.new( "Invalid Project object (#{project.class})." ) \
unless ( project.is_a?( Pipeline::Project ) )
throw ArgumentError.new( "Invalid Branch object (#{branch.class})." ) \
unless ( branch.nil? or branch.is_a?( Pipeline::Branch ) )
env = Environment::new()
branch.fill_env( env ) unless ( branch.nil? )
project.fill_env( env ) if ( branch.nil? )
env.subst( "$(audio)/ProjectSettings.xml" )
end
#
# Return project RAVE assets path.
#
def RAVE::get_project_assets_path( project, branch = nil )
throw ArgumentError.new( "Invalid Project object (#{project.class})." ) \
unless ( project.is_a?( Pipeline::Project ) )
throw ArgumentError.new( "Invalid Branch object (#{branch.class})." ) \
unless ( branch.nil? or branch.is_a?( Pipeline::Branch ) )
env = Environment.new()
branch.fill_env( env ) unless ( branch.nil? )
project.fill_env( env ) if ( branch.nil? )
OS::Path::normalise( env.subst( "$(audio)/assets/Objects/" ) )
end
#
# Return RAVE metadata categories for a project/branch as a Hash, mapping
# category String to input file(s) path.
#
# == Example Usage
# DHM TODO.
#
def RAVE::get_project_metadata_tags( project, branch = nil )
settings_file = RAVE::get_project_settings_filename( project, branch )
tags = {}
File::open( settings_file ) do |file|
doc = REXML::Document.new( file )
doc.elements.each( 'ProjectSettings/MetadataSettings/MetadataFile' ) do |xml_node|
name = xml_node.elements['Name'].text.to_s
path = OS::Path::normalise( xml_node.elements['DataPath'].text.to_s )
tags[name] = path
end
end
tags
end
#
# Return RAVE metadata category for a project/branch and a particular
# filename. The filename's path is matched based on its prefix directory,
# so any file under a particular metadata directory should correctly be
# determined.
#
# Returns nil if we cannot find a valid tag. Otherwise the tag as String
# is returned.
#
def RAVE::get_project_metadata_tag_for_filename( project, branch, filename )
tags = RAVE::get_project_metadata_tags( project, branch )
prefix = RAVE::get_project_assets_path( project, branch )
filename = OS::Path::normalise( filename )
return ( nil ) unless ( filename.starts_with( prefix ) )
# Loop through our tags trying to find the correct tag for the path.
tags.each do |name, path|
fullpath = OS::Path::combine( prefix, path )
next unless ( filename.starts_with( fullpath ) )
return ( name )
end
nil
end
#
# Convert a file or Array of files from their absolute filename only.
# The project, branch and mc.exe location is determined and the conversion
# done.
#
# == Assumptions
# Metadata compiler path: $(toolsbin)/mc/mc.exe.
#
def RAVE::data_convert_file( filenames, &block )
filenames = [ filenames ] unless ( filenames.is_a?( Array ) )
config = Pipeline::Config::instance( )
conv_project, conv_branch = RAVE::get_project_from_filenames( filenames )
env = Environment.new
conv_branch.fill_env( env )
settings_file = RAVE::get_project_settings_filename( conv_project, conv_branch )
tags = get_project_metadata_tags( conv_project, conv_branch )
filenames.each do |filename|
metadata = RAVE::get_project_metadata_tag_for_filename( conv_project, conv_branch, filename )
# For each project target.
conv_project.targets.each do |platform, target|
next unless ( target.enabled )
plat = RageUtils::rage_platform( platform ).upcase
commandline = "$(toolsbin)/mc/mc.exe -project #{settings_file} -platform #{plat} -metadata #{metadata} -workingPath x:/"
commandline = env.subst( commandline )
RAVE::log().info( "Starting RAVE metadata compiler..." )
RAVE::log().info( "#{commandline}" )
status, sout, serr = OS::start( commandline )
case status.exitstatus
when 0
RAVE::log().info( "RAVE metadata compiler exited ok." )
sout.each do |m| RAVE::log().info( m ); end
else
RAVE::log().error( "Error invoking RAVE metadata compiler: #{status.exitstatus}." )
sout.each do |m| RAVE::log().info( m ); end
serr.each do |m| RAVE::log().error( m ); end
end
end
end
end
# Return module-wide log object.
def RAVE::log()
@@log = Log.new( 'rave' ) if ( @@log.nil? )
@@log
end
#------------------------------------------------------------------------
# Private
#------------------------------------------------------------------------
private
@@log = nil
end # RAVE module
end # ProjectUtil module
end # Pipeline module
# pipeline/projectutil/RAVE/data_convert.rb