With a magestic legacy as long and historied as Presents, nothing is ever easy.
We need to support legacy closures that have multiple constructors, one of which will be a zero-argument constructor. All of the existing static inner classes that extend NodeAction/NodeRequest will be such legacy classes. Whee! git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6555 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -457,23 +457,24 @@ public abstract class Streamer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// obtain the constructor we'll use to create instances
|
// if we have a zero argument constructor, we have to use that one
|
||||||
if (!isClosure) {
|
for (Constructor<?> ctor : _target.getDeclaredConstructors()) {
|
||||||
// locate our zero argument constructor
|
if (ctor.getParameterTypes().length == 0) {
|
||||||
for (Constructor<?> ctor : _target.getDeclaredConstructors()) {
|
_ctor = ctor;
|
||||||
if (ctor.getParameterTypes().length == 0) {
|
_ctorArgs = ArrayUtil.EMPTY_OBJECT;
|
||||||
_ctor = ctor;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ctorArgs = ArrayUtil.EMPTY_OBJECT;
|
}
|
||||||
|
|
||||||
} else {
|
// if we're an anonymous closure, we also support having a single constructor to which
|
||||||
// a closure should have only one constructor
|
// we'll pass zero-valued arguments, which will then be overwritten by unstreaming
|
||||||
|
if (isClosure && _ctor == null) {
|
||||||
Constructor<?>[] ctors = _target.getDeclaredConstructors();
|
Constructor<?>[] ctors = _target.getDeclaredConstructors();
|
||||||
if (ctors.length > 1) {
|
if (ctors.length > 1) {
|
||||||
throw new RuntimeException("Streamable closure classes must have only " +
|
throw new RuntimeException(
|
||||||
"one constructor [class=" + _target.getName() + "]");
|
"Streamable closure classes must have either a zero-argument constructor " +
|
||||||
|
"or a single argument-taking constructor; multiple argument-taking " +
|
||||||
|
"constructors are not allowed [class=" + _target.getName() + "]");
|
||||||
}
|
}
|
||||||
_ctor = ctors[0];
|
_ctor = ctors[0];
|
||||||
_ctor.setAccessible(true);
|
_ctor.setAccessible(true);
|
||||||
|
|||||||
@@ -447,6 +447,25 @@ public class StreamableTest
|
|||||||
assertEquals(act.act(), react.act());
|
assertEquals(act.act(), react.act());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static class LegacyClosure implements Streamable.Closure
|
||||||
|
{
|
||||||
|
public int arg;
|
||||||
|
public LegacyClosure (int arg) {
|
||||||
|
this.arg = arg;
|
||||||
|
}
|
||||||
|
public LegacyClosure () {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLegacyZeroMultipleCtorHavingClosure ()
|
||||||
|
throws IOException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
LegacyClosure inst = new LegacyClosure(42);
|
||||||
|
LegacyClosure reinst = (LegacyClosure)unflatten(flatten(inst));
|
||||||
|
assertEquals(inst.arg, reinst.arg);
|
||||||
|
}
|
||||||
|
|
||||||
protected int unsafeOuterCall ()
|
protected int unsafeOuterCall ()
|
||||||
{
|
{
|
||||||
return 42;
|
return 42;
|
||||||
|
|||||||
Reference in New Issue
Block a user