From 628e90b347aa554459867a0691c1f6d598e6126c Mon Sep 17 00:00:00 2001 From: Robert Zubeck Date: Tue, 27 Feb 2007 00:39:20 +0000 Subject: [PATCH] Updates to host coordinator: - every time we check for the host's existence, if the host doesn't exist or abandoned the game, the client will try to claim their role automatically - unified both event types into one "host changed" event - fixed bug that ignored negative player ids git-svn-id: svn+ssh://src.earth.threerings.net/vilya/trunk@218 c613c5cb-e716-0410-b11b-feb51c14d237 --- src/as/com/threerings/ezgame/EZGameControl.as | 2 +- .../com/threerings/ezgame/HostCoordinator.as | 62 ++++++++++++------- src/as/com/threerings/ezgame/HostEvent.as | 28 +++++++-- 3 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/as/com/threerings/ezgame/EZGameControl.as b/src/as/com/threerings/ezgame/EZGameControl.as index 0560702d..51913dc2 100644 --- a/src/as/com/threerings/ezgame/EZGameControl.as +++ b/src/as/com/threerings/ezgame/EZGameControl.as @@ -412,7 +412,7 @@ public class EZGameControl extends BaseControl * Get the display name of the specified occupant. * Two players may have the same name: always use playerId to * purposes of identification and comparison. The name is for display - * only. + * only. Will be null is the specified playerId is not in the game. */ public function getOccupantName (playerId :int) :String { diff --git a/src/as/com/threerings/ezgame/HostCoordinator.as b/src/as/com/threerings/ezgame/HostCoordinator.as index 4461116f..65414d6b 100644 --- a/src/as/com/threerings/ezgame/HostCoordinator.as +++ b/src/as/com/threerings/ezgame/HostCoordinator.as @@ -85,24 +85,27 @@ public class HostCoordinator extends EventDispatcher if (_control.isConnected()) { // Try set host role if it's not already claimed (i.e. null) debugLog("Trying to claim host role."); - debugLog("Current status: " + status); + debugLog("Current host: " + getHostId()); tryReplaceHost(null); } } /** * Retrieves current host coordination status, as one of the STATUS_* constants. + * If the current host is not known, or had abandoned the game, the client will silently + * try to claim the host role while returning this status property. * * Note: do not save the value of this property. Hosting status can change at any moment: when * the current host quits the game, any client can suddenly become the new host. */ public function get status () : String { - var hostId : Number = getHostId(); + var hostId : Number = getHostId(true); + if (hostId == _control.getMyId()) { return STATUS_HOST; } - if (hostId > 0) { + if (hostId != 0) { return STATUS_NOT_HOST; } return STATUS_UNKNOWN; @@ -126,7 +129,6 @@ public class HostCoordinator extends EventDispatcher debugLog("Current host: " + getHostId()); if (getHostId() == event.occupantId) { // Elvis has left the building - debugLog("Removing the old host..."); // Clear the old host value, and put myself in their place. Only the first client will // succeed in doing this. tryReplaceHost (event.occupantId); @@ -137,35 +139,49 @@ public class HostCoordinator extends EventDispatcher public function propertyChanged (event : PropertyChangedEvent) : void { if (event.name == HOST_NAME) { - debugLog("Host variable changed to: " + event.newValue); - - // if the host was not known before, dispatch the claimed event - if (event.oldValue == null && event.newValue != null) { - this.dispatchEvent(new HostEvent(HostEvent.CLAIMED, _control)); - } - - // always dispatch the changed event - this.dispatchEvent(new HostEvent(HostEvent.CHANGED, _control)); + debugLog("Host variable changed from " + event.oldValue + " to " + event.newValue); + this.dispatchEvent( + new HostEvent( + HostEvent.CHANGED, _control, Number(event.oldValue), Number(event.newValue))); } } // IMPLEMENTATION DETAILS - /** Get the current host ID (will be 0 if there is no authoritative host) */ - protected function getHostId () : Number + /** + * Retrieves and returns current host's playerId. If the current host is unknown or + * no longer in the game, returns 0. + * + * If the claimIfAvailable flag is set, and the host role is available (either because + * no previous host has been recorded, or the currently known host had abandoned the game), + * the current client will try to claim the host role. + */ + protected function getHostId (claimIfAvailable : Boolean = false) : Number { - var hostvalue : Object = _control.get(HOST_NAME); - if (hostvalue != null && hostvalue is Number) { - return hostvalue as Number; + var host : Object = _control.get(HOST_NAME); + + if (host == null || // no host was recorded, or + _control.getOccupantName (Number(host)) == null) // host has left the game + { + if (claimIfAvailable) { + tryReplaceHost (host); + } + return 0; + + } else { + // otherwise, the host is present and known + return Number(host); } - return 0; } - /** Helper function: tries to set the host variable to the client's id, if the current value is + /** + * Helper function: tries to set the host variable to the client's id, if the current value is * equal to /hostId/. If the value of null for hostId has the meaning of "set me as host only - * if the role has not been claimed yet". */ + * if the role has not been claimed yet". + */ protected function tryReplaceHost (hostId : Object) : void { + debugLog("Removing old host with id " + hostId); _control.testAndSet (HOST_NAME, _control.getMyId (), hostId); debugHostStatus (); } @@ -181,12 +197,12 @@ public class HostCoordinator extends EventDispatcher /** Debug only */ protected function debugHostStatus () : void { - debugLog((status == STATUS_HOST ? "I am" : "I'm not") + + debugLog((getHostId() == _control.getMyId() ? "I am" : "I'm not") + " the host (id " + getHostId() + ", mine is " + _control.getMyId() + ")"); } /** Magic key that stores current authoritative host */ - protected var HOST_NAME : String = "HOST_COORDINATOR_AUTHORITATIVE_HOST"; + protected var HOST_NAME : String = "_host_name"; /** Controller storage */ protected var _control : EZGameControl = null; diff --git a/src/as/com/threerings/ezgame/HostEvent.as b/src/as/com/threerings/ezgame/HostEvent.as index b469972b..6be52a0f 100644 --- a/src/as/com/threerings/ezgame/HostEvent.as +++ b/src/as/com/threerings/ezgame/HostEvent.as @@ -32,13 +32,22 @@ public class HostEvent extends EZEvent /** Indicates that the current host changed. */ public static const CHANGED :String = "Host Changed"; - /** Indicates that the host used to be unknown, but it became claimed - by one of the clients. */ - public static const CLAIMED :String = "Host Claimed"; - - public function HostEvent (type :String, ezgame :EZGameControl) + public function HostEvent ( + type :String, ezgame :EZGameControl, previousHost :Number, newHost :Number) { super (type, ezgame); + _previous = previousHost; + _new = newHost; + } + + public function get previousHost () :Number + { + return _previous; + } + + public function get newHost () :Number + { + return _new; } override public function toString () :String @@ -48,7 +57,14 @@ public class HostEvent extends EZEvent override public function clone () :Event { - return new HostEvent (type, _ezgame); + return new HostEvent (type, _ezgame, _previous, _new); } + + /** Id of the previous host (possibly null). */ + protected var _previous :Number; + + /** Id of the new host. */ + protected var _new :Number; + } }