-
Notifications
You must be signed in to change notification settings - Fork 45
/
SceneRefAttribute.cs
162 lines (150 loc) · 5.18 KB
/
SceneRefAttribute.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
using System;
using UnityEngine;
namespace KBCore.Refs
{
/// <summary>
/// RefLoc indicates the expected location of the reference.
/// </summary>
internal enum RefLoc
{
/// <summary>
/// Anywhere will only validate the reference isn't null, but relies on you to
/// manually assign the reference yourself.
/// </summary>
Anywhere = -1,
/// <summary>
/// Self looks for the reference on the same game object as the attributed component
/// using GetComponent(s)()
/// </summary>
Self = 0,
/// <summary>
/// Parent looks for the reference on the parent hierarchy of the attributed components game object
/// using GetComponent(s)InParent()
/// </summary>
Parent = 1,
/// <summary>
/// Child looks for the reference on the child hierarchy of the attributed components game object
/// using GetComponent(s)InChildren()
/// </summary>
Child = 2,
/// <summary>
/// Scene looks for the reference anywhere in the scene
/// using GameObject.FindAnyObjectByType() and GameObject.FindObjectsOfType()
/// </summary>
Scene = 4,
}
/// <summary>
/// Optional flags offering additional functionality.
/// </summary>
[Flags]
public enum Flag
{
/// <summary>
/// Default behaviour.
/// </summary>
None = 0,
/// <summary>
/// Allow empty (or null in the case of non-array types) results.
/// </summary>
Optional = 1 << 0,
/// <summary>
/// Include inactive components in the results (only applies to Child and Parent).
/// </summary>
IncludeInactive = 1 << 1,
/// <summary>
/// Allows the user to override the automatic selection. Will still validate that
/// the field location (self, child, etc) matches as expected.
/// </summary>
Editable = 1 << 2,
/// <summary>
/// Excludes components on current GameObject from search(only applies to Child and Parent).
/// </summary>
ExcludeSelf = 1 << 3,
}
/// <summary>
/// Attribute allowing you to decorate component reference fields with their search criteria.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public abstract class SceneRefAttribute : PropertyAttribute
{
internal RefLoc Loc { get; }
internal Flag Flags { get; }
internal SceneRefFilter Filter
{
get
{
if (this._filterType == null)
return null;
return (SceneRefFilter) Activator.CreateInstance(this._filterType);
}
}
private readonly Type _filterType;
internal SceneRefAttribute(
RefLoc loc,
Flag flags,
Type filter
)
{
this.Loc = loc;
this.Flags = flags;
this._filterType = filter;
}
internal bool HasFlags(Flag flags)
=> (this.Flags & flags) == flags;
}
/// <summary>
/// Anywhere will only validate the reference isn't null, but relies on you to
/// manually assign the reference yourself.
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class AnywhereAttribute : SceneRefAttribute
{
public AnywhereAttribute(Flag flags = Flag.None, Type filter = null)
: base(RefLoc.Anywhere, flags, filter)
{}
}
/// <summary>
/// Self looks for the reference on the same game object as the attributed component
/// using GetComponent(s)()
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class SelfAttribute : SceneRefAttribute
{
public SelfAttribute(Flag flags = Flag.None, Type filter = null)
: base(RefLoc.Self, flags, filter)
{}
}
/// <summary>
/// Parent looks for the reference on the parent hierarchy of the attributed components game object
/// using GetComponent(s)InParent()
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class ParentAttribute : SceneRefAttribute
{
public ParentAttribute(Flag flags = Flag.None, Type filter = null)
: base(RefLoc.Parent, flags, filter)
{}
}
/// <summary>
/// Child looks for the reference on the child hierarchy of the attributed components game object
/// using GetComponent(s)InChildren()
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class ChildAttribute : SceneRefAttribute
{
public ChildAttribute(Flag flags = Flag.None, Type filter = null)
: base(RefLoc.Child, flags, filter)
{}
}
/// <summary>
/// Scene looks for the reference anywhere in the scene
/// using GameObject.FindAnyObjectByType() and GameObject.FindObjectsOfType()
/// </summary>
[AttributeUsage(AttributeTargets.Field)]
public class SceneAttribute : SceneRefAttribute
{
public SceneAttribute(Flag flags = Flag.None, Type filter = null)
: base(RefLoc.Scene, flags, filter)
{}
}
}