PBXProjectEditor.cs
PBXProjectEditor.cs
#if UNITY_IOS
/**
* @file PBXProjectEditor.cs
* @brief PBXプロジェクトの編集を行う。
* @date $Date$
* @version $Rev$
* @author $Author$
*/
using UnityEditor;
using UnityEditor.iOS.Xcode;
using System;
using System.IO;
using System.Collections.Generic;
namespace yyama2.Editor.XCProjEdit {
/// <summary>
/// PBXプロジェクトのプロパティを設定する。
///
///
/// 設定は下記の様に定義してください。
///
/// ■file操作(追加・削除・移動) ※PBXParamFile.FileParam参照
/// new List() {
/// new PBXParamFile.FileParam(
/// type,
/// fromDir,
/// fromFile,
/// toDir,
/// toFile,
/// compileFlag // 省略可
/// ),
/// }
///
/// ■Framework ※PBXParamFramework参照
/// new Dictionary<string, int>() {
/// { "value.framework", 1 },
/// }
///
/// ■Property設定 ※PBXParamProperty.PropertyParams参照
/// new Dictionary<string, List<PBXParamProperty.PropertyParams>>() {
/// "property",
/// new List<PBXParamProperty.PropertyParams>() {
/// new PBXParamProperty.PropertyParams(
/// configType:"config_type", // configType
/// addValue:new string[]{ "YES" }, // AddValue
/// nremoveType:ew string[]{ "NO" }, // RemoveValue
/// forceOverride:false // 上書きフラグ
/// ),
/// }
/// },
/// </summary>
public static class PBXProjectEditor {
/// <summary> Unityデフォルトのプロジェクト名(基本変更しなくていい)</summary>
public const string NATIVE_TARGET_NAME = "Unity-iPhone";
/// <summary> XcodeProjectの拡張子</summary>
public const string XCODE_PROJ_FILE_EXTENSION = ".xcodeproj";
/// <summary> XcodeProjectファイル</summary>
public const string XCODE_PROJ_FILE = NATIVE_TARGET_NAME + XCODE_PROJ_FILE_EXTENSION;
/// <summary> PBXプロジェクトファイル</summary>
public const string PBX_PROJ_FILE = "project.pbxproj";
/// <summary> project.pbxprojのパスを取得する</summary>
/// <param name="path"> project.pbxprojのあるフォルダパス</param>
/// <returns> project.pbxprojのファイルパス</returns>
public static string GetDefaultPBXProjectPath( string path )
{
return Path.Combine( Path.Combine( path, XCODE_PROJ_FILE ), PBX_PROJ_FILE );
}
/// <summary>
/// PBXプロジェクトの編集
/// </summary>
/// <param name="pbxProjPath">Pbx proj path.</param>
/// <param name="pbxParams">Pbx parameters.</param>
/// <param name="callClass">この関数を呼び出しているクラスタイプ.ログ出力に飲み使用します.typeof( クラス )</param>
public static void PBXProjectEdit( string pbxProjPath, List<PBXParam> pbxParams, Type callClass = null )
{
string className = "";
if( callClass != null )
{
className += callClass.Name;
}
UnityEngine.Debug.Log( "PBXProjectEditor:" + className );
string log = "======================= PBXProjectValue =======================\n";
UnityEngine.Debug.Log( "pbxProjPath=>" + pbxProjPath );
PBXProject pbxProj = new PBXProject();
pbxProj.ReadFromFile( pbxProjPath );
foreach( PBXParam param in pbxParams )
{
param.Edit( ref pbxProj );
}
pbxProj.WriteToFile( pbxProjPath );
log += className + "\n";
foreach( PBXParam param in pbxParams )
{
log += param.GetParamLog();
}
log += "\n======================= PBXProjectValue =======================";
UnityEngine.Debug.Log( log );
}
}
/// <summary>
/// 設定項目のクラス。
/// </summary>
public abstract class PBXParam {
/// <summary>
/// 設定されているパラメータのログ。
/// </summary>
/// <returns>The parameter log.</returns>
public abstract string GetParamLog();
/// <summary>
/// 設定の編集を行う
/// </summary>
/// <param name="pbxProj">Pbx projct.</param>
public abstract void Edit( ref PBXProject pbxProj );
/// <summary>
/// プロジェクト名のリスト(基本的には、Unity-iPhoneのみ)
/// </summary>
/// <value>プロジェクト名一覧.</value>
public string[] ProjectNames { get; protected set; }
/// <summary>
/// プロジェクトのguidを取得する。
/// </summary>
/// <returns>The project guids.</returns>
/// <param name="pbxProj">Pbx project.</param>
protected IEnumerable<string> GetProjectGuids( PBXProject pbxProj )
{
List<string> guids = new List<string>();
foreach( string projectName in ProjectNames )
{
guids.Add( pbxProj.TargetGuidByName( projectName ) );
}
return guids;
}
/// <summary>
/// コンストラクタ。継承先のクラスで必ず呼び出すこと( GetProjectGuids()で使用します。 )
/// </summary>
/// <param name="projectNames">Project names.</param>
public PBXParam( string[] projectNames )
{
if( projectNames == null || projectNames.Length == 0 ) {
projectNames = new []{ PBXProjectEditor.NATIVE_TARGET_NAME };
}
this.ProjectNames = projectNames;
}
}
/// <summary>
/// プロジェクトに設定されているファイルを追加するクラス。
/// </summary>
public class PBXParamFile : PBXParam {
/// <summary> 編集を行うかどうか</summary>
private readonly List<FileParam> m_params;
/// <summary> Xcodeプロジェクトのディレクトリ</summary>
private readonly string m_xcodePath;
/// <summary>
/// どのようなファイル操作を行うか。
/// </summary>
public enum FileEditType
{
/// <summary> ファイルの追加 </summary>
ADD,
/// <summary> ファイルのリネーム(移動)</summary>
MOVE,
/// <summary> ファイルの削除(物理削除は行わない)</summary>
REMOVE,
}
/// <summary>
/// 変更設定。
/// </summary>
public class FileParam {
/// <summary> edit type.</summary>
public FileEditType Type{ get; private set; }
/// <summary> form directory path.</summary>
public string FromDirPath{ get; private set; }
/// <summary> from file name.</summary>
public string FromFileName{ get; private set; }
/// <summary> to directory path.</summary>
public string ToDirPath{ get; private set; }
/// <summary> to file name.</summary>
public string ToFileName{ get; private set; }
/// <summary> to file name.</summary>
public string CompileFlags{ get; private set; }
/// <summary>
/// <para>指定するタイプによって引数の使い分けを行う。</para>
/// <para></para>
/// <para>ADD</para>
/// <para>(Unityから自動で転送されないファイルをXcodeに転送してプロジェクトに追加する)</para>
/// <para>_fromDir : Unity上(Assetsを除く)</para>
/// <para>fromFile : Unity上のファイル名</para>
/// <para>___toDir : Xcode上のディレクトリ</para>
/// <para>__toFile : Xcode上のファイル名</para>
/// <para></para>
/// <para>MOVE</para>
/// <para>(Xcode上からファイルを移動(リネーム)する)</para>
/// <para>_fromDir : Xcode上で移動前のディレクトリ</para>
/// <para>fromFile : Xcode上で移動前のファイル名</para>
/// <para>___toDir : Xcode上で移動後のディレクトリ</para>
/// <para>__toFile : Xcode上で移動後のファイル名</para>
/// <para></para>
/// <para>REMOVE</para>
/// <para>(Xcode上からファイルを削除する)</para>
/// <para>_fromDir : Xcode上のディレクトリ</para>
/// <para>fromFile : Xcode上のファイル名</para>
/// <para>___toDir : -</para>
/// <para>__toFile : -</para>
/// </summary>
/// <param name="type">Type.</param>
/// <param name="fromDir">From dir.</param>
/// <param name="fromFile">From file.</param>
/// <param name="toDir">To dir.</param>
/// <param name="toFile">To file.</param>
/// <param name="compileFlags">Compile Flags.</param>
public FileParam( FileEditType type, string fromDir, string fromFile, string toDir = null, string toFile = null, string compileFlags = null )
{
if( type != FileEditType.REMOVE )
{
string param = "";
bool isNull = false;
if( toDir == null )
{
param += "toDir";
isNull = true;
}
if( toFile == null )
{
if( isNull )
{
param += ", ";
}
param += "toFile";
}
if( isNull )
{
throw new System.ArgumentNullException( param, "If type is not REMOVE, you must set toXXX parameter!" );
}
}
this.Type = type;
this.FromDirPath = fromDir;
this.FromFileName = fromFile;
this.ToDirPath = toDir;
this.ToFileName = toFile;
this.CompileFlags = compileFlags;
}
/// <summary>
/// ログを作成.
/// </summary>
public string CreateLog()
{
string log = "[File:";
switch( Type )
{
case FileEditType.ADD:
log += "Add]" + "\n\tUnity file: " + CombinePath( FromDirPath, FromFileName ) + "\n\tXcode file: " + CombinePath( ToDirPath, ToFileName + "\n\tCompile flags: " + CompileFlags );
break;
case FileEditType.MOVE:
log += "Move]" + "\n\tXC before file: " + CombinePath( FromDirPath, FromFileName ) + "\n\tXC after file: " + CombinePath( ToDirPath, ToFileName + "\n\tCompile flags: " + CompileFlags );
break;
case FileEditType.REMOVE:
log += "Delete]" + "\n\tDelete file: " + CombinePath( FromDirPath, FromFileName );
break;
}
return log;
}
}
/// <summary>
/// 設定されているパラメータのログ。
/// </summary>
/// <returns>The parameter log.</returns>
public override string GetParamLog ()
{
string log = "";
foreach( FileParam param in m_params )
{
log += param.CreateLog() + "\n";
}
return log;
}
/// <summary>
/// 設定の編集を行う
/// </summary>
/// <param name="pbxProj">Pbx projct.</param>
public override void Edit( ref PBXProject pbxProj )
{
foreach( FileParam param in m_params )
{
switch( param.Type )
{
case FileEditType.ADD:
{
// ファイルを追加する
AddFile( ref pbxProj, param );
break;
}
case FileEditType.MOVE:
{
// ファイルのリネームや移動
MoveFile( ref pbxProj, param );
break;
}
case FileEditType.REMOVE:
{
// ファイルの削除
RemoveFile( ref pbxProj, param );
break;
}
}
}
}
/// <summary>
/// Unity上にはあるが、プロジェクトに追加されていないファイルをXcodeプロジェクトに追加する。
/// </summary>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="param">Parameter.</param>
private void AddFile( ref PBXProject pbxProj, FileParam param )
{
// UnityのファイルをXcodeにコピーする
string unityPath = CombinePath( UnityEngine.Application.dataPath, param.FromDirPath, param.FromFileName );
string xcodePath = CombinePath( m_xcodePath, param.ToDirPath, param.ToFileName );
CopyFile( unityPath, xcodePath );
string addPath = CombinePath( param.ToDirPath, param.ToFileName );
AddFileProc( ref pbxProj, addPath, param.CompileFlags );
}
/// <summary>
/// Xcodeにファイルを追加する
/// </summary>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="addPath">Add path.</param>
/// <param name="compileFlag">Compile flag.</param>
private void AddFileProc( ref PBXProject pbxProj, string addPath, string compileFlag )
{
// ファイル参照をプロジェクトに追加
pbxProj.AddFile( addPath, addPath );
string fileGuid = pbxProj.FindFileGuidByProjectPath( addPath );
// プロジェクトの設定(BuildPhase)に追加
foreach( string guid in GetProjectGuids( pbxProj ) )
{
pbxProj.AddFileToBuildWithFlags( guid, fileGuid, compileFlag );
}
}
/// <summary>
/// Xcodeのファイルを移動(リネーム)する
/// </summary>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="param">Parameter.</param>
private void MoveFile( ref PBXProject pbxProj, FileParam param )
{
string beforePath = CombinePath( param.FromDirPath, param.FromFileName );
string afterPath = CombinePath( param.ToDirPath, param.ToFileName );
// 既存のファイルを削除
RemoveFileProc( ref pbxProj, beforePath );
// 既存のファイルのリネーム
MoveFile( CombinePath( m_xcodePath, beforePath ), CombinePath( m_xcodePath, afterPath ) );
// リネーム後ファイルの追加
AddFileProc( ref pbxProj, afterPath, param.CompileFlags );
}
/// <summary>
/// Xcodeに追加されているファイルの削除(物理削除は行わない)
/// </summary>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="param">Parameter.</param>
private void RemoveFile( ref PBXProject pbxProj, FileParam param )
{
string removePath = CombinePath( param.FromDirPath, param.FromFileName );
RemoveFileProc( ref pbxProj, removePath );
}
/// <summary>
/// Xcodeに追加されているファイルの削除(物理削除は行わない)
/// </summary>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="removePath">Remove path.</param>
private void RemoveFileProc( ref PBXProject pbxProj, string removePath )
{
if ( !pbxProj.ContainsFileByProjectPath( removePath ) ) return;
string fileGuid = pbxProj.FindFileGuidByProjectPath( removePath );
foreach( string guid in GetProjectGuids( pbxProj ) )
{
pbxProj.RemoveFileFromBuild( guid, fileGuid );
}
pbxProj.RemoveFile( fileGuid );
}
/// <summary>
/// ファイルの親ディレクトリを作成する。
/// </summary>
/// <param name="filePath">File path.</param>
public static void CreateParentDirectory( string filePath )
{
string[] files = filePath.Split( "/"[0] );
string path = "";
for( int i = 0; i < files.Length - 1; ++i )
{
path += "/" + files[i];
if( !Directory.Exists( path ) )
{
Directory.CreateDirectory( path );
}
}
}
/// <summary>
/// ファイルをコピーする.
/// </summary>
/// <param name="fromFile">From file.</param>
/// <param name="toFile">To file.</param>
public static void CopyFile( string fromFile, string toFile )
{
CreateParentDirectory( toFile );
FileUtil.CopyFileOrDirectory( fromFile, toFile );
}
/// <summary>
/// ファイルを移動(リネーム)する。
/// </summary>
/// <param name="fromFile">From file.</param>
/// <param name="toFile">To file.</param>
public static void MoveFile( string fromFile, string toFile )
{
CreateParentDirectory( toFile );
FileUtil.MoveFileOrDirectory( fromFile, toFile );
}
/// <summary>
/// パスの結合
/// </summary>
/// <returns>The path.</returns>
/// <param name="fileAndDir">File and dir.</param>
public static string CombinePath( params string[] fileAndDir )
{
string root = fileAndDir[0];
for( int i = 1; i < fileAndDir.Length; ++i )
{
root = Path.Combine( root, fileAndDir[i] );
}
return root;
}
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="parameters">Parameters.</param>
/// <param name="xcodePath">Xcode path.</param>
/// <param name="projectNames">Project names.</param>
public PBXParamFile( List<FileParam> parameters, string xcodePath, params string[] projectNames ) : base ( projectNames )
{
m_params = parameters;
m_xcodePath = xcodePath;
}
}
/// <summary>
/// Framework変更
/// </summary>
public class PBXParamFramework : PBXParam {
/// <summary>
/// Framework設定
/// </summary>
private readonly Dictionary<string, int> m_framemworks;
/// <summary>
/// ログ用の文字列作成
/// </summary>
/// <returns>The parameter log.</returns>
public override string GetParamLog()
{
string log = "";
foreach( KeyValuePair<string, int> framework in m_framemworks )
{
log += "[Framework] " + framework.Key + ": " +
(
( framework.Value == -1 ) ? "Delete!!" :
(
( framework.Value == 1 ) ? "Optional" : "Required"
)
) + "\n";
}
return log;
}
/// <summary>
/// 設定の編集を行う
/// </summary>
/// <param name="pbxProj">Pbx projct.</param>
public override void Edit( ref PBXProject pbxProj )
{
IEnumerable<string> guids = GetProjectGuids( pbxProj );
foreach( string guid in guids )
{
foreach( KeyValuePair<string, int> framemwork in m_framemworks )
{
if( framemwork.Value == -1 )
pbxProj.RemoveFrameworkFromProject( guid, framemwork.Key );
else
pbxProj.AddFrameworkToProject( guid, framemwork.Key, framemwork.Value == 1 );
}
}
}
/// <summary>
/// コンストラクタ
///
/// new Dictionary<string, int>() {
/// { "value1", 0 }, // Required
/// { "value2", 1 }, // Optional
/// { "value3", -1 },// 削除
/// }
/// </summary>
/// <param name="framemworks">Framemworks.</param>
/// <param name="projectNames">Project names.</param>
public PBXParamFramework( Dictionary<string, int> framemworks, params string[] projectNames ) : base( projectNames )
{
this.m_framemworks = framemworks;
}
}
/// <summary>
/// プロパティ変更
/// </summary>
public class PBXParamProperty : PBXParam {
/// <summary>
/// プロパティ設定
/// </summary>
private readonly Dictionary<string, List<PropertyParams>> m_params;
/// <summary>
/// プロパティ設定項目
/// </summary>
public class PropertyParams {
/// <summary> 設定を行うタイプ(Debug/Releaseなど) </summary>
public string ConfigType { get; private set; }
/// <summary> 追加する値</summary>
public string[] AddValues { get; private set; }
/// <summary> 削除する値</summary>
public string[] RemoveValues { get; private set; }
/// <summary> 既存の項目をむしして上書きするかどうか。</summary>
public bool ForceOverride { get; private set; }
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="configType">設定を行うコンフィグのタイプ.nullの場合はすべての設定に反映されます.</param>
/// <param name="addValue">追加する値の配列.</param>
/// <param name="removeValue">削除する値の配列.</param>
/// <param name="forceOverride">強制的に上書きを行うかどうか.</param>
public PropertyParams( string[] addValue, string[] removeValue = null, string configType = null, bool forceOverride = false )
{
this.ConfigType = configType;
this.AddValues = addValue;
this.RemoveValues = removeValue;
this.ForceOverride = forceOverride;
}
/// <summary>
/// ログの作成
/// </summary>
/// <returns>The log.</returns>
public string CraeteLog()
{
string add = "[";
for( int i = 0; AddValues != null && i < AddValues.Length; ++i )
{
add += AddValues[i];
if( AddValues.Length - 1 != i )
{
add += ",";
}
}
add += "]";
string remove = "[";
for( int i = 0; RemoveValues != null && i < RemoveValues.Length; ++i )
{
remove += RemoveValues[i];
if( RemoveValues.Length - 1 != i )
{
remove += ",";
}
}
remove += "]";
return "\n\tConfig Type: " + ConfigType + "\n\tadd values: " + add + "\n\tremove values: " + remove;
}
}
/// <summary>
/// コンフィグ設定のguidを取得
/// </summary>
/// <returns>The config guids.</returns>
/// <param name="pbxProj">Pbx proj.</param>
/// <param name="configName">Config name.</param>
private IEnumerable<string> GetConfigGuids( PBXProject pbxProj, string configName )
{
IEnumerable<string> projects = GetProjectGuids( pbxProj );
List<string> guids = new List<string>();
foreach( string guid in projects )
{
guids.Add( pbxProj.BuildConfigByName( guid, configName ) );
}
return guids;
}
/// <summary>
/// ログの作成
/// </summary>
/// <returns>The parameter log.</returns>
public override string GetParamLog()
{
string log = "";
foreach( KeyValuePair<string, List<PropertyParams>> kv in m_params )
{
foreach( PropertyParams param in kv.Value )
{
log += "[Property] " + kv.Key + ":" + param.CraeteLog() + "\n";
}
}
return log;
}
/// <summary>
/// 設定の編集を行う
/// </summary>
/// <param name="pbxProj">Pbx projct.</param>
public override void Edit( ref PBXProject pbxProj )
{
foreach( KeyValuePair<string, List<PropertyParams>> param in m_params )
{
string key = param.Key;
foreach( PropertyParams propertyItem in param.Value )
{
IEnumerable<string> guids = propertyItem.ConfigType == null ? GetProjectGuids( pbxProj ) : GetConfigGuids( pbxProj, propertyItem.ConfigType );
// 既存設定を無視して上書き
if( propertyItem.ForceOverride )
{
int i = 0;
if( propertyItem.ConfigType == null )
{
foreach( string addValue in propertyItem.AddValues )
{
if( i == 0 )
pbxProj.SetBuildProperty( guids, key, addValue );
else
pbxProj.AddBuildProperty( guids, key, addValue );
}
++i;
}
else
{
guids = GetConfigGuids( pbxProj, propertyItem.ConfigType );
foreach( string addValue in propertyItem.AddValues )
{
if( i == 0 )
pbxProj.SetBuildPropertyForConfig( guids, key, addValue );
else
pbxProj.AddBuildPropertyForConfig( guids, key, addValue );
}
++i;
}
}
else
{
if( propertyItem.ConfigType == null )
{
pbxProj.UpdateBuildProperty( guids, key, propertyItem.AddValues, propertyItem.RemoveValues );
}
else
{
/*
* UpdateBuildPropertyForConfig( IEnumerator<string>, stirng, string[], string[] )
* は内部的に、UpdateBuildProperty( string, string, string[], string[] )をコールしており、
* UpdateBuildPropertyForConfig( string, string, string[], string[] )と挙動が異なるので、foreachでguidはループで指定する
*/
foreach( string guid in guids )
{
pbxProj.UpdateBuildPropertyForConfig( guid, key, propertyItem.AddValues, propertyItem.RemoveValues );
}
}
}
}
}
}
/// <summary>
/// コンストラクタ
/// </summary>
/// <param name="parameters">Parameters.</param>
/// <param name="projectNames">Project names.</param>
public PBXParamProperty( Dictionary<string, List<PropertyParams>> parameters, params string[] projectNames ) : base( projectNames )
{
this.m_params = parameters;
}
}
}
#endif
PlistEditor.cs
PlistEditor.cs
#if UNITY_IOS
/**
* @file PlistEditor.cs
* @brief plistの編集を行うクラス。
* @date $Date$
* @version $Rev$
* @author $Author$
*/
using UnityEditor.iOS.Xcode;
using System;
using System.IO;
using System.Collections.Generic;
namespace yyama2.Editor.XCProjEdit {
/// <summary>
/// plistの値を変更する。
///
///
/// 値の設定は、下記のように定義してください。
/// ※キーは任意の文字列です。
///
/// int 系のデータ
/// { "int", 1 },
/// boolean系の値
/// { "bool", true },
/// 文字列
/// { "string", "string value" },
/// 配列
/// { "list", new List<object>() { 1, 2, 3 } },
/// Dict
/// { "dict", new Dictionary<string, object>() {
/// { "value1", "string value" },
/// { "value2", 1 },
/// { "value3", true },
/// }
/// },
/// </summary>
public class PlistEditor {
/// <summary> Info.plistのパスを取得する</summary>
/// <param name="path"> Info.plistのあるフォルダパス</param>
/// <returns> Info.plistのファイルパス</returns>
public static string GetInfoPlistPath( string path )
{
return Path.Combine( path, "Info.plist" );
}
/// <summary>
/// plistを編集する。
/// </summary>
/// <param name="plistPath"> plistファイルパス</param>
/// <param name="values">追加する値.</param>
/// <param name="callClass">この関数を呼び出しているクラス.</param>
public static void EditPlist( string plistPath, Dictionary<string, object> values, Type callClass )
{
string className = "";
if( callClass != null )
{
className += callClass.Name;
}
UnityEngine.Debug.Log( "PlistEditor:" + className );
string log = "======================= PlistValue =======================\n";
UnityEngine.Debug.Log( "plistPath=>" + plistPath );
PlistDocument plist = new PlistDocument();
plist.ReadFromFile( plistPath );
foreach( KeyValuePair<string, object> value in values )
{
setValue( value.Key, value.Value, ref plist.root );
}
// Documentsフォルダを共有可能にする
plist.WriteToFile( plistPath );
log += className + "\n";
log += plistPath +"\n{";
foreach( var value in values )
{
CreateLog( value.Key, value.Value, 0, ref log );
}
log += "\n}\n" + "======================= PlistValue =======================";
UnityEngine.Debug.Log( log );
}
/// <summary>
/// 値をセットする
/// </summary>
/// <param name="key"> キー.</param>
/// <param name="value"> 値.</param>
/// <param name="dict"> Dictオブジェクト.</param>
private static void setValue( string key, object value, ref PlistElementDict dict )
{
bool validValue = true;
Type type = value.GetType();
// int .
if( type == typeof(int) )
{
dict.SetInteger( key, (int)value );
}
// bool .
else if( type == typeof(bool) )
{
dict.SetBoolean( key, (bool)value );
}
// string .
else if( type == typeof(string) )
{
dict.SetString( key, (string)value );
}
// list
else if( type == typeof(List<object>) )
{
PlistElementArray subArray;
if( !tryGetValue<PlistElementArray>( key, dict, out subArray ) )
{
subArray = dict.CreateArray( key );
}
List<object> list = (List<object>)value;
foreach( object val in list )
{
addValue( val, ref subArray );
}
}
// dictionary
else if( type == typeof(Dictionary<string, object>) )
{
PlistElementDict subDict;
if( !tryGetValue<PlistElementDict>( key, dict, out subDict ) )
{
subDict = dict.CreateDict( key );
}
Dictionary<string, object> dictionary = (Dictionary<string, object>)value;
foreach( var dictItem in dictionary )
{
setValue( dictItem.Key, dictItem.Value, ref subDict );
}
}
else validValue = false;
// invalid parameter
if( !validValue )
{
UnityEngine.Debug.LogError( "Plist Editor. Invalid Parameter => " + key );
}
}
/// <summary>
/// リストに値をセットする
/// </summary>
/// <param name="value">値.</param>
/// <param name="array">Arrayオブジェクト.</param>
private static void addValue( object value, ref PlistElementArray array )
{
Type type = value.GetType();
// int .
if( type == typeof(int) )
{
array.AddInteger( (int)value );
}
// bool .
else if( type == typeof(bool) )
{
array.AddBoolean( (bool)value );
}
// string .
else if( type == typeof(string) )
{
array.AddString( (string)value );
}
// list
else if( type == typeof(List<object>) )
{
PlistElementArray subArray = array.AddArray();
List<object> list = (List<object>)value;
foreach( object val in list )
{
addValue( val, ref subArray );
}
}
// dictionary
else if( type == typeof(Dictionary<string, object>) )
{
PlistElementDict subDict = array.AddDict();
Dictionary<string, object> dictionary = (Dictionary<string, object>)value;
foreach( var dictItem in dictionary )
{
setValue( dictItem.Key, dictItem.Value, ref subDict );
}
}
else
{
UnityEngine.Debug.LogError( "Add List Error!!" );
}
}
/// <summary>
/// dictオブジェクトから値を抽出する
/// </summary>
/// <returns><c>true</c>, if success to get, <c>false</c> otherwise.</returns>
/// <param name="key">Key.</param>
/// <param name="dict">Dictオブジェクト.</param>
/// <param name="val">Value.</param>
/// <typeparam name="T">The 1st type parameter.</typeparam>
private static bool tryGetValue<T>( string key, PlistElementDict dict, out T val ) where T : PlistElement
{
IDictionary<string, PlistElement> dictValue = dict.values;
PlistElement el;
val = null;
if( dictValue.TryGetValue( key, out el ) )
{
val = el as T;
}
return val != null;
}
/// <summary>
/// ログ様の文字列作成 .
/// </summary>
/// <param name="key">Key.</param>
/// <param name="value">Value.</param>
/// <param name="indent">Indent.</param>
/// <param name="log">Log.</param>
private static void CreateLog( string key, object value, int indent, ref string log )
{
++indent;
string indentTabs = "";
for( int i = 0; i < indent; ++i )
{
indentTabs += "\t";
}
log += "\n" + indentTabs + key + ":";
Type type = value.GetType();
// int .
if( type == typeof(int) )
{
log += value;
}
// bool .
else if( type == typeof(bool) )
{
log += value;
}
// string .
else if( type == typeof(string) )
{
log += "\"" + value + "\"";
}
// list
else if( type == typeof(List<object>) )
{
log += "[";
List<object> list = (List<object>)value;
for( int i = 0; i < list.Count; ++i )
{
CreateLog( "["+ i +"]", list[i], indent, ref log);
}
log += "\n" + indentTabs + "]";
}
// dictionary
else if( type == typeof(Dictionary<string, object>) )
{
Dictionary<string, object> dictionary = (Dictionary<string, object>)value;
log += "{";
foreach( var dictItem in dictionary )
{
CreateLog( dictItem.Key, dictItem.Value, indent, ref log );
}
log += "\n" + indentTabs + "}";
}
log += ",";
}
}
}
#endif