mirror of
https://github.com/DCFApixels/DragonECS-Unity.git
synced 2025-09-18 18:14:35 +08:00
update
This commit is contained in:
parent
250b6b275f
commit
0fd029f711
@ -1,4 +1,7 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
@ -6,8 +9,26 @@ namespace DCFApixels.DragonECS
|
||||
[CreateAssetMenu(fileName = nameof(EcsPipelineTemplateSO), menuName = EcsConsts.FRAMEWORK_NAME + "/" + nameof(EcsPipelineTemplateSO), order = 1)]
|
||||
public class EcsPipelineTemplateSO : ScriptableObject, IEcsModule
|
||||
{
|
||||
private string[] _layers;
|
||||
private static string[] _defaultLayers = new string[]
|
||||
{
|
||||
EcsConsts.PRE_BEGIN_LAYER,
|
||||
EcsConsts.BEGIN_LAYER,
|
||||
EcsConsts.BASIC_LAYER,
|
||||
EcsConsts.END_LAYER,
|
||||
EcsConsts.POST_END_LAYER,
|
||||
};
|
||||
|
||||
[SerializeField]
|
||||
private string[] _layers = _defaultLayers.ToArray();
|
||||
|
||||
[SerializeField]
|
||||
private SystemRecord[] _systems;
|
||||
|
||||
[SerializeField]
|
||||
[SerializeReference]
|
||||
[ReferenceButton]
|
||||
private IEcsModule[] _modules;
|
||||
|
||||
void IEcsModule.Import(EcsPipeline.Builder b)
|
||||
{
|
||||
b.Layers.MergeWith(_layers);
|
||||
@ -53,9 +74,64 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
ValidateLayers();
|
||||
ValidateSystems();
|
||||
}
|
||||
private void ValidateLayers()
|
||||
{
|
||||
Dictionary<string, int> builtinLayerIndexes = new Dictionary<string, int>();
|
||||
foreach (var item in _defaultLayers)
|
||||
{
|
||||
builtinLayerIndexes.Add(item, -1);
|
||||
}
|
||||
|
||||
List<string> newLayers = _layers.Distinct().ToList();
|
||||
|
||||
for (int i = 0; i < newLayers.Count; i++)
|
||||
{
|
||||
var layer = newLayers[i];
|
||||
if (builtinLayerIndexes.ContainsKey(layer))
|
||||
{
|
||||
builtinLayerIndexes[layer] = i;
|
||||
}
|
||||
}
|
||||
|
||||
int lastNewLayersCount = newLayers.Count;
|
||||
foreach (var pair in builtinLayerIndexes)
|
||||
{
|
||||
if(pair.Value < 0)
|
||||
{
|
||||
newLayers.Add(pair.Key);
|
||||
}
|
||||
}
|
||||
for (int i = lastNewLayersCount; i < newLayers.Count; i++)
|
||||
{
|
||||
builtinLayerIndexes[newLayers[i]] = i;
|
||||
}
|
||||
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var pair in builtinLayerIndexes.OrderBy(o => o.Value))
|
||||
{
|
||||
newLayers[pair.Value] = _defaultLayers[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
_layers = newLayers.ToArray();
|
||||
}
|
||||
private void ValidateSystems()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct SystemRecord
|
||||
{
|
||||
[SerializeReference]
|
||||
[ReferenceButton]
|
||||
public IEcsProcess system;
|
||||
public string layer;
|
||||
public int sortOrder;
|
||||
|
@ -1,13 +1,33 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
//[CustomEditor(typeof(EcsPipelineTemplateSO))]
|
||||
//internal class EcsPipelineTemplateSOEditor
|
||||
//{
|
||||
//
|
||||
//}
|
||||
[CustomEditor(typeof(EcsPipelineTemplateSO))]
|
||||
internal class EcsPipelineTemplateSOEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
base.OnInspectorGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
Validate();
|
||||
}
|
||||
if (GUILayout.Button("Validate"))
|
||||
{
|
||||
Validate();
|
||||
}
|
||||
}
|
||||
|
||||
private void Validate()
|
||||
{
|
||||
foreach (var target in targets)
|
||||
{
|
||||
((EcsPipelineTemplateSO)target).Validate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
304
src/EcsPipelineTemplate/ReferenceButtonAttribute.cs
Normal file
304
src/EcsPipelineTemplate/ReferenceButtonAttribute.cs
Normal file
@ -0,0 +1,304 @@
|
||||
using DCFApixels.DragonECS;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS.Unity.Internal
|
||||
{
|
||||
internal sealed class ReferenceButtonAttribute : PropertyAttribute { }
|
||||
}
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
namespace DCFApixels.DragonECS.Unity.Editors
|
||||
{
|
||||
using DCFApixels.DragonECS.Unity.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEditor.IMGUI.Controls;
|
||||
using UnityObject = UnityEngine.Object;
|
||||
|
||||
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute))]
|
||||
internal sealed class ReferenceButtonAttributeDrawer : PropertyDrawer
|
||||
{
|
||||
private static bool _isInit;
|
||||
|
||||
private static Type[] _serializableTypes;
|
||||
private static Dictionary<Type, ReferenceDropDown> _predicatTypesMenus = new Dictionary<Type, ReferenceDropDown>();
|
||||
|
||||
private class ReferenceDropDown : AdvancedDropdown
|
||||
{
|
||||
public readonly Type PredicateType;
|
||||
public ReferenceDropDown(Type predicateType) : base(new AdvancedDropdownState())
|
||||
{
|
||||
PredicateType = predicateType;
|
||||
|
||||
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
|
||||
}
|
||||
protected override AdvancedDropdownItem BuildRoot()
|
||||
{
|
||||
int increment = 0;
|
||||
var root = new Item(null, "Select Type", increment++);
|
||||
root.AddChild(new Item(null, "<NULL>", increment++));
|
||||
|
||||
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
|
||||
|
||||
foreach (var type in _serializableTypes)
|
||||
{
|
||||
if (PredicateType.IsAssignableFrom(type))
|
||||
{
|
||||
ITypeMeta meta = type.ToMeta();
|
||||
string name = meta.Name;
|
||||
string description = meta.Description.Text;
|
||||
MetaGroup group = meta.Group;
|
||||
var splitedGroup = group.Splited;
|
||||
|
||||
Item parent = root;
|
||||
if(splitedGroup.Count > 0)
|
||||
{
|
||||
int i = 1;
|
||||
foreach (var subgroup in splitedGroup)
|
||||
{
|
||||
Key key = new Key(group, i);
|
||||
if (dict.TryGetValue(key, out Item item) == false)
|
||||
{
|
||||
item = new Item(null, subgroup, increment++);
|
||||
parent.AddChild(item);
|
||||
dict.Add(key, item);
|
||||
}
|
||||
parent = item;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
var leafItem = new Item(type, name, increment++);
|
||||
parent.AddChild(leafItem);
|
||||
}
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
protected override void ItemSelected(AdvancedDropdownItem item)
|
||||
{
|
||||
base.ItemSelected(item);
|
||||
OnSelected((Item)item);
|
||||
}
|
||||
|
||||
public event Action<Item> OnSelected = delegate { };
|
||||
|
||||
public class Item : AdvancedDropdownItem
|
||||
{
|
||||
public readonly Type Type;
|
||||
public Item(Type type, string name, int id) : base(name)
|
||||
{
|
||||
Type = type;
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
#region Key
|
||||
private readonly struct Key : IEquatable<Key>
|
||||
{
|
||||
public readonly MetaGroup Group;
|
||||
public readonly int Length;
|
||||
public Key(MetaGroup group, int length)
|
||||
{
|
||||
Group = group;
|
||||
Length = length;
|
||||
}
|
||||
public bool Equals(Key other)
|
||||
{
|
||||
if (Length != other.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IEnumerator<string> splitedEnum = Group.Splited.GetEnumerator();
|
||||
IEnumerator<string> splitedEnumOther = Group.Splited.GetEnumerator();
|
||||
for (int i = 0; i < Length; i++)
|
||||
{
|
||||
splitedEnum.MoveNext();
|
||||
splitedEnumOther.MoveNext();
|
||||
if (splitedEnum.Current != splitedEnumOther.Current)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Key key && Equals(key);
|
||||
}
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int state = Length;
|
||||
state ^= state << 13;
|
||||
state ^= state >> 17;
|
||||
state ^= state << 5;
|
||||
var x = Group.Splited.GetEnumerator();
|
||||
x.MoveNext();
|
||||
return x.Current.GetHashCode() ^ state;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//private readonly struct Key : IEquatable<Key>
|
||||
//{
|
||||
// public readonly string FullName;
|
||||
// public readonly int Length;
|
||||
// public Key(string fullName, int length)
|
||||
// {
|
||||
// FullName = fullName;
|
||||
// Length = length;
|
||||
// }
|
||||
// public bool Equals(Key other)
|
||||
// {
|
||||
// if (Length != other.Length)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// for (int i = 0; i < Length; i++)
|
||||
// {
|
||||
// if (FullName[i] != other.FullName[i])
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// public override bool Equals(object obj)
|
||||
// {
|
||||
// return obj is Key key && Equals(key);
|
||||
// }
|
||||
// public override int GetHashCode()
|
||||
// {
|
||||
// unchecked
|
||||
// {
|
||||
// int state = Length;
|
||||
// state ^= state << 13;
|
||||
// state ^= state >> 17;
|
||||
// state ^= state << 5;
|
||||
// return FullName.GetHashCode() ^ state;
|
||||
// };
|
||||
// }
|
||||
//}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Init
|
||||
private static void Init()
|
||||
{
|
||||
if (_isInit) { return; }
|
||||
|
||||
List<Type> types = new List<Type>();
|
||||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
var targetTypes = assembly.GetTypes().Where(type =>
|
||||
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
|
||||
type.IsSubclassOf(typeof(UnityObject)) == false &&
|
||||
type.GetCustomAttribute<SerializableAttribute>() != null);
|
||||
|
||||
types.AddRange(targetTypes);
|
||||
}
|
||||
_serializableTypes = types.ToArray();
|
||||
_isInit = true;
|
||||
}
|
||||
|
||||
private static ReferenceDropDown GetReferenceDropDown(Type predicatType)
|
||||
{
|
||||
Init();
|
||||
if (_predicatTypesMenus.TryGetValue(predicatType, out ReferenceDropDown menu) == false)
|
||||
{
|
||||
menu = new ReferenceDropDown(predicatType);
|
||||
menu.OnSelected += SelectComponent;
|
||||
_predicatTypesMenus.Add(predicatType, menu);
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
[ThreadStatic]
|
||||
private static SerializedProperty currentProperty;
|
||||
private static void SelectComponent(ReferenceDropDown.Item item)
|
||||
{
|
||||
Type type = item.Type;
|
||||
if (type == null)
|
||||
{
|
||||
currentProperty.managedReferenceValue = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProperty.managedReferenceValue = Activator.CreateInstance(type);
|
||||
currentProperty.isExpanded = true;
|
||||
}
|
||||
|
||||
currentProperty.serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
|
||||
{
|
||||
if (property.managedReferenceValue != null)
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property, label, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return EditorGUIUtility.singleLineHeight;
|
||||
}
|
||||
}
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
Rect selButtnoRect = position;
|
||||
selButtnoRect.height = EditorGUIUtility.singleLineHeight;
|
||||
DrawSelectionPopup(selButtnoRect, property, label);
|
||||
|
||||
if (property.managedReferenceValue != null)
|
||||
{
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.BeginProperty(position, label, property);
|
||||
EditorGUI.LabelField(position, label);
|
||||
EditorGUI.EndProperty();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
Rect buttonRect = RectUtility.AddPadding(position, EditorGUIUtility.labelWidth, 0f, 0f, 0f);
|
||||
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
|
||||
if (GUI.Button(buttonRect, obj == null ? "Select..." : obj.GetMeta().Name, EditorStyles.layerMaskField))
|
||||
{
|
||||
currentProperty = property;
|
||||
GetReferenceDropDown(fieldInfo.FieldType).Show(buttonRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.SYSTEMS_GROUP)]
|
||||
[System.Serializable] public class TestSystem0 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.SYSTEMS_GROUP)]
|
||||
[System.Serializable] public class TestSystem1 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.SYSTEMS_GROUP)]
|
||||
[System.Serializable] public class TestSystem2 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.SYSTEMS_GROUP)]
|
||||
[System.Serializable] public class TestSystem3 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP)]
|
||||
[System.Serializable] public class TestSystem4 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP)]
|
||||
[System.Serializable] public class TestSystem7 : IEcsProcess { }
|
||||
[MetaGroup(EcsConsts.PACK_GROUP)]
|
||||
[System.Serializable] public class TestSystem8 : IEcsProcess { }
|
||||
[System.Serializable] public class _TestSystemX : IEcsProcess { }
|
||||
[System.Serializable] public class TestSystem9 : IEcsProcess { }
|
||||
[System.Serializable] public class TestSystem5 : IEcsProcess { }
|
||||
[System.Serializable] public class TestSystem6 : IEcsProcess { }
|
11
src/EcsPipelineTemplate/ReferenceButtonAttribute.cs.meta
Normal file
11
src/EcsPipelineTemplate/ReferenceButtonAttribute.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 999d5f8fb88eafc44b8a88406eb3ec39
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -61,10 +61,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
|
||||
name = group.Name + name;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(description) == false)
|
||||
{
|
||||
name = $"{name} [i]";
|
||||
}
|
||||
_genericMenu.AddItem(new GUIContent(name, description), false, SelectComponent, dummy);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user