- Cleaned up streamers.

- Allow configuring of two new streaming policies for enums.
- Changed the alphabetical fields policy to be checked once on class init.

Let me elaborate on the first two changes:

1) The base Streamer class had grown to handle a variety of things.
There were two different ways to handle enums, a whole section of code
for arrays (two ways of handling those), and then custom reader/writer
methods were supported with fallback for regular old streaming classes.
A lot of this was checked by introspection every single time an object
was written/created/read. In addition, there were 6 different fields
in the base class, many of which would be unused by default. All
the BasicStreamers also inherited these fields and never did anything
with them.

So my change makes Streamer an abstract class with no non-static fields.
I pulled all the logic for different streaming strategies
into different classes and do the tests to determine which class
to use once when first setting up the streamer for a particular target class.

If our target class is an array with a final element type, why should
we be re-checking those two things each and every time an object is
written? Or if it's not an array and we've got field marshallers set up,
why are we wondering if it's an array or enum each time?

In addition, reading/writing would freak out if a field marshaller
was never found for a particular field. Let's fail faster and freak
out when the marshallers are first initialized, which is fine
now that (in a recentish commit) we don't initialize the marshallers
if there appears to be no reason to do so (if a Streamable class has
both a custom reader and a custom writer method, then the marshallers
are never used. The class could have non-transient fields that don't
stream, but it takes care of them itself in the custom methods.)

2) There are now three enum-streaming policies that can be configured.

- OLD, the default, will try to stream by byte if the enum is a ByteEnum,
  and fall back to using the enum's name.

- NEW will always stream an enum by ordinal, using the smallest integer
  type possible, given the enum's size. ByteEnum is ignored.

- NEW_WITH_BYTE_ENUM will do the ByteEnum thing for ByteEnums, and fall
  back to the new ordinal thing for other enums.


The idea here is that narya streaming is designed specifically such that
the server and client are running the same code. There are some edge
cases, and some games persist streamed objects, but in general
streaming by ordinal should be fine.

But, it's opt-in for now. I can't go breaking everything.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6522 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Ray Greenwell
2011-03-08 00:48:39 +00:00
parent 3b5e4d3f68
commit b1d7577599
2 changed files with 698 additions and 344 deletions
@@ -74,6 +74,17 @@ public class BasicStreamers
.put(Iterable.class, new IterableStreamer())
.build();
/** Abstract base class for basic streamers. */
public abstract static class BasicStreamer extends Streamer
{
@Override
public void readObject (Object object, ObjectInputStream in, boolean useReader)
throws IOException, ClassNotFoundException
{
// nothing to do here
}
}
/** Streams {@link Boolean} instances. */
public static class BooleanStreamer extends BasicStreamer
{
@@ -588,17 +599,6 @@ public class BasicStreamers
}
}
/** Streams {@link String} instances. */
public static class BasicStreamer extends Streamer
{
@Override
public void readObject (Object object, ObjectInputStream in, boolean useReader)
throws IOException, ClassNotFoundException
{
// nothing to do here
}
}
public static boolean[] readBooleanArray (ObjectInputStream ins)
throws IOException
{
File diff suppressed because it is too large Load Diff