215 lines
7.0 KiB
Ruby
Executable File
215 lines
7.0 KiB
Ruby
Executable File
#
|
|
# File:: pipeline/util/autodeskMotionbuilder.rb
|
|
# Description:: Autodesk Motionbuilder Interface
|
|
#
|
|
# Author:: Mike Wilson <mike.wilson@rockstarnorth.com>
|
|
# Date:: 3 February 2011
|
|
#
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Uses
|
|
#----------------------------------------------------------------------------
|
|
require 'pipeline/config/projects'
|
|
require 'pipeline/os/path'
|
|
require 'pipeline/os/start'
|
|
require 'pipeline/os/sysinfo'
|
|
require 'pipeline/util/application'
|
|
require 'rexml/document'
|
|
require 'singleton'
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Implementation
|
|
#----------------------------------------------------------------------------
|
|
module Pipeline
|
|
|
|
#
|
|
# == Description
|
|
# Autodesk Motionbuilder application interface, to determine installed versions,
|
|
# install directories etc. Essentially a friendly wrapper for Motionbuilder for
|
|
# the Windows Registry that now copes with x86 registry on Windows x64.
|
|
#
|
|
class AutodeskMotionbuilder
|
|
include Singleton
|
|
|
|
#---------------------------------------------------------------------
|
|
# Public Constants
|
|
#---------------------------------------------------------------------
|
|
|
|
# Plugin direcotries for different verisons of max
|
|
# VERSION_DIRS = {
|
|
# 0.0 => 'maxBlank',
|
|
# 11.0 => 'max2009',
|
|
# 12.0 => 'max2010',
|
|
# 13.0 => 'max2011',
|
|
# 14.0 => 'max2012'
|
|
# }
|
|
|
|
#---------------------------------------------------------------------
|
|
# Public Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
# Class constructor ensures we only reg dump once.
|
|
def initialize( )
|
|
init( )
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return whether any versions of Autodesk's 3dsmax is installed on
|
|
# the local machine.
|
|
#
|
|
def is_installed?( )
|
|
( not ( @native.empty? and @x86.empty? ) )
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Get the root directory for max installations
|
|
#
|
|
def get_root_dir( )
|
|
"dcc/#{Pipeline::Config::instance().max_options.toolset_mode.to_s}/"
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return an array of installed 3dsmax versions (as floats).
|
|
#
|
|
def versions( )
|
|
( @native.keys + @x86.keys ).uniq
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return the latest installed version of Autodesk's 3dsmax on the local
|
|
# machine - nil if no versions are installed.
|
|
#
|
|
def latest_version( )
|
|
|
|
installed_versions = versions( )
|
|
installed_versions.sort!() do |x,y| y <=> x end
|
|
|
|
return installed_versions[0] if installed_versions.size > 0
|
|
return nil
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return a Hash of Hashes of installed versions (key) and their install
|
|
# locations (string path) for all installed 3dsmax versions (if their
|
|
# installdir is available in the Registry).
|
|
#
|
|
# Hash is of the form:
|
|
# { :x86 => { ... }, :x64 => { ... } }
|
|
#
|
|
def installdirs( )
|
|
return nil unless is_installed?
|
|
|
|
if ( :x64 == OS::WinSystemInfo::SysType( ) ) then
|
|
{ :x64 => @native, :x86 => @x86 }
|
|
else
|
|
{ :x86 => @native, :x64 => {} }
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Return autodeskMotionbuilder class static log object.
|
|
#
|
|
def AutodeskMotionbuilder::log( )
|
|
@@log = Log.new( 'AutodeskMotionbuilder' ) if ( @@log.nil? )
|
|
@@log
|
|
end
|
|
|
|
private
|
|
#---------------------------------------------------------------------
|
|
# Private Data
|
|
#---------------------------------------------------------------------
|
|
@@log = nil
|
|
|
|
#---------------------------------------------------------------------
|
|
# Private Constants
|
|
#---------------------------------------------------------------------
|
|
|
|
DCC_COMMON_DIR = 'dcc/common/'
|
|
|
|
REGISTRY_DUMP = OS::Path::combine( 'install', '3dsmaxRegDump.exe' )
|
|
REGISTRY_FILE = '3dsmaxRegDump.xml'
|
|
|
|
XML_XPATH_NATIVE_VERSION = 'Applications/AutodeskMotionBuilder/mbNative/version'
|
|
XML_XPATH_X86_VERSION = 'Applications/AutodeskMotionBuilder/mbX86/version'
|
|
|
|
INIT_SCRIPT_X86 = 'rockstarnorthconfiginit.ms'
|
|
INIT_SCRIPT_X64 = 'rockstarnorthconfiginit64.ms'
|
|
|
|
#---------------------------------------------------------------------
|
|
# Private Methods
|
|
#---------------------------------------------------------------------
|
|
|
|
#
|
|
# == Description
|
|
# This private method runs the 3dsmaxRegDump executable and writes out
|
|
# our info XML file that is then parsed into an internal structure.
|
|
#
|
|
def init( )
|
|
begin
|
|
toolsbin = Pipeline::Config::instance().toolsbin
|
|
toolstmp = Pipeline::Config::instance().temp()
|
|
regdump = OS::Path::combine( toolsbin, REGISTRY_DUMP )
|
|
xmlout = OS::Path::combine( toolstmp, REGISTRY_FILE )
|
|
|
|
FileUtils::mkdir_p( toolstmp )
|
|
|
|
AutodeskMotionbuilder::log().info( "Starting \"#{regdump} #{xmlout}\"..." )
|
|
status, sout, serr = OS::start( "#{regdump} #{xmlout}" )
|
|
|
|
# Parse our XML file.
|
|
parse( xmlout )
|
|
|
|
rescue Exception => ex
|
|
AutodeskMotionbuilder::log().exception( ex, 'Unhandled exception during reg dump' )
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Parse the passed in 3dsmax reg dump XML file; initialising our internal
|
|
# data ready to be returned by our instance methods.
|
|
#
|
|
def parse( filename )
|
|
|
|
@native = {}
|
|
@x86 = {}
|
|
File::open( filename, 'r' ) do |fp|
|
|
|
|
doc = REXML::Document::new( fp )
|
|
doc.elements.each( XML_XPATH_NATIVE_VERSION ) do |nativeElem|
|
|
@native[nativeElem.attributes['id']] = nativeElem.attributes['installdir']
|
|
end
|
|
doc.elements.each( XML_XPATH_X86_VERSION ) do |x86Elem|
|
|
@x86[x86Elem.attributes['id']] = x86Elem.attributes['installdir']
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end # Pipeline module
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Entry (Unit Testing)
|
|
#----------------------------------------------------------------------------
|
|
if ( __FILE__ == $0 ) then
|
|
|
|
autodeskMotionbuilder = Pipeline::autodeskMotionbuilder::instance( )
|
|
puts "Autodesk Motionbuilder installed?: #{autodeskMotionbuilder.is_installed?}"
|
|
autodeskMotionbuilder.installdirs.each_pair do |platform, dirs|
|
|
puts "Platform: #{platform}"
|
|
dirs.each_pair do |version, installdir|
|
|
puts "\t#{version} => #{installdir}"
|
|
end
|
|
end
|
|
puts "Versions: #{autodeskMotionbuilder.versions.join('; ')}"
|
|
puts "Latest: #{autodeskMotionbuilder.latest_version}"
|
|
puts "Root dir: #{autodeskMotionbuilder.get_root_dir()}"
|
|
end
|
|
|
|
# pipeline/util/autodeskMotionbuilder.rb
|