- Home /
Caching data for a PropertyDrawer
I'm creating a PropertyDrawer for an object that takes a lot of CPU power to get or set it. Since an instance of a PropertyDrawer is reused for multiple properties, I need a way to cache the data in a dictionary.
In order for this to work, there must be some way to uniquely identity a property. I've tried the following in OnGUI():
property.GetHashCode - doesn't work because a new instance of SerializedProperty is created every time
property.name - Seemed to work at first, but not in an array. All names become "data"
property.CountInProperty() - Crashes Unity with "`m_ByteOffset < m_Data->size ()`"
My code looks like this:
public class Drawer : PropertyDrawer
{
private Dictionary<string, Data> allData = new Dictionary<string, Data>();
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
Data data;
allData.TryGetValue(property.somethingUnique, out data);
if (data == null)
{
data = new Data(property);
allData.Add(property.somethingUnique, data);
}
// do things with data
}
}
Since an instance of a PropertyDrawer is reused for multiple properties
Where did you get this info? Could you elaborate more on that?
If I call Debug.Log(GetHashCode())
in OnGUI(), the same thing is output no matter how many properties there are.
I'm confused here. You said a drawer instance is used on multiple properties. But now you're logging the hash code for your properties, and saying that they're different? - I'm not sure what you mean.
Do you mean that if you get the enumerator for your serializedObject, iterate on all the SerializedProperties you'd get from that, they'll all have the same hash code?
OR
do you mean that if you had something like:
public class $$anonymous$$B : $$anonymous$$onoBehaviour
{
[Att]
public int intValue;
[Att]
public float floatValue;
}
and then in your drawer, you log the hash code for the drawer that's used to draw the [Att] on the intValue and floatValue, they're the same drawer? No way.
I fixed that comment in an edit. GetHashCode() is being called on the PropertyDrawer, this has nothing to do with SerializedProperty.GetHashCode()
So yea, I meant your second option. It definitely happens, but not all the time. I found the reuse occurs more often for an array of the same type.
@stuffses: it seems you're correct. I've seen this dictionary before but didn't look into it with further interest... It seems that they have a dictionary for type/drawers, so yea for a certain type you'll get the same drawer.
Answer by Sprakle · Jun 25, 2014 at 01:56 AM
Oh, silly me. I can just use the GUIContent label text. That should be unique in almost all cases.
Edit: property.propertyPath
works better because the result will be unique even with nesting.
Now I can have infinitely nested reorderable lists!
Using a Dictionary keyed by property.propertyPath worked for me.
Can't thank you enough
Your answer
Follow this Question
Related Questions
Using DuplicateCommand and DeleteCommand with Properties 0 Answers
Reflection on class variable values null on editor startup 0 Answers
Mixing custom editors with custom property drawers, possible ? 1 Answer
Is a PropertyDrawer "persistent" ? 1 Answer
Why PropertyDrawers shared same values? 2 Answers