Ejemplo n.º 1
0
        public AssetManagerWorld(
            IAssetManagerProvider assetManagerProvider,
            I2DRenderUtilities renderUtilities,
            ISkin skin,
            IAssetLoader[] loaders)
        {
            this.Entities = new List<IEntity>();
            this.m_Skin = skin;
            this.m_Start = DateTime.Now;

            // Add the asset manager layout.
            var entity = new CanvasEntity(this.m_Skin);
            this.m_Layout = new AssetManagerLayout(assetManagerProvider, renderUtilities, loaders, entity);
            entity.Canvas = this.m_Layout;
            this.Entities.Add(entity);

            this.m_Layout.MarkDirty.Click += (sender, e) =>
            {
                foreach (var asset in this.AssetManager.GetAll())
                    this.AssetManager.Dirty(asset.Name);
            };

            this.m_Layout.Bake.Click += (sender, e) =>
            {
                if (this.m_CurrentEditor != null)
                    this.m_CurrentEditor.Bake(this.AssetManager);
                var item = this.m_Layout.AssetTree.SelectedItem as AssetTreeItem;
                if (item == null)
                    return;
                this.AssetManager.Bake(item.Asset);
            };

            this.m_Layout.AssetTree.SelectedItemChanged += (sender, e) =>
            {
                if (this.m_CurrentEditor != null)
                    this.m_CurrentEditor.FinishLayout(this.m_Layout.EditorContainer, this.AssetManager);
                var item = this.m_Layout.AssetTree.SelectedItem as AssetTreeItem;
                if (item != null && m_Editors.ContainsKey(item.Asset.GetType()))
                {
                    this.m_CurrentEditor = m_Editors[item.Asset.GetType()];
                    this.m_CurrentEditor.SetAsset(item.Asset);
                    this.m_CurrentEditor.BuildLayout(this.m_Layout.EditorContainer, this.AssetManager);
                }
                else
                {
                    this.m_CurrentEditor = null;
                    this.m_Layout.EditorContainer.SetChild(
                        new Label { Text = "No editor for " + (item == null ? "folders" : item.Asset.GetType().Name) });
                }
            };

            this.m_Layout.ExitClick += (sender, e) =>
            {
                Environment.Exit(0);
            };

            this.m_Layout.BakeAllClick += (sender, e) =>
            {
                foreach (var asset in this.AssetManager.GetAll())
                    this.AssetManager.Bake(asset);
            };

            this.m_Layout.CreateNameEntered += (sender, e) =>
            {
                var asset = e.Loader.GetNew(this.AssetManager, this.m_Layout.PromptName.Text);
                assetManagerProvider.GetAssetManager(false).Bake(asset);
                this.m_Layout.AssetTree.AddChild(new AssetTreeItem
                {
                    Text = this.m_Layout.PromptName.Text,
                    Asset = asset
                });
            };
        }
Ejemplo n.º 2
0
        /// <summary>Apply any <see cref="Editors"/> to a loaded asset.</summary>
        /// <typeparam name="T">The asset type.</typeparam>
        /// <param name="info">The basic asset metadata.</param>
        /// <param name="asset">The loaded asset.</param>
        private IAssetData ApplyEditors <T>(IAssetInfo info, IAssetData asset)
        {
            IAssetData GetNewData(object data) => new AssetDataForObject(info, data, this.AssertAndNormalizeAssetName);

            // special case: if the asset was loaded with a more general type like 'object', call editors with the actual type instead.
            {
                Type actualType     = asset.Data.GetType();
                Type actualOpenType = actualType.IsGenericType ? actualType.GetGenericTypeDefinition() : null;

                if (typeof(T) != actualType && (actualOpenType == typeof(Dictionary <,>) || actualOpenType == typeof(List <>) || actualType == typeof(Texture2D) || actualType == typeof(Map)))
                {
                    return((IAssetData)this.GetType()
                           .GetMethod(nameof(this.ApplyEditors), BindingFlags.NonPublic | BindingFlags.Instance)
                           .MakeGenericMethod(actualType)
                           .Invoke(this, new object[] { info, asset }));
                }
            }

            // edit asset
            foreach (var entry in this.Editors)
            {
                // check for match
                IModMetadata mod    = entry.Mod;
                IAssetEditor editor = entry.Data;
                try
                {
                    if (!editor.CanEdit <T>(info))
                    {
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    mod.LogAsMod($"Mod crashed when checking whether it could edit asset '{info.AssetName}', and will be ignored. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
                    continue;
                }

                // try edit
                object prevAsset = asset.Data;
                try
                {
                    editor.Edit <T>(asset);
                    this.Monitor.Log($"{mod.DisplayName} edited {info.AssetName}.");
                }
                catch (Exception ex)
                {
                    mod.LogAsMod($"Mod crashed when editing asset '{info.AssetName}', which may cause errors in-game. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
                }

                // validate edit
                if (asset.Data == null)
                {
                    mod.LogAsMod($"Mod incorrectly set asset '{info.AssetName}' to a null value; ignoring override.", LogLevel.Warn);
                    asset = GetNewData(prevAsset);
                }
                else if (!(asset.Data is T))
                {
                    mod.LogAsMod($"Mod incorrectly set asset '{asset.AssetName}' to incompatible type '{asset.Data.GetType()}', expected '{typeof(T)}'; ignoring override.", LogLevel.Warn);
                    asset = GetNewData(prevAsset);
                }
            }

            // return result
            return(asset);
        }