添加debug工具
This commit is contained in:
655
Assets/Plugins/RuntimeInspector/Scripts/RuntimeInspector.cs
Normal file
655
Assets/Plugins/RuntimeInspector/Scripts/RuntimeInspector.cs
Normal file
@ -0,0 +1,655 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace RuntimeInspectorNamespace
|
||||
{
|
||||
public class RuntimeInspector : SkinnedWindow, ITooltipManager
|
||||
{
|
||||
public enum VariableVisibility { None = 0, SerializableOnly = 1, All = 2 };
|
||||
public enum HeaderVisibility { Collapsible = 0, AlwaysVisible = 1, Hidden = 2 };
|
||||
|
||||
private const string POOL_OBJECT_NAME = "RuntimeInspectorPool";
|
||||
|
||||
public delegate object InspectedObjectChangingDelegate( object previousInspectedObject, object newInspectedObject );
|
||||
public delegate void ComponentFilterDelegate( GameObject gameObject, List<Component> components );
|
||||
|
||||
#pragma warning disable 0649
|
||||
[SerializeField, UnityEngine.Serialization.FormerlySerializedAs( "refreshInterval" )]
|
||||
private float m_refreshInterval = 0f;
|
||||
private float nextRefreshTime = -1f;
|
||||
public float RefreshInterval
|
||||
{
|
||||
get { return m_refreshInterval; }
|
||||
set { m_refreshInterval = value; }
|
||||
}
|
||||
|
||||
[Space]
|
||||
[SerializeField]
|
||||
private VariableVisibility m_exposeFields = VariableVisibility.SerializableOnly;
|
||||
public VariableVisibility ExposeFields
|
||||
{
|
||||
get { return m_exposeFields; }
|
||||
set
|
||||
{
|
||||
if( m_exposeFields != value )
|
||||
{
|
||||
m_exposeFields = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private VariableVisibility m_exposeProperties = VariableVisibility.SerializableOnly;
|
||||
public VariableVisibility ExposeProperties
|
||||
{
|
||||
get { return m_exposeProperties; }
|
||||
set
|
||||
{
|
||||
if( m_exposeProperties != value )
|
||||
{
|
||||
m_exposeProperties = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Space]
|
||||
[SerializeField]
|
||||
private bool m_arrayIndicesStartAtOne = false;
|
||||
public bool ArrayIndicesStartAtOne
|
||||
{
|
||||
get { return m_arrayIndicesStartAtOne; }
|
||||
set
|
||||
{
|
||||
if( m_arrayIndicesStartAtOne != value )
|
||||
{
|
||||
m_arrayIndicesStartAtOne = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_useTitleCaseNaming = false;
|
||||
public bool UseTitleCaseNaming
|
||||
{
|
||||
get { return m_useTitleCaseNaming; }
|
||||
set
|
||||
{
|
||||
if( m_useTitleCaseNaming != value )
|
||||
{
|
||||
m_useTitleCaseNaming = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Space]
|
||||
[SerializeField]
|
||||
private bool m_showAddComponentButton = true;
|
||||
public bool ShowAddComponentButton
|
||||
{
|
||||
get { return m_showAddComponentButton; }
|
||||
set
|
||||
{
|
||||
if( m_showAddComponentButton != value )
|
||||
{
|
||||
m_showAddComponentButton = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool m_showRemoveComponentButton = true;
|
||||
public bool ShowRemoveComponentButton
|
||||
{
|
||||
get { return m_showRemoveComponentButton; }
|
||||
set
|
||||
{
|
||||
if( m_showRemoveComponentButton != value )
|
||||
{
|
||||
m_showRemoveComponentButton = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Space]
|
||||
[SerializeField]
|
||||
private bool m_showTooltips;
|
||||
public bool ShowTooltips { get { return m_showTooltips; } }
|
||||
|
||||
[SerializeField]
|
||||
private float m_tooltipDelay = 0.5f;
|
||||
public float TooltipDelay
|
||||
{
|
||||
get { return m_tooltipDelay; }
|
||||
set { m_tooltipDelay = value; }
|
||||
}
|
||||
|
||||
internal TooltipListener TooltipListener { get; private set; }
|
||||
|
||||
[Space]
|
||||
[SerializeField]
|
||||
private int m_nestLimit = 5;
|
||||
public int NestLimit
|
||||
{
|
||||
get { return m_nestLimit; }
|
||||
set
|
||||
{
|
||||
if( m_nestLimit != value )
|
||||
{
|
||||
m_nestLimit = value;
|
||||
isDirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private HeaderVisibility m_inspectedObjectHeaderVisibility = HeaderVisibility.Collapsible;
|
||||
public HeaderVisibility InspectedObjectHeaderVisibility
|
||||
{
|
||||
get { return m_inspectedObjectHeaderVisibility; }
|
||||
set
|
||||
{
|
||||
if( m_inspectedObjectHeaderVisibility != value )
|
||||
{
|
||||
m_inspectedObjectHeaderVisibility = value;
|
||||
|
||||
if( currentDrawer != null && currentDrawer is ExpandableInspectorField )
|
||||
( (ExpandableInspectorField) currentDrawer ).HeaderVisibility = m_inspectedObjectHeaderVisibility;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int poolCapacity = 10;
|
||||
private Transform poolParent;
|
||||
|
||||
[SerializeField]
|
||||
private RuntimeHierarchy m_connectedHierarchy;
|
||||
public RuntimeHierarchy ConnectedHierarchy
|
||||
{
|
||||
get { return m_connectedHierarchy; }
|
||||
set { m_connectedHierarchy = value; }
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private RuntimeInspectorSettings[] settings;
|
||||
|
||||
private bool m_isLocked = false;
|
||||
public bool IsLocked
|
||||
{
|
||||
get { return m_isLocked; }
|
||||
set { m_isLocked = value; }
|
||||
}
|
||||
|
||||
[Header( "Internal Variables" )]
|
||||
[SerializeField]
|
||||
private ScrollRect scrollView;
|
||||
private RectTransform drawArea;
|
||||
|
||||
[SerializeField]
|
||||
private Image background;
|
||||
|
||||
[SerializeField]
|
||||
private Image scrollbar;
|
||||
#pragma warning restore 0649
|
||||
|
||||
private static int aliveInspectors = 0;
|
||||
|
||||
private bool initialized = false;
|
||||
|
||||
private readonly Dictionary<Type, InspectorField[]> typeToDrawers = new Dictionary<Type, InspectorField[]>( 89 );
|
||||
private readonly Dictionary<Type, InspectorField[]> typeToReferenceDrawers = new Dictionary<Type, InspectorField[]>( 89 );
|
||||
private readonly List<InspectorField> eligibleDrawers = new List<InspectorField>( 4 );
|
||||
|
||||
private static readonly Dictionary<Type, List<InspectorField>> drawersPool = new Dictionary<Type, List<InspectorField>>();
|
||||
|
||||
private readonly List<VariableSet> hiddenVariables = new List<VariableSet>( 32 );
|
||||
private readonly List<VariableSet> exposedVariables = new List<VariableSet>( 32 );
|
||||
|
||||
private InspectorField currentDrawer = null;
|
||||
private bool inspectLock = false;
|
||||
private bool isDirty = false;
|
||||
|
||||
private object m_inspectedObject;
|
||||
public object InspectedObject { get { return m_inspectedObject; } }
|
||||
|
||||
public bool IsBound { get { return !m_inspectedObject.IsNull(); } }
|
||||
|
||||
private Canvas m_canvas;
|
||||
public Canvas Canvas { get { return m_canvas; } }
|
||||
|
||||
// Used to make sure that the scrolled content always remains within the scroll view's boundaries
|
||||
private PointerEventData nullPointerEventData;
|
||||
|
||||
public InspectedObjectChangingDelegate OnInspectedObjectChanging;
|
||||
|
||||
private ComponentFilterDelegate m_componentFilter;
|
||||
public ComponentFilterDelegate ComponentFilter
|
||||
{
|
||||
get { return m_componentFilter; }
|
||||
set
|
||||
{
|
||||
m_componentFilter = value;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
private void Initialize()
|
||||
{
|
||||
if( initialized )
|
||||
return;
|
||||
|
||||
initialized = true;
|
||||
|
||||
drawArea = scrollView.content;
|
||||
m_canvas = GetComponentInParent<Canvas>();
|
||||
nullPointerEventData = new PointerEventData( null );
|
||||
|
||||
if( m_showTooltips )
|
||||
{
|
||||
TooltipListener = gameObject.AddComponent<TooltipListener>();
|
||||
TooltipListener.Initialize( this );
|
||||
}
|
||||
|
||||
GameObject poolParentGO = GameObject.Find( POOL_OBJECT_NAME );
|
||||
if( poolParentGO == null )
|
||||
{
|
||||
poolParentGO = new GameObject( POOL_OBJECT_NAME );
|
||||
DontDestroyOnLoad( poolParentGO );
|
||||
}
|
||||
|
||||
poolParent = poolParentGO.transform;
|
||||
aliveInspectors++;
|
||||
|
||||
for( int i = 0; i < settings.Length; i++ )
|
||||
{
|
||||
if( !settings[i] )
|
||||
continue;
|
||||
|
||||
VariableSet[] hiddenVariablesForTypes = settings[i].HiddenVariables;
|
||||
for( int j = 0; j < hiddenVariablesForTypes.Length; j++ )
|
||||
{
|
||||
VariableSet hiddenVariablesSet = hiddenVariablesForTypes[j];
|
||||
if( hiddenVariablesSet.Init() )
|
||||
hiddenVariables.Add( hiddenVariablesSet );
|
||||
}
|
||||
|
||||
VariableSet[] exposedVariablesForTypes = settings[i].ExposedVariables;
|
||||
for( int j = 0; j < exposedVariablesForTypes.Length; j++ )
|
||||
{
|
||||
VariableSet exposedVariablesSet = exposedVariablesForTypes[j];
|
||||
if( exposedVariablesSet.Init() )
|
||||
exposedVariables.Add( exposedVariablesSet );
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Add( drawArea );
|
||||
RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Add( poolParent );
|
||||
|
||||
#if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
|
||||
// On new Input System, scroll sensitivity is much higher than legacy Input system
|
||||
scrollView.scrollSensitivity *= 0.25f;
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if( --aliveInspectors == 0 )
|
||||
{
|
||||
if( poolParent )
|
||||
{
|
||||
RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Remove( poolParent );
|
||||
DestroyImmediate( poolParent.gameObject );
|
||||
}
|
||||
|
||||
ColorPicker.DestroyInstance();
|
||||
ObjectReferencePicker.DestroyInstance();
|
||||
|
||||
drawersPool.Clear();
|
||||
}
|
||||
|
||||
RuntimeInspectorUtils.IgnoredTransformsInHierarchy.Remove( drawArea );
|
||||
}
|
||||
|
||||
private void OnTransformParentChanged()
|
||||
{
|
||||
m_canvas = GetComponentInParent<Canvas>();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void OnValidate()
|
||||
{
|
||||
base.OnValidate();
|
||||
|
||||
if( UnityEditor.EditorApplication.isPlaying )
|
||||
isDirty = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
if( IsBound )
|
||||
{
|
||||
float time = Time.realtimeSinceStartup;
|
||||
if( isDirty )
|
||||
{
|
||||
// Rebind to refresh the exposed variables in Inspector
|
||||
object inspectedObject = m_inspectedObject;
|
||||
StopInspectInternal();
|
||||
InspectInternal( inspectedObject );
|
||||
|
||||
isDirty = false;
|
||||
nextRefreshTime = time + m_refreshInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( time > nextRefreshTime )
|
||||
{
|
||||
nextRefreshTime = time + m_refreshInterval;
|
||||
Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( currentDrawer != null )
|
||||
StopInspectInternal();
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
if( IsBound )
|
||||
{
|
||||
if( currentDrawer == null )
|
||||
m_inspectedObject = null;
|
||||
else
|
||||
currentDrawer.Refresh();
|
||||
}
|
||||
}
|
||||
|
||||
// Refreshes the Inspector in the next Update. Called by most of the InspectorDrawers
|
||||
// when their values have changed. If a drawer is bound to a property whose setter
|
||||
// may modify the input data (e.g. when input data is 20 but the setter clamps it to 10),
|
||||
// the drawer's BoundInputFields will still show the unmodified input data (20) until the
|
||||
// next Refresh. That is because BoundInputFields don't have access to the fields/properties
|
||||
// they are modifying, there is no way for the BoundInputFields to know whether or not
|
||||
// the property has modified the input data (changed it from 20 to 10).
|
||||
//
|
||||
// Why not refresh only the changed InspectorDrawers? Because changing a property may affect
|
||||
// multiple fields/properties that are bound to other drawers, we don't know which
|
||||
// drawers may be affected. The safest way is to refresh all the drawers.
|
||||
//
|
||||
// Why not Refresh? That's the hacky part: most drawers call this function in their
|
||||
// BoundInputFields' OnValueSubmitted event. If Refresh was used, BoundInputField's
|
||||
// "recentText = str;" line that is called after the OnValueSubmitted event would mess up
|
||||
// with refreshing the value displayed on the BoundInputField.
|
||||
public void RefreshDelayed()
|
||||
{
|
||||
nextRefreshTime = 0f;
|
||||
}
|
||||
|
||||
// Makes sure that scroll view's contents are within scroll view's bounds
|
||||
internal void EnsureScrollViewIsWithinBounds()
|
||||
{
|
||||
// When scrollbar is snapped to the very bottom of the scroll view, sometimes OnScroll alone doesn't work
|
||||
if( scrollView.verticalNormalizedPosition <= Mathf.Epsilon )
|
||||
scrollView.verticalNormalizedPosition = 0.0001f;
|
||||
|
||||
scrollView.OnScroll( nullPointerEventData );
|
||||
}
|
||||
|
||||
protected override void RefreshSkin()
|
||||
{
|
||||
background.color = Skin.BackgroundColor;
|
||||
scrollbar.color = Skin.ScrollbarColor;
|
||||
|
||||
if( IsBound && !isDirty )
|
||||
currentDrawer.Skin = Skin;
|
||||
}
|
||||
|
||||
public void Inspect( object obj )
|
||||
{
|
||||
if( !m_isLocked )
|
||||
InspectInternal( obj );
|
||||
}
|
||||
|
||||
internal void InspectInternal( object obj )
|
||||
{
|
||||
if( inspectLock )
|
||||
return;
|
||||
|
||||
isDirty = false;
|
||||
Initialize();
|
||||
|
||||
if( OnInspectedObjectChanging != null )
|
||||
obj = OnInspectedObjectChanging( m_inspectedObject, obj );
|
||||
|
||||
if( m_inspectedObject == obj )
|
||||
return;
|
||||
|
||||
StopInspectInternal();
|
||||
|
||||
inspectLock = true;
|
||||
try
|
||||
{
|
||||
m_inspectedObject = obj;
|
||||
|
||||
if( obj.IsNull() )
|
||||
return;
|
||||
|
||||
#if UNITY_EDITOR || !NETFX_CORE
|
||||
if( obj.GetType().IsValueType )
|
||||
#else
|
||||
if( obj.GetType().GetTypeInfo().IsValueType )
|
||||
#endif
|
||||
{
|
||||
m_inspectedObject = null;
|
||||
Debug.LogError( "Can't inspect a value type!" );
|
||||
return;
|
||||
}
|
||||
|
||||
//if( !gameObject.activeSelf )
|
||||
//{
|
||||
// m_inspectedObject = null;
|
||||
// Debug.LogError( "Can't inspect while Inspector is inactive!" );
|
||||
// return;
|
||||
//}
|
||||
|
||||
InspectorField inspectedObjectDrawer = CreateDrawerForType( obj.GetType(), drawArea, 0, false );
|
||||
if( inspectedObjectDrawer != null )
|
||||
{
|
||||
inspectedObjectDrawer.BindTo( obj.GetType(), string.Empty, () => m_inspectedObject, ( value ) => m_inspectedObject = value );
|
||||
inspectedObjectDrawer.NameRaw = obj.GetNameWithType();
|
||||
inspectedObjectDrawer.Refresh();
|
||||
|
||||
if( inspectedObjectDrawer is ExpandableInspectorField )
|
||||
( (ExpandableInspectorField) inspectedObjectDrawer ).IsExpanded = true;
|
||||
|
||||
currentDrawer = inspectedObjectDrawer;
|
||||
if( currentDrawer is ExpandableInspectorField )
|
||||
( (ExpandableInspectorField) currentDrawer ).HeaderVisibility = m_inspectedObjectHeaderVisibility;
|
||||
|
||||
GameObject go = m_inspectedObject as GameObject;
|
||||
if( !go && m_inspectedObject as Component )
|
||||
go = ( (Component) m_inspectedObject ).gameObject;
|
||||
|
||||
if( ConnectedHierarchy && go && !ConnectedHierarchy.Select( go.transform, RuntimeHierarchy.SelectOptions.FocusOnSelection ) )
|
||||
ConnectedHierarchy.Deselect();
|
||||
}
|
||||
else
|
||||
m_inspectedObject = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
inspectLock = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void StopInspect()
|
||||
{
|
||||
if( !m_isLocked )
|
||||
StopInspectInternal();
|
||||
}
|
||||
|
||||
internal void StopInspectInternal()
|
||||
{
|
||||
if( inspectLock )
|
||||
return;
|
||||
|
||||
if( currentDrawer != null )
|
||||
{
|
||||
currentDrawer.Unbind();
|
||||
currentDrawer = null;
|
||||
}
|
||||
|
||||
m_inspectedObject = null;
|
||||
scrollView.verticalNormalizedPosition = 1f;
|
||||
|
||||
ColorPicker.Instance.Close();
|
||||
ObjectReferencePicker.Instance.Close();
|
||||
}
|
||||
|
||||
public InspectorField CreateDrawerForType( Type type, Transform drawerParent, int depth, bool drawObjectsAsFields = true, MemberInfo variable = null )
|
||||
{
|
||||
InspectorField[] variableDrawers = GetDrawersForType( type, drawObjectsAsFields );
|
||||
if( variableDrawers != null )
|
||||
{
|
||||
for( int i = 0; i < variableDrawers.Length; i++ )
|
||||
{
|
||||
if( variableDrawers[i].CanBindTo( type, variable ) )
|
||||
{
|
||||
InspectorField drawer = InstantiateDrawer( variableDrawers[i], drawerParent );
|
||||
drawer.Inspector = this;
|
||||
drawer.Skin = Skin;
|
||||
drawer.Depth = depth;
|
||||
|
||||
return drawer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private InspectorField InstantiateDrawer( InspectorField drawer, Transform drawerParent )
|
||||
{
|
||||
List<InspectorField> drawerPool;
|
||||
if( drawersPool.TryGetValue( drawer.GetType(), out drawerPool ) )
|
||||
{
|
||||
for( int i = drawerPool.Count - 1; i >= 0; i-- )
|
||||
{
|
||||
InspectorField instance = drawerPool[i];
|
||||
drawerPool.RemoveAt( i );
|
||||
|
||||
if( instance )
|
||||
{
|
||||
instance.transform.SetParent( drawerParent, false );
|
||||
instance.gameObject.SetActive( true );
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InspectorField newDrawer = (InspectorField) Instantiate( drawer, drawerParent, false );
|
||||
newDrawer.Initialize();
|
||||
return newDrawer;
|
||||
}
|
||||
|
||||
private InspectorField[] GetDrawersForType( Type type, bool drawObjectsAsFields )
|
||||
{
|
||||
bool searchReferenceFields = drawObjectsAsFields && typeof( Object ).IsAssignableFrom( type );
|
||||
|
||||
InspectorField[] cachedResult;
|
||||
if( ( searchReferenceFields && typeToReferenceDrawers.TryGetValue( type, out cachedResult ) ) ||
|
||||
( !searchReferenceFields && typeToDrawers.TryGetValue( type, out cachedResult ) ) )
|
||||
return cachedResult;
|
||||
|
||||
Dictionary<Type, InspectorField[]> drawersDict = searchReferenceFields ? typeToReferenceDrawers : typeToDrawers;
|
||||
|
||||
eligibleDrawers.Clear();
|
||||
for( int i = settings.Length - 1; i >= 0; i-- )
|
||||
{
|
||||
InspectorField[] drawers = searchReferenceFields ? settings[i].ReferenceDrawers : settings[i].StandardDrawers;
|
||||
for( int j = drawers.Length - 1; j >= 0; j-- )
|
||||
{
|
||||
if( drawers[j].SupportsType( type ) )
|
||||
eligibleDrawers.Add( drawers[j] );
|
||||
}
|
||||
}
|
||||
|
||||
cachedResult = eligibleDrawers.Count > 0 ? eligibleDrawers.ToArray() : null;
|
||||
drawersDict[type] = cachedResult;
|
||||
|
||||
return cachedResult;
|
||||
}
|
||||
|
||||
internal void PoolDrawer( InspectorField drawer )
|
||||
{
|
||||
List<InspectorField> drawerPool;
|
||||
if( !drawersPool.TryGetValue( drawer.GetType(), out drawerPool ) )
|
||||
{
|
||||
drawerPool = new List<InspectorField>( poolCapacity );
|
||||
drawersPool[drawer.GetType()] = drawerPool;
|
||||
}
|
||||
|
||||
if( drawerPool.Count < poolCapacity )
|
||||
{
|
||||
drawer.gameObject.SetActive( false );
|
||||
drawer.transform.SetParent( poolParent, false );
|
||||
drawerPool.Add( drawer );
|
||||
}
|
||||
else
|
||||
Destroy( drawer.gameObject );
|
||||
}
|
||||
|
||||
internal ExposedVariablesEnumerator GetExposedVariablesForType( Type type )
|
||||
{
|
||||
MemberInfo[] allVariables = type.GetAllVariables();
|
||||
if( allVariables == null )
|
||||
return new ExposedVariablesEnumerator( null, null, null, VariableVisibility.None, VariableVisibility.None );
|
||||
|
||||
List<VariableSet> hiddenVariablesForType = null;
|
||||
List<VariableSet> exposedVariablesForType = null;
|
||||
for( int i = 0; i < hiddenVariables.Count; i++ )
|
||||
{
|
||||
if( hiddenVariables[i].type.IsAssignableFrom( type ) )
|
||||
{
|
||||
if( hiddenVariablesForType == null )
|
||||
hiddenVariablesForType = new List<VariableSet>() { hiddenVariables[i] };
|
||||
else
|
||||
hiddenVariablesForType.Add( hiddenVariables[i] );
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < exposedVariables.Count; i++ )
|
||||
{
|
||||
if( exposedVariables[i].type.IsAssignableFrom( type ) )
|
||||
{
|
||||
if( exposedVariablesForType == null )
|
||||
exposedVariablesForType = new List<VariableSet>() { exposedVariables[i] };
|
||||
else
|
||||
exposedVariablesForType.Add( exposedVariables[i] );
|
||||
}
|
||||
}
|
||||
|
||||
return new ExposedVariablesEnumerator( allVariables, hiddenVariablesForType, exposedVariablesForType, m_exposeFields, m_exposeProperties );
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user