Share a single MethodFinder between all instances of a subclass of PlaceManager as they can be large enough constitute the bulk of a PlaceManager

git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5029 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Charlie Groves
2008-04-29 18:07:04 +00:00
parent f6e95780f5
commit 938d7f5994
2 changed files with 41 additions and 17 deletions
@@ -24,16 +24,24 @@ package com.threerings.crowd.server;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import com.samskivert.util.HashIntMap; import com.samskivert.util.HashIntMap;
import com.samskivert.util.Interval; import com.samskivert.util.Interval;
import com.samskivert.util.MethodFinder;
import com.samskivert.util.StringUtil; import com.samskivert.util.StringUtil;
import com.threerings.crowd.Log;
import com.threerings.crowd.chat.data.SpeakMarshaller;
import com.threerings.crowd.chat.server.SpeakDispatcher;
import com.threerings.crowd.chat.server.SpeakHandler;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.OccupantInfo;
import com.threerings.crowd.data.Place;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.presents.data.ClientObject; import com.threerings.presents.data.ClientObject;
import com.threerings.presents.server.InvocationManager;
import com.threerings.presents.server.PresentsDObjectMgr;
import com.threerings.presents.dobj.AccessController; import com.threerings.presents.dobj.AccessController;
import com.threerings.presents.dobj.DObject; import com.threerings.presents.dobj.DObject;
import com.threerings.presents.dobj.DObjectManager; import com.threerings.presents.dobj.DObjectManager;
@@ -46,19 +54,9 @@ import com.threerings.presents.dobj.ObjectDeathListener;
import com.threerings.presents.dobj.ObjectDestroyedEvent; import com.threerings.presents.dobj.ObjectDestroyedEvent;
import com.threerings.presents.dobj.ObjectRemovedEvent; import com.threerings.presents.dobj.ObjectRemovedEvent;
import com.threerings.presents.dobj.OidListListener; import com.threerings.presents.dobj.OidListListener;
import com.threerings.presents.dobj.ServerMessageEvent;
import com.threerings.presents.dobj.SetAdapter; import com.threerings.presents.dobj.SetAdapter;
import com.threerings.presents.server.InvocationManager;
import com.threerings.crowd.Log; import com.threerings.presents.server.PresentsDObjectMgr;
import com.threerings.crowd.data.BodyObject;
import com.threerings.crowd.data.OccupantInfo;
import com.threerings.crowd.data.Place;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.chat.data.SpeakMarshaller;
import com.threerings.crowd.chat.server.SpeakDispatcher;
import com.threerings.crowd.chat.server.SpeakHandler;
/** /**
* The place manager is the server-side entity that handles all place-related interaction. It * The place manager is the server-side entity that handles all place-related interaction. It
@@ -78,6 +76,7 @@ import com.threerings.crowd.chat.server.SpeakHandler;
public class PlaceManager public class PlaceManager
implements MessageListener, OidListListener, ObjectDeathListener, SpeakHandler.SpeakerValidator implements MessageListener, OidListListener, ObjectDeathListener, SpeakHandler.SpeakerValidator
{ {
/** /**
* An interface used to allow the registration of standard message handlers to be invoked by * An interface used to allow the registration of standard message handlers to be invoked by
* the place manager when particular types of message events are received. * the place manager when particular types of message events are received.
@@ -358,6 +357,14 @@ public class PlaceManager
nargs[0] = source; nargs[0] = source;
System.arraycopy(args, 0, nargs, 1, args.length); System.arraycopy(args, 0, nargs, 1, args.length);
} }
// Lazily create our dispatcher now that it's actually getting a message
if (_dispatcher == null) {
if (!_dispatcherFinders.containsKey(getClass())) {
_dispatcherFinders.put(getClass(), new MethodFinder(getClass()));
}
_dispatcher = new DynamicListener(this, _dispatcherFinders.get(getClass()));
}
_dispatcher.dispatchMethod(event.getName(), nargs); _dispatcher.dispatchMethod(event.getName(), nargs);
} }
} }
@@ -707,6 +714,14 @@ public class PlaceManager
* idility, or null if no interval is currently registered. */ * idility, or null if no interval is currently registered. */
protected Interval _shutdownInterval; protected Interval _shutdownInterval;
/**
* Maps from a PlaceManager subclass to a MethodFinder for it. When there are many many
* instances of a PlaceManager in existence, having a MethodFinder instance for each gets
* quite expensive.
*/
protected static Map<Class<?>, MethodFinder> _dispatcherFinders =
new HashMap<Class<?>, MethodFinder>();
/** Used to do method lookup magic when we receive message events. */ /** Used to do method lookup magic when we receive message events. */
protected DynamicListener _dispatcher = new DynamicListener(this); protected DynamicListener _dispatcher;
} }
@@ -42,9 +42,18 @@ public class DynamicListener
* target. * target.
*/ */
public DynamicListener (Object target) public DynamicListener (Object target)
{
this(target, new MethodFinder(target.getClass()));
}
/**
* Creates a listener that dynamically dispatches events on the supplied
* target using the methods in finder.
*/
public DynamicListener (Object target, MethodFinder finder)
{ {
_target = target; _target = target;
_finder = new MethodFinder(target.getClass()); _finder = finder;
} }
// from interface AttributeChangeListener // from interface AttributeChangeListener