I've noticed an anti-pattern emerge where people call scheduleBuild()
when they think they've changed enough state that they should rebuild,
instead of just wrapping their changes in setState(). This leads to
them missing state changes, having extraneous scheduleBuild() calls,
and other similar bugs.
By removing scheduleBuild(), the only way to actually schedule a build
now is to call setState(), and hopefully that'll make it much clearer
that you're only supposed to do this when you change state.
This fixes some theoretical bugs whereby we were using hashCode to try
to get unique keys for objects, but really we wanted object identity.
It also lays the groundwork for a new GlobalKey concept.
I tried to keep the impact on the code minimal, which is why the "Key"
constructor is actually a factory that returns a StringKey. The code
has this class hierarchy:
```
KeyBase
|
Key--------------+---------------+
| | |
StringKey ObjectKey UniqueKey
```
...where the constructors are Key and Key.stringify (StringKey),
Key.fromObjectIdentity (ObjectKey), and Key.unique (UniqueKey).
We could instead of factory methods use regular constructors with the
following hierarchy:
```
KeyBase
|
LocalKey---------+---------------+
| | |
Key ObjectIdentityKey UniqueKey
```
...with constructors Key, Key.stringify, ObjectIdentityKey, and
UniqueKey, but I felt that that was maybe a more confusing hierarchy.
I don't have a strong opinion on this.
It turns out that we aren't really using these. The identity logic is sufficient.
Also, add some asserts for a crash I had once but couldn't reproduce, in case that helps catch it next time.
This change makes it easier to defined only the width or the height of an image
and let the other value be filled in from the image's intrinsic aspect ratio.
Fixes#175