DObject. There will never be multiple instances with the same oid that
represent "equal" objects and it's possible that in certain (controlled and
limited) cirumstances, objects with different object managers might have the
same oid even though they are different objects.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4853 542714f4-19e9-0310-aa3c-eee0fc999fb1
interface to a list of listeners. Also made RootDObjectManager a RunQueue so
that we can pass around references to the interface rather than requiring a
PresentsDObjectMgr.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4789 542714f4-19e9-0310-aa3c-eee0fc999fb1
(pre-applied and) posted before we received our object but processed (and hence
dispatched to us) after we received our object.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4715 542714f4-19e9-0310-aa3c-eee0fc999fb1
fake Entry implementation. This also avoids breakage if a DSet entry's key
itself implements DSet.Entry (which just happened for the first time in Narya
history).
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4673 542714f4-19e9-0310-aa3c-eee0fc999fb1
except that messages will never leave the server. If generated on a client,
they'll go to the server and be processed like a normal event there
(event handlers will be called) but the event will not leave the server and
be sent to subscribing clients.
Changed the ManagerCaller used by PlaceObjects to use ServerMessageEvents.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4648 542714f4-19e9-0310-aa3c-eee0fc999fb1
queue up an invoker unit which would go off and do some database stuff and then
by the time it came back and was ready to publish its results to a distributed
object, the object in question would have been destroyed for any of a variety
of fairly natural reasons (client disconnected or logged off, game was
abandoned, dog ate homework).
One "solution" to this problem would be to litter our games' code with
thousands of calls to isActive() in the handleResult() methods of our invoker
units. We've done a bit of that in Yohoho but I've resisted starting down that
path in our other games.
Another solution would be to create an Invoker.Unit wrapper that takes a
reference to the distributed object (or objects) that it will be modifying and
have the common unit code check that the object(s) in question are still alive
at the end of the asynchronous operation and not call handleResult() if they
are not. This has numerous problems: what do you do if one object is alive but
not another, how do you incorporate this functionality in with the numerous
other Invoker.Unit derivations we have that simplify our lives in other ways
(without getting crazy and starting to use something like AOP), do you silently
abort the operation or log something?
So instead, I've come around to the idea that this is simply a dirty fact of
life in asynchronous programming and the fact that we can accept modifications
to distributed state after the distribted object in question is dead is a good
thing. We used to log a warning every time this happened and freak out even
more substantially if one tried to start a transaction on a dead object. Now we
will simply log an informational message (I don't think this sort of thing
should be silently ignored because there are some cases where it is an
indication of incorrect code, those are simply more rare). We will also allow a
transaction to be started on a dead object and when the transaction is
committed, all the events involved will be dropped just like a single
modification would have been dropped on that object.
This allows the most sensible thing to happen which is any results that are
published to still live objects will actually be published and results
published to dead objects will be dropped without making a big fuss. Since a
dead object by definition cannot have subscribers, no one could possibly have
cared about the dropped events anyway.
Also widened.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4545 542714f4-19e9-0310-aa3c-eee0fc999fb1
looking for something assignable from Object (rather than the other
way around) when the argument was null.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4346 542714f4-19e9-0310-aa3c-eee0fc999fb1
like Groovy and JRuby. Created a DynamicEventDispatcher that automatically maps
attribute, element and set events to methods. Say you have a field:
public DSet occupantInfo;
you can create a method in any class:
public void occupantInfoAdded (BodyObject source, OccupantInfo entry);
and then bind that class as a listener using the dynamic event dispatcher:
_myobj.addListener(new DynamicEventDispatcher(object));
I also created a nicer replacement for the MessageHandler system which is
clunky but still way simpler than using a full InvocationService. Basically we
dispatch MessageEvent as if it were a method call.
For example, in AtlantiManager I define:
public void placeTile (BodyObject placer, AtlantiTile tile)
which receives a request by a player to place a tile on their turn. Then in
AtlantiController, I simply call:
_atlobj.manager.invoke("placeTile", tile);
Of course, in JRuby and Groovy, that's going to look like:
_atlobj.manager.placeTile(tile);
which is all part of the fun.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4344 542714f4-19e9-0310-aa3c-eee0fc999fb1
distributed objects by reflection since we don't allow clients to create
objects, furthermore we needn't do it asynchronously. The object creation
methods were moved into the server-side only interface and made "immediate", so
the caller creates a derived instance of DObject and registers it with the
system instead of creating it with a Subscriber callback.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4342 542714f4-19e9-0310-aa3c-eee0fc999fb1
where we don't think it ever will.
Instead of returning null, or the exception, always throw a runtime
with just the CloneNotSupportedException as the argument, as this will
contain the most information and will preserve the stack trace.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4264 542714f4-19e9-0310-aa3c-eee0fc999fb1
required some serious bending and folding of the generic type system, but for
the most part we managed to avoid any mutilating. The gendobj task now
generates properly typed "addToXXX" and "updateXXX" DSet methods based on the
parameterized type of the DSet. This might cause unrecompiled code to break,
but I don't think there are many cases in the base toolkit where people call
DSet adders or updaters. We'll see and I'll add backwards compatibility
versions for cases where we need them to support GG games (everything else we
can just recompile).
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4245 542714f4-19e9-0310-aa3c-eee0fc999fb1
Pecos. I'll sort out the per-project niggling bits in just a moment.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4209 542714f4-19e9-0310-aa3c-eee0fc999fb1
returns a properly typed clone of the DSet in question.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4164 542714f4-19e9-0310-aa3c-eee0fc999fb1
all generic references to E as DSet.Entry rather than Object which is what I
was assuming. So when I write:
(E[])new Object[...]
that gets rewritten to:
(Entry[])new Object[...]
which causes le freakout. We need to use Entry[] everywhere, which we happened
to be doing for everything except toArray().
I rewrote things to use E[] everywhere now that I know it will get rewritten to
Entry[]. I thought it was going to get rewritten to Object[] before so I didn't
genericize that stuff.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4059 542714f4-19e9-0310-aa3c-eee0fc999fb1
have to be parameterized on the type of the Comparable that is returned by
getKey(), but that turns out to be a twisty maze of generics that is not
obvious to me how to express using Java's generics syntax and it opens up
various cans of worms that I don't have time to solve right now. So we'll
settle for the DSet itself being parameterized on the Entry class and the Entry
class being non-type safe.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4051 542714f4-19e9-0310-aa3c-eee0fc999fb1
magically booches and causes an IncompatibleClassChangeError, so we're just
going to work around it.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4008 542714f4-19e9-0310-aa3c-eee0fc999fb1
(It may be the same thing under the hood, but our pal Occam would approve.)
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3958 542714f4-19e9-0310-aa3c-eee0fc999fb1
than it needs to be.
Broke streaming compatibility in order to be much more efficient over the wire.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3938 542714f4-19e9-0310-aa3c-eee0fc999fb1
optimization in the process.
Previously, we dumped stack on the server if a entry add was illegal but
did nothing for update/remove.
On the client, we complained for updates and (indirectly) adds, but not
removes.
Now we complain everywhere.
And- as an added bonus, on the server we now do only one binary search for
updates and removals. Whee!
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3528 542714f4-19e9-0310-aa3c-eee0fc999fb1
methods they were looking for.
Since it's probably impossible to have proguard generically skip renaming
for these generated method names, let's update the fields in a different way.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3434 542714f4-19e9-0310-aa3c-eee0fc999fb1
'iterator()' name and deprecate the old 'entries()' method.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3405 542714f4-19e9-0310-aa3c-eee0fc999fb1