Files
gtav-src/tools_ng/lib/pipeline/resourcing/converters/converter_map.rb
T
2025-09-29 00:52:08 +02:00

233 lines
8.2 KiB
Ruby
Executable File

#
# File:: %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_map.rb
# Description:: Map data converter definition.
#
# Author:: David Muir <david.muir@rockstarnorth.com>
# Date:: 10 January 2010
#
# Content convert specifics for map assets. This class should not be
# used directly - use the ConvertSystem class instead.
#
#----------------------------------------------------------------------------
# Uses
#----------------------------------------------------------------------------
require 'pipeline/config/projects'
require 'pipeline/content/content_core'
require 'pipeline/content/content_maps'
require 'pipeline/resourcing/converter'
require 'pipeline/resourcing/converters/converter_map_assetcombine'
require 'pipeline/resourcing/converters/converter_map_collision'
require 'pipeline/resourcing/converters/converter_map_scenexml'
require 'pipeline/util/incredibuild'
#----------------------------------------------------------------------------
# Implementation
#----------------------------------------------------------------------------
module Pipeline
module Resourcing
module Converters
#
# == Description
# Map data root processor.
#
class MapConverter < ConverterBase
include HasConverterChildren
attr_reader :maps_output # Map child-converter output; Hash, by MapZip.
def initialize( project, branch )
super( project, branch )
initialize_children( )
@maps = []
@file_list = {}
# Add our child converters in the order they should be run.
add_child_converter( MapConverterAssetCombine::new( project, branch ) )
add_child_converter( MapConverterCollision::new( project, branch ) )
add_child_converter( MapConverterSceneXml::new( project, branch ) )
end
# Return whether this converter can convert the specified content node.
def can_convert?( content )
( content.is_a?( Content::ProcessedMapZip ) )
end
# Converter prebuild step.
def prebuild( )
end
# Build the map processed zip(s).
#
# This runs build for each child converter; each child returns a Hash
# optionally containing two keys, :output and :exclude.
#
# Files in the :output Array are included in the resultant zip; files
# in the :exclude Array are in the source zip but not taken across.
# Files listed in the :conversion Array are sent to the RageConverter
# (this is a way of injecting new assets into the 2nd->3rd pipeline step).
#
def build( &block )
MapConverter::log().info( "Map converter building #{@maps.size} processed map zips." )
@maps_output = {}
exclude_list = {}
conversion_list = []
maps_result = true
# Unpack map data.
@maps.each do |map|
prebuild_internal( map )
end
# Push map through all of the child converters; this allows the
# child converters to parallelise their processing.
@children.each do |child|
cres = child.build( @maps )
if ( cres.nil? ) then
maps_result = false
else
cres.each_pair do |map, result|
# Maps output has :exclude and :output keys
@maps_output[map] = {} unless ( @maps_output.has_key?( map ) )
@maps_output[map].merge!( result ) do |k, v1, v2|
[] + v1 + v2
end
conversion_list += result[:conversion] if ( result.has_key?( :conversion ) )
end
end
end
# Package up result after building up our data.
maps_result = true
@maps.each do |map|
additional_outputs = @maps_output[map][:output]
exclude_outputs = @maps_output[map][:exclude]
maps_result &= postbuild_internal( map, additional_outputs, exclude_outputs )
end
result = {}
result[:conversion] = conversion_list
result[:success] = maps_result
result
end
# Clear the content from the build list.
def clear( )
@maps.clear( )
@maps_output.clear( )
end
# Add the content to the build list (if valid).
def add_content( content )
if ( content.is_a?( Content::ProcessedMapZip ) ) then
@maps << content
@maps.uniq!
true
else
MapConverter::log().error( "Could not convert: #{content}." )
false
end
end
# Return raw map converter cache directory.
def MapConverter::cache_dir_raw( branch )
c = ConvertSystem::instance( )
maps = OS::Path::combine( c.cache_root, 'maps' )
FileUtils::mkdir_p(maps) \
unless ( File::directory?( maps ) )
maps
end
# Return map converter cache directory.
def MapConverter::cache_dir( branch, map )
throw ArgumentError::new( "Invalid Content::MapZip or Content::ProcessedMapZip object (#{map.class})." ) \
unless ( map.is_a?( Content::MapZip ) or map.is_a?( Content::ProcessedMapZip ) )
OS::Path::combine( MapConverter::cache_dir_raw( branch ), map.name )
end
# Return MapConverter log object.
def MapConverter::log()
@@log = Log.new( 'convert_map' ) if ( @@log.nil? )
@@log
end
# Return whether we should use XGE for processing; we only utilise it
# when its installed and there are more than one map section being processed.
def MapConverter::use_xge( maps )
config = Pipeline::Config::instance()
( config.use_xge and Incredibuild::is_installed?() and ( maps.size() > 1 ) )
end
#--------------------------------------------------------------------
# Private
#--------------------------------------------------------------------
private
@@log = nil
# Prebuild step; extracts the input zip files as required.
def prebuild_internal( map )
MapConverter::log().info( "Extracting processed map input files #{map.name}." )
@file_list[map] = []
cache_dir = MapConverter::cache_dir( @branch, map )
mapzip_files = map.inputs.collect do |mapzipinput|
mapzipinput.filename
end
mapzip_files.each do |zip|
if ( File::exists?( zip ) ) then
@file_list[map] += ProjectUtil::data_zip_extract3( zip, cache_dir, true )
else
MapConverter::log().error( "Dependency file does not exist: #{zip}." )
end
end
end
# Postbuild step; repackages the output zip files as required picking
# up the addition output and exclusion lists as required.
def postbuild_internal( map, output_list, exclude_list )
throw ArgumentError::new( "Invalid additional file output list (#{output_list.class})." ) \
unless ( output_list.is_a?( Array ) )
throw ArgumentError::new( "Invalid exclude file list (#{exclude_list.class})." ) \
unless ( exclude_list.is_a?( Array ) )
MapConverter::log().info( "Repackaging processed map: #{map.filename}." )
MapConverter::log().info( "\tExcluding: #{exclude_list.join(',')}" )
cache_dir = MapConverter::cache_dir( @branch, map )
mapzip_files = map.inputs.collect do |mapzipinput|
mapzipinput.filename
end
output_filename = map.filename
output_dir = OS::Path::get_directory( output_filename )
FileUtils::mkdir_p( output_dir ) \
unless ( File::directory?( output_dir ) )
# Determine the actual file list to create the Zip from.
actual_file_list = []
@file_list[map].each do |filename|
assetname = OS::Path::get_filename( filename )
actual_file_list << filename unless ( exclude_list.include?( assetname ) )
end
output_list.each do |filename|
actual_file_list << filename
end
ProjectUtil::data_zip_create( output_filename, actual_file_list, true )
end
end
end # Converters module
end # Resourcing module
end # Pipeline module
# %RS_TOOLSLIB%/pipeline/resourcing/converters/converter_map.rb